UEsDBAoAAAAAAAAAIQAmbx6fMgAAADIAAAAUAAAATUVUQS1JTkYvTUFOSUZFU1QuTUZNYW5pZmVzdC1WZXJzaW9uOiAxLjAKQ3JlYXRlZC1CeTogMS42LjAgKHByb3RvYykKClBLAwQKAAAAAAAAACEAWlhvACwEAAAsBAAAEgAAAFVuaXR0ZXN0RW1wdHkuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2VtcHR5LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcHVibGljIGZpbmFsIGNsYXNzIFVuaXR0ZXN0RW1wdHkgewogIHByaXZhdGUgVW5pdHRlc3RFbXB0eSgpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuJGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9lbXB0eS5wcm90byIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgIH0pOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEA75bietBlswDQZbMAMwAAAGNvbS9nb29nbGUvcHJvdG9idWYvVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Vub3Jtb3VzX2Rlc2NyaXB0b3IucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWY7CgpwdWJsaWMgZmluYWwgY2xhc3MgVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgewogIHByaXZhdGUgVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IoKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEVub3Jtb3VzRGVzY3JpcHRvck9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEgPSAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMSA9IDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xID0gMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMiA9IDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yID0gMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIgPSAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zID0gMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMgPSAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMyA9IDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQgPSA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNCA9IDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ID0gNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNSA9IDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ID0gNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUgPSA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ID0gNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYgPSA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNiA9IDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcgPSA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNyA9IDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ID0gNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOCA9IDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ID0gOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzggPSA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ID0gOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkgPSA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOSA9IDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwID0gMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwID0gMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwID0gMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEgPSAxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEgPSAxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEgPSAxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMiA9IDEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMiA9IDEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMiA9IDEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzID0gMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzID0gMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzID0gMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQgPSAxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQgPSAxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQgPSAxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNSA9IDE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNSA9IDE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNSA9IDE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2ID0gMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2ID0gMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2ID0gMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcgPSAxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcgPSAxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcgPSAxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOCA9IDE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOCA9IDE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOCA9IDE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMThCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5ID0gMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5ID0gMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5ID0gMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAgPSAyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAgPSAyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAgPSAyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMSA9IDIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMSA9IDIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMSA9IDIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyID0gMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyID0gMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyID0gMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMgPSAyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMgPSAyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMgPSAyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNCA9IDI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNCA9IDI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNCA9IDI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1ID0gMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1ID0gMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1ID0gMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYgPSAyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYgPSAyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYgPSAyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNyA9IDI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNyA9IDI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNyA9IDI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4ID0gMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4ID0gMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4ID0gMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkgPSAyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkgPSAyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkgPSAyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMCA9IDMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMCA9IDMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMCA9IDMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxID0gMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxID0gMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxID0gMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIgPSAzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIgPSAzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIgPSAzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMyA9IDMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMyA9IDMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMyA9IDMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0ID0gMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0ID0gMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0ID0gMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUgPSAzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUgPSAzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUgPSAzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNiA9IDM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNiA9IDM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNiA9IDM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3ID0gMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3ID0gMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3ID0gMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzggPSAzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzggPSAzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzggPSAzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOSA9IDM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOSA9IDM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOSA9IDM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwID0gNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwID0gNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwID0gNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEgPSA0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEgPSA0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEgPSA0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MiA9IDQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MiA9IDQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MiA9IDQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzID0gNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzID0gNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzID0gNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQgPSA0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQgPSA0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQgPSA0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NSA9IDQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NSA9IDQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NSA9IDQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2ID0gNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2ID0gNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2ID0gNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcgPSA0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcgPSA0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcgPSA0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OCA9IDQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OCA9IDQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OCA9IDQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5ID0gNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5ID0gNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5ID0gNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAgPSA1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAgPSA1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAgPSA1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MSA9IDUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MSA9IDUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MSA9IDUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyID0gNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyID0gNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyID0gNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMgPSA1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMgPSA1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMgPSA1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NCA9IDU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NCA9IDU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NCA9IDU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1ID0gNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1ID0gNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1ID0gNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYgPSA1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYgPSA1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYgPSA1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NyA9IDU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NyA9IDU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NyA9IDU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4ID0gNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4ID0gNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4ID0gNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkgPSA1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkgPSA1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkgPSA1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MCA9IDYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MCA9IDYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MCA9IDYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxID0gNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxID0gNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxID0gNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIgPSA2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIgPSA2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIgPSA2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MyA9IDYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MyA9IDYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MyA9IDYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0ID0gNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0ID0gNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0ID0gNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUgPSA2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUgPSA2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUgPSA2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NiA9IDY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NiA9IDY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NiA9IDY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3ID0gNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3ID0gNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3ID0gNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjggPSA2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjggPSA2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjggPSA2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OSA9IDY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OSA9IDY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OSA9IDY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwID0gNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwID0gNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwID0gNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEgPSA3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEgPSA3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEgPSA3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MiA9IDcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MiA9IDcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MiA9IDcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczID0gNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczID0gNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczID0gNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQgPSA3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQgPSA3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQgPSA3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NSA9IDc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NSA9IDc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NSA9IDc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2ID0gNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2ID0gNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2ID0gNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcgPSA3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcgPSA3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcgPSA3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OCA9IDc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OCA9IDc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OCA9IDc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5ID0gNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5ID0gNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5ID0gNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAgPSA4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAgPSA4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAgPSA4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MSA9IDgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MSA9IDgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MSA9IDgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyID0gODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyID0gODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyID0gODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMgPSA4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMgPSA4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMgPSA4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NCA9IDg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NCA9IDg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NCA9IDg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1ID0gODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1ID0gODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1ID0gODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYgPSA4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYgPSA4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYgPSA4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NyA9IDg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NyA9IDg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NyA9IDg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4ID0gODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4ID0gODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4ID0gODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkgPSA4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkgPSA4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkgPSA4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MCA9IDkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MCA9IDkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MCA9IDkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxID0gOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxID0gOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxID0gOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIgPSA5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIgPSA5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIgPSA5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MyA9IDkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MyA9IDkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MyA9IDkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0ID0gOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0ID0gOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0ID0gOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUgPSA5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUgPSA5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUgPSA5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NiA9IDk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NiA9IDk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NiA9IDk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3ID0gOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3ID0gOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3ID0gOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTggPSA5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTggPSA5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTggPSA5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OSA9IDk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OSA9IDk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OSA9IDk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMCA9IDEwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDAgPSAxMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAwID0gMTAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAxID0gMTAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMSA9IDEwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDEgPSAxMDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDIgPSAxMDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAyID0gMTAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMiA9IDEwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMyA9IDEwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDMgPSAxMDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAzID0gMTAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA0ID0gMTA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNCA9IDEwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDQgPSAxMDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDUgPSAxMDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA1ID0gMTA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNSA9IDEwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNiA9IDEwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDYgPSAxMDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA2ID0gMTA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA3ID0gMTA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNyA9IDEwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDcgPSAxMDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDggPSAxMDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA4ID0gMTA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwOCA9IDEwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwOSA9IDEwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDkgPSAxMDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA5ID0gMTA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEwID0gMTEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMCA9IDExMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTAgPSAxMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTEgPSAxMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTExID0gMTExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMSA9IDExMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMiA9IDExMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTIgPSAxMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEyID0gMTEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEzID0gMTEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMyA9IDExMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTMgPSAxMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTQgPSAxMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE0ID0gMTE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNCA9IDExNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNSA9IDExNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTUgPSAxMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE1ID0gMTE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE2ID0gMTE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNiA9IDExNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTYgPSAxMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTcgPSAxMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE3ID0gMTE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNyA9IDExNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExOCA9IDExOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTggPSAxMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE4ID0gMTE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE5ID0gMTE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExOSA9IDExOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTkgPSAxMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjAgPSAxMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIwID0gMTIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMCA9IDEyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMSA9IDEyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjEgPSAxMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIxID0gMTIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIyID0gMTIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMiA9IDEyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjIgPSAxMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjMgPSAxMjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIzID0gMTIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMyA9IDEyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNCA9IDEyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjQgPSAxMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI0ID0gMTI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI1ID0gMTI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNSA9IDEyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjUgPSAxMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjYgPSAxMjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI2ID0gMTI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNiA9IDEyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNyA9IDEyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjcgPSAxMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI3ID0gMTI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI4ID0gMTI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyOCA9IDEyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjggPSAxMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjkgPSAxMjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI5ID0gMTI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyOSA9IDEyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMCA9IDEzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzAgPSAxMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMwID0gMTMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMxID0gMTMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMSA9IDEzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzEgPSAxMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzIgPSAxMzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMyID0gMTMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMiA9IDEzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMyA9IDEzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzMgPSAxMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMzID0gMTMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM0ID0gMTM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNCA9IDEzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzQgPSAxMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzUgPSAxMzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM1ID0gMTM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNSA9IDEzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNiA9IDEzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzYgPSAxMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM2ID0gMTM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM3ID0gMTM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNyA9IDEzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzcgPSAxMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzggPSAxMzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM4ID0gMTM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzOCA9IDEzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzOSA9IDEzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzkgPSAxMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM5ID0gMTM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQwID0gMTQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MCA9IDE0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDAgPSAxNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDEgPSAxNDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQxID0gMTQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MSA9IDE0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MiA9IDE0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDIgPSAxNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQyID0gMTQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQzID0gMTQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MyA9IDE0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDMgPSAxNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDQgPSAxNDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ0ID0gMTQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NCA9IDE0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NSA9IDE0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDUgPSAxNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ1ID0gMTQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ2ID0gMTQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NiA9IDE0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDYgPSAxNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDcgPSAxNDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ3ID0gMTQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NyA9IDE0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0OCA9IDE0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDggPSAxNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ4ID0gMTQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ5ID0gMTQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0OSA9IDE0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDkgPSAxNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTAgPSAxNTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUwID0gMTUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MCA9IDE1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MSA9IDE1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTEgPSAxNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUxID0gMTUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUyID0gMTUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MiA9IDE1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTIgPSAxNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTMgPSAxNTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUzID0gMTUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MyA9IDE1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NCA9IDE1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTQgPSAxNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU0ID0gMTU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU1ID0gMTU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NSA9IDE1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTUgPSAxNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTYgPSAxNTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU2ID0gMTU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NiA9IDE1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NyA9IDE1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTcgPSAxNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU3ID0gMTU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU4ID0gMTU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1OCA9IDE1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTggPSAxNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTkgPSAxNTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU5ID0gMTU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1OSA9IDE1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MCA9IDE2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjAgPSAxNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYwID0gMTYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYxID0gMTYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MSA9IDE2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjEgPSAxNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjIgPSAxNjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYyID0gMTYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MiA9IDE2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MyA9IDE2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjMgPSAxNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYzID0gMTYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY0ID0gMTY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NCA9IDE2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjQgPSAxNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjUgPSAxNjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY1ID0gMTY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NSA9IDE2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NiA9IDE2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjYgPSAxNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY2ID0gMTY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY3ID0gMTY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NyA9IDE2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjcgPSAxNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjggPSAxNjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY4ID0gMTY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2OCA9IDE2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2OSA9IDE2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjkgPSAxNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY5ID0gMTY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcwID0gMTcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MCA9IDE3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzAgPSAxNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzEgPSAxNzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcxID0gMTcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MSA9IDE3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MiA9IDE3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzIgPSAxNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcyID0gMTcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTczID0gMTczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MyA9IDE3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTczKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzMgPSAxNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTczLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTczQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzQgPSAxNzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc0ID0gMTc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NCA9IDE3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NSA9IDE3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzUgPSAxNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc1ID0gMTc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc2ID0gMTc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NiA9IDE3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzYgPSAxNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzcgPSAxNzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc3ID0gMTc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NyA9IDE3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3OCA9IDE3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzggPSAxNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc4ID0gMTc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc5ID0gMTc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3OSA9IDE3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzkgPSAxNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODAgPSAxODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgwID0gMTgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MCA9IDE4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MSA9IDE4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODEgPSAxODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgxID0gMTgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgyID0gMTgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MiA9IDE4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODIgPSAxODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODMgPSAxODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgzID0gMTgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MyA9IDE4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NCA9IDE4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODQgPSAxODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg0ID0gMTg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg1ID0gMTg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NSA9IDE4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODUgPSAxODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODYgPSAxODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg2ID0gMTg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NiA9IDE4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NyA9IDE4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODcgPSAxODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg3ID0gMTg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg4ID0gMTg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4OCA9IDE4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODggPSAxODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODkgPSAxODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg5ID0gMTg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4OSA9IDE4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MCA9IDE5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTAgPSAxOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkwID0gMTkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkxID0gMTkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MSA9IDE5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTEgPSAxOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTIgPSAxOTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkyID0gMTkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MiA9IDE5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MyA9IDE5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTMgPSAxOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkzID0gMTkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk0ID0gMTk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NCA9IDE5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTQgPSAxOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTUgPSAxOTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk1ID0gMTk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NSA9IDE5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NiA9IDE5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTYgPSAxOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk2ID0gMTk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk3ID0gMTk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NyA9IDE5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTcgPSAxOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTggPSAxOTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk4ID0gMTk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5OCA9IDE5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOThCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5OSA9IDE5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTkgPSAxOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk5ID0gMTk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAwID0gMjAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMCA9IDIwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDAgPSAyMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDEgPSAyMDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAxID0gMjAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMSA9IDIwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMiA9IDIwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDIgPSAyMDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAyID0gMjAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAzID0gMjAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMyA9IDIwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDMgPSAyMDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDQgPSAyMDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA0ID0gMjA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNCA9IDIwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNSA9IDIwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDUgPSAyMDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA1ID0gMjA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA2ID0gMjA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNiA9IDIwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDYgPSAyMDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDcgPSAyMDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA3ID0gMjA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNyA9IDIwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwOCA9IDIwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDggPSAyMDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA4ID0gMjA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA5ID0gMjA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwOSA9IDIwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDkgPSAyMDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTAgPSAyMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEwID0gMjEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMCA9IDIxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMSA9IDIxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjExIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjExKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTEgPSAyMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjExID0gMjExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEyID0gMjEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMiA9IDIxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTIgPSAyMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTMgPSAyMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEzID0gMjEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMyA9IDIxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNCA9IDIxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTQgPSAyMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE0ID0gMjE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE1ID0gMjE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNSA9IDIxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTUgPSAyMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTYgPSAyMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE2ID0gMjE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNiA9IDIxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNyA9IDIxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTcgPSAyMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE3ID0gMjE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE4ID0gMjE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxOCA9IDIxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTggPSAyMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTkgPSAyMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE5ID0gMjE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxOSA9IDIxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMCA9IDIyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjAgPSAyMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIwID0gMjIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIxID0gMjIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMSA9IDIyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjEgPSAyMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjIgPSAyMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIyID0gMjIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMiA9IDIyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMyA9IDIyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjMgPSAyMjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIzID0gMjIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI0ID0gMjI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNCA9IDIyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjQgPSAyMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjUgPSAyMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI1ID0gMjI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNSA9IDIyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNiA9IDIyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjYgPSAyMjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI2ID0gMjI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI3ID0gMjI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNyA9IDIyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjcgPSAyMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjggPSAyMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI4ID0gMjI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyOCA9IDIyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyOSA9IDIyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjkgPSAyMjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI5ID0gMjI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMwID0gMjMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMCA9IDIzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzAgPSAyMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzEgPSAyMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMxID0gMjMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMSA9IDIzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMiA9IDIzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzIgPSAyMzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMyID0gMjMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMzID0gMjMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMyA9IDIzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzMgPSAyMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzQgPSAyMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM0ID0gMjM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNCA9IDIzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNSA9IDIzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzUgPSAyMzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM1ID0gMjM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM2ID0gMjM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNiA9IDIzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzYgPSAyMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzcgPSAyMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM3ID0gMjM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNyA9IDIzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzOCA9IDIzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzggPSAyMzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM4ID0gMjM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM5ID0gMjM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzOSA9IDIzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzkgPSAyMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDAgPSAyNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQwID0gMjQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MCA9IDI0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MSA9IDI0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDEgPSAyNDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQxID0gMjQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQyID0gMjQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MiA9IDI0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDIgPSAyNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDMgPSAyNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQzID0gMjQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MyA9IDI0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NCA9IDI0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDQgPSAyNDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ0ID0gMjQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ1ID0gMjQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NSA9IDI0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDUgPSAyNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDYgPSAyNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ2ID0gMjQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NiA9IDI0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NyA9IDI0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDcgPSAyNDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ3ID0gMjQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ4ID0gMjQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0OCA9IDI0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDggPSAyNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDkgPSAyNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ5ID0gMjQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0OSA9IDI0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MCA9IDI1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTAgPSAyNTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUwID0gMjUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUxID0gMjUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MSA9IDI1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTEgPSAyNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTIgPSAyNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUyID0gMjUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MiA9IDI1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MyA9IDI1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTMgPSAyNTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUzID0gMjUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU0ID0gMjU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NCA9IDI1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTQgPSAyNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTUgPSAyNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU1ID0gMjU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NSA9IDI1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NiA9IDI1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTYgPSAyNTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU2ID0gMjU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU3ID0gMjU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NyA9IDI1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTcgPSAyNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTggPSAyNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU4ID0gMjU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1OCA9IDI1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNThCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1OSA9IDI1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTkgPSAyNTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU5ID0gMjU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYwID0gMjYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MCA9IDI2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjAgPSAyNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjEgPSAyNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYxID0gMjYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MSA9IDI2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MiA9IDI2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjIgPSAyNjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYyID0gMjYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYzID0gMjYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MyA9IDI2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjMgPSAyNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjQgPSAyNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY0ID0gMjY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NCA9IDI2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NSA9IDI2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjUgPSAyNjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY1ID0gMjY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY2ID0gMjY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NiA9IDI2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjYgPSAyNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjcgPSAyNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY3ID0gMjY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NyA9IDI2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2OCA9IDI2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjggPSAyNjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY4ID0gMjY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY5ID0gMjY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2OSA9IDI2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjkgPSAyNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzAgPSAyNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcwID0gMjcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MCA9IDI3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MSA9IDI3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzEgPSAyNzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcxID0gMjcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcyID0gMjcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MiA9IDI3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzIgPSAyNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzMgPSAyNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjczID0gMjczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MyA9IDI3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NCA9IDI3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzQgPSAyNzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc0ID0gMjc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc1ID0gMjc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NSA9IDI3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzUgPSAyNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzYgPSAyNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc2ID0gMjc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NiA9IDI3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NyA9IDI3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzcgPSAyNzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc3ID0gMjc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc4ID0gMjc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3OCA9IDI3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzggPSAyNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzkgPSAyNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc5ID0gMjc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3OSA9IDI3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MCA9IDI4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODAgPSAyODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgwID0gMjgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgxID0gMjgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MSA9IDI4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODEgPSAyODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODIgPSAyODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgyID0gMjgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MiA9IDI4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MyA9IDI4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODMgPSAyODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgzID0gMjgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg0ID0gMjg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NCA9IDI4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODQgPSAyODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODUgPSAyODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg1ID0gMjg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NSA9IDI4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NiA9IDI4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODYgPSAyODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg2ID0gMjg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg3ID0gMjg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NyA9IDI4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODcgPSAyODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODggPSAyODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg4ID0gMjg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4OCA9IDI4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4OSA9IDI4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODkgPSAyODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg5ID0gMjg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkwID0gMjkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MCA9IDI5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTAgPSAyOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTEgPSAyOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkxID0gMjkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MSA9IDI5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MiA9IDI5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTIgPSAyOTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkyID0gMjkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkzID0gMjkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MyA9IDI5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTMgPSAyOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTQgPSAyOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk0ID0gMjk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NCA9IDI5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NSA9IDI5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTUgPSAyOTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk1ID0gMjk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk2ID0gMjk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NiA9IDI5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTYgPSAyOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTcgPSAyOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk3ID0gMjk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NyA9IDI5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5OCA9IDI5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTggPSAyOTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk4ID0gMjk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk5ID0gMjk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5OSA9IDI5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTkgPSAyOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDAgPSAzMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAwID0gMzAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMCA9IDMwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMSA9IDMwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDEgPSAzMDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAxID0gMzAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAyID0gMzAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMiA9IDMwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDIgPSAzMDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDMgPSAzMDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAzID0gMzAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMyA9IDMwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNCA9IDMwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDQgPSAzMDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA0ID0gMzA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA1ID0gMzA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNSA9IDMwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDUgPSAzMDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDYgPSAzMDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA2ID0gMzA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNiA9IDMwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNyA9IDMwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDcgPSAzMDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA3ID0gMzA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA4ID0gMzA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwOCA9IDMwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDggPSAzMDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDkgPSAzMDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA5ID0gMzA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwOSA9IDMwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMCA9IDMxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTAgPSAzMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEwID0gMzEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzExID0gMzExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMSA9IDMxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzExKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTEgPSAzMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzExLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzExQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTIgPSAzMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEyID0gMzEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMiA9IDMxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMyA9IDMxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTMgPSAzMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEzID0gMzEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE0ID0gMzE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNCA9IDMxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTQgPSAzMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTUgPSAzMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE1ID0gMzE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNSA9IDMxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNiA9IDMxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTYgPSAzMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE2ID0gMzE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE3ID0gMzE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNyA9IDMxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTcgPSAzMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTggPSAzMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE4ID0gMzE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxOCA9IDMxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMThCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxOSA9IDMxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTkgPSAzMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE5ID0gMzE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIwID0gMzIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMCA9IDMyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjAgPSAzMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjEgPSAzMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIxID0gMzIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMSA9IDMyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMiA9IDMyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjIgPSAzMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIyID0gMzIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIzID0gMzIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMyA9IDMyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjMgPSAzMjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjQgPSAzMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI0ID0gMzI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNCA9IDMyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNSA9IDMyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjUgPSAzMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI1ID0gMzI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI2ID0gMzI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNiA9IDMyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjYgPSAzMjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjcgPSAzMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI3ID0gMzI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNyA9IDMyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyOCA9IDMyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjggPSAzMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI4ID0gMzI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI5ID0gMzI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyOSA9IDMyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjkgPSAzMjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzAgPSAzMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMwID0gMzMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMCA9IDMzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMSA9IDMzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzEgPSAzMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMxID0gMzMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMyID0gMzMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMiA9IDMzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzIgPSAzMzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzMgPSAzMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMzID0gMzMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMyA9IDMzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzNCA9IDMzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzQgPSAzMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM0ID0gMzM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM1ID0gMzM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzNSA9IDMzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzUgPSAzMzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzYgPSAzMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM2ID0gMzM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzNiA9IDMzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzNyA9IDMzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzcgPSAzMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM3ID0gMzM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM4ID0gMzM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzOCA9IDMzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzggPSAzMzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzkgPSAzMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM5ID0gMzM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzOSA9IDMzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0MCA9IDM0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDAgPSAzNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQwID0gMzQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQxID0gMzQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0MSA9IDM0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDEgPSAzNDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDIgPSAzNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQyID0gMzQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0MiA9IDM0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0MyA9IDM0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDMgPSAzNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQzID0gMzQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ0ID0gMzQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NCA9IDM0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDQgPSAzNDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDUgPSAzNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ1ID0gMzQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NSA9IDM0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NiA9IDM0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDYgPSAzNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ2ID0gMzQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ3ID0gMzQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NyA9IDM0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDcgPSAzNDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDggPSAzNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ4ID0gMzQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0OCA9IDM0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0OSA9IDM0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDkgPSAzNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ5ID0gMzQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUwID0gMzUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MCA9IDM1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTAgPSAzNTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTEgPSAzNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUxID0gMzUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MSA9IDM1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MiA9IDM1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTIgPSAzNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUyID0gMzUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUzID0gMzUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MyA9IDM1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTMgPSAzNTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTQgPSAzNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU0ID0gMzU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NCA9IDM1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NSA9IDM1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTUgPSAzNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU1ID0gMzU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU2ID0gMzU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NiA9IDM1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTYgPSAzNTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTcgPSAzNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU3ID0gMzU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NyA9IDM1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1OCA9IDM1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTggPSAzNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU4ID0gMzU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU5ID0gMzU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1OSA9IDM1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTkgPSAzNTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjAgPSAzNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYwID0gMzYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MCA9IDM2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MSA9IDM2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjEgPSAzNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYxID0gMzYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYyID0gMzYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MiA9IDM2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjIgPSAzNjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjMgPSAzNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYzID0gMzYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MyA9IDM2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2NCA9IDM2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjQgPSAzNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY0ID0gMzY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY1ID0gMzY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2NSA9IDM2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjUgPSAzNjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjYgPSAzNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY2ID0gMzY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2NiA9IDM2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2NyA9IDM2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjcgPSAzNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY3ID0gMzY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY4ID0gMzY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2OCA9IDM2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjggPSAzNjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjkgPSAzNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY5ID0gMzY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2OSA9IDM2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3MCA9IDM3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzAgPSAzNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcwID0gMzcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcxID0gMzcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3MSA9IDM3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzEgPSAzNzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzIgPSAzNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcyID0gMzcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3MiA9IDM3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3MyA9IDM3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzczIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzczKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzMgPSAzNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzczID0gMzczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc0ID0gMzc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NCA9IDM3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzQgPSAzNzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzUgPSAzNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc1ID0gMzc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NSA9IDM3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NiA9IDM3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzYgPSAzNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc2ID0gMzc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc3ID0gMzc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NyA9IDM3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzcgPSAzNzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzggPSAzNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc4ID0gMzc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3OCA9IDM3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3OSA9IDM3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzkgPSAzNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc5ID0gMzc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgwID0gMzgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MCA9IDM4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODAgPSAzODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODEgPSAzODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgxID0gMzgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MSA9IDM4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MiA9IDM4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODIgPSAzODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgyID0gMzgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgzID0gMzgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MyA9IDM4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODMgPSAzODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODQgPSAzODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg0ID0gMzg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NCA9IDM4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NSA9IDM4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODUgPSAzODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg1ID0gMzg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg2ID0gMzg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NiA9IDM4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODYgPSAzODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODcgPSAzODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg3ID0gMzg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NyA9IDM4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4OCA9IDM4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODggPSAzODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg4ID0gMzg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg5ID0gMzg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4OSA9IDM4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODkgPSAzODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTAgPSAzOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkwID0gMzkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MCA9IDM5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MSA9IDM5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTEgPSAzOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkxID0gMzkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkyID0gMzkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MiA9IDM5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTIgPSAzOTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTMgPSAzOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkzID0gMzkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MyA9IDM5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5NCA9IDM5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTQgPSAzOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk0ID0gMzk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk1ID0gMzk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5NSA9IDM5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTUgPSAzOTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTYgPSAzOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk2ID0gMzk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5NiA9IDM5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5NyA9IDM5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTcgPSAzOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk3ID0gMzk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk4ID0gMzk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5OCA9IDM5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTggPSAzOTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTkgPSAzOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk5ID0gMzk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5OSA9IDM5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMCA9IDQwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDAgPSA0MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAwID0gNDAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAxID0gNDAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMSA9IDQwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDEgPSA0MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDIgPSA0MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAyID0gNDAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMiA9IDQwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMyA9IDQwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDMgPSA0MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAzID0gNDAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA0ID0gNDA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNCA9IDQwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDQgPSA0MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDUgPSA0MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA1ID0gNDA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNSA9IDQwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNiA9IDQwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDYgPSA0MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA2ID0gNDA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA3ID0gNDA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNyA9IDQwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDcgPSA0MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDggPSA0MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA4ID0gNDA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwOCA9IDQwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwOSA9IDQwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDkgPSA0MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA5ID0gNDA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEwID0gNDEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMCA9IDQxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTAgPSA0MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTEgPSA0MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDExID0gNDExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDExLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMSA9IDQxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMiA9IDQxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTIgPSA0MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEyID0gNDEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEzID0gNDEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMyA9IDQxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTMgPSA0MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTQgPSA0MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE0ID0gNDE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNCA9IDQxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNSA9IDQxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTUgPSA0MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE1ID0gNDE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE2ID0gNDE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNiA9IDQxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTYgPSA0MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTcgPSA0MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE3ID0gNDE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNyA9IDQxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxOCA9IDQxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTggPSA0MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE4ID0gNDE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE5ID0gNDE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxOSA9IDQxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTkgPSA0MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjAgPSA0MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIwID0gNDIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMCA9IDQyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMSA9IDQyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjEgPSA0MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIxID0gNDIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIyID0gNDIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMiA9IDQyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjIgPSA0MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjMgPSA0MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIzID0gNDIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMyA9IDQyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNCA9IDQyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjQgPSA0MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI0ID0gNDI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI1ID0gNDI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNSA9IDQyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjUgPSA0MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjYgPSA0MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI2ID0gNDI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNiA9IDQyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNyA9IDQyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjcgPSA0MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI3ID0gNDI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI4ID0gNDI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyOCA9IDQyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjggPSA0MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjkgPSA0MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI5ID0gNDI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyOSA9IDQyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzMCA9IDQzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzAgPSA0MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMwID0gNDMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMxID0gNDMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzMSA9IDQzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzEgPSA0MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzIgPSA0MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMyID0gNDMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzMiA9IDQzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzMyA9IDQzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzMgPSA0MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMzID0gNDMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM0ID0gNDM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNCA9IDQzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzQgPSA0MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzUgPSA0MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM1ID0gNDM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNSA9IDQzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNiA9IDQzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzYgPSA0MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM2ID0gNDM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM3ID0gNDM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNyA9IDQzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzcgPSA0MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzggPSA0MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM4ID0gNDM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzOCA9IDQzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzOSA9IDQzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzkgPSA0MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM5ID0gNDM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQwID0gNDQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MCA9IDQ0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDAgPSA0NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDEgPSA0NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQxID0gNDQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MSA9IDQ0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MiA9IDQ0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDIgPSA0NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQyID0gNDQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQzID0gNDQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MyA9IDQ0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDMgPSA0NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDQgPSA0NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ0ID0gNDQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NCA9IDQ0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NSA9IDQ0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDUgPSA0NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ1ID0gNDQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ2ID0gNDQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NiA9IDQ0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDYgPSA0NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDcgPSA0NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ3ID0gNDQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NyA9IDQ0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0OCA9IDQ0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDggPSA0NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ4ID0gNDQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ5ID0gNDQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0OSA9IDQ0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDkgPSA0NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTAgPSA0NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUwID0gNDUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MCA9IDQ1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MSA9IDQ1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTEgPSA0NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUxID0gNDUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUyID0gNDUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MiA9IDQ1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTIgPSA0NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTMgPSA0NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUzID0gNDUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MyA9IDQ1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1NCA9IDQ1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTQgPSA0NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU0ID0gNDU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU1ID0gNDU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1NSA9IDQ1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTUgPSA0NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTYgPSA0NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU2ID0gNDU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1NiA9IDQ1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1NyA9IDQ1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTcgPSA0NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU3ID0gNDU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU4ID0gNDU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1OCA9IDQ1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTggPSA0NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTkgPSA0NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU5ID0gNDU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1OSA9IDQ1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2MCA9IDQ2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjAgPSA0NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYwID0gNDYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYxID0gNDYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2MSA9IDQ2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjEgPSA0NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjIgPSA0NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYyID0gNDYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2MiA9IDQ2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2MyA9IDQ2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjMgPSA0NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYzID0gNDYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY0ID0gNDY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NCA9IDQ2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjQgPSA0NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjUgPSA0NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY1ID0gNDY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NSA9IDQ2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NiA9IDQ2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjYgPSA0NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY2ID0gNDY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY3ID0gNDY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NyA9IDQ2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjcgPSA0NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjggPSA0NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY4ID0gNDY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2OCA9IDQ2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2OSA9IDQ2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjkgPSA0NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY5ID0gNDY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcwID0gNDcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MCA9IDQ3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzAgPSA0NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzEgPSA0NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcxID0gNDcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MSA9IDQ3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MiA9IDQ3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzIgPSA0NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcyID0gNDcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDczID0gNDczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MyA9IDQ3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDczKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzMgPSA0NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDczLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDczQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzQgPSA0NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc0ID0gNDc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NCA9IDQ3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NSA9IDQ3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzUgPSA0NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc1ID0gNDc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc2ID0gNDc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NiA9IDQ3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzYgPSA0NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzcgPSA0NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc3ID0gNDc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NyA9IDQ3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3OCA9IDQ3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzggPSA0NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc4ID0gNDc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc5ID0gNDc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3OSA9IDQ3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzkgPSA0NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODAgPSA0ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgwID0gNDgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MCA9IDQ4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MSA9IDQ4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODEgPSA0ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgxID0gNDgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgyID0gNDgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MiA9IDQ4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODIgPSA0ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODMgPSA0ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgzID0gNDgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MyA9IDQ4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4NCA9IDQ4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODQgPSA0ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg0ID0gNDg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg1ID0gNDg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4NSA9IDQ4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODUgPSA0ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODYgPSA0ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg2ID0gNDg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4NiA9IDQ4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4NyA9IDQ4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODcgPSA0ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg3ID0gNDg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg4ID0gNDg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4OCA9IDQ4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODggPSA0ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODkgPSA0ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg5ID0gNDg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4OSA9IDQ4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5MCA9IDQ5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTAgPSA0OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkwID0gNDkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkxID0gNDkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5MSA9IDQ5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTEgPSA0OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTIgPSA0OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkyID0gNDkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5MiA9IDQ5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5MyA9IDQ5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTMgPSA0OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkzID0gNDkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk0ID0gNDk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NCA9IDQ5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTQgPSA0OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTUgPSA0OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk1ID0gNDk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NSA9IDQ5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NiA9IDQ5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTYgPSA0OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk2ID0gNDk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk3ID0gNDk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NyA9IDQ5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTcgPSA0OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTggPSA0OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk4ID0gNDk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5OCA9IDQ5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OThCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5OSA9IDQ5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTkgPSA0OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk5ID0gNDk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAwID0gNTAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMCA9IDUwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDAgPSA1MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDEgPSA1MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAxID0gNTAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMSA9IDUwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMiA9IDUwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDIgPSA1MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAyID0gNTAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAzID0gNTAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMyA9IDUwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDMgPSA1MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDQgPSA1MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA0ID0gNTA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNCA9IDUwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNSA9IDUwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDUgPSA1MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA1ID0gNTA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA2ID0gNTA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNiA9IDUwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDYgPSA1MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDcgPSA1MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA3ID0gNTA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNyA9IDUwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwOCA9IDUwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDggPSA1MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA4ID0gNTA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA5ID0gNTA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwOSA9IDUwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDkgPSA1MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTAgPSA1MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEwID0gNTEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMCA9IDUxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMSA9IDUxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTExIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTExKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTEgPSA1MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTExID0gNTExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEyID0gNTEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMiA9IDUxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTIgPSA1MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTMgPSA1MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEzID0gNTEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMyA9IDUxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNCA9IDUxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTQgPSA1MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE0ID0gNTE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE1ID0gNTE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNSA9IDUxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTUgPSA1MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTYgPSA1MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE2ID0gNTE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNiA9IDUxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNyA9IDUxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTcgPSA1MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE3ID0gNTE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE4ID0gNTE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxOCA9IDUxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTggPSA1MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTkgPSA1MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE5ID0gNTE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxOSA9IDUxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyMCA9IDUyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjAgPSA1MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIwID0gNTIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIxID0gNTIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyMSA9IDUyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjEgPSA1MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjIgPSA1MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIyID0gNTIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyMiA9IDUyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyMyA9IDUyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjMgPSA1MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIzID0gNTIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI0ID0gNTI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNCA9IDUyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjQgPSA1MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjUgPSA1MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI1ID0gNTI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNSA9IDUyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNiA9IDUyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjYgPSA1MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI2ID0gNTI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI3ID0gNTI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNyA9IDUyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjcgPSA1MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjggPSA1MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI4ID0gNTI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyOCA9IDUyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyOSA9IDUyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjkgPSA1MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI5ID0gNTI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMwID0gNTMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMCA9IDUzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzAgPSA1MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzEgPSA1MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMxID0gNTMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMSA9IDUzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMiA9IDUzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzIgPSA1MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMyID0gNTMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMzID0gNTMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMyA9IDUzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzMgPSA1MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzQgPSA1MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM0ID0gNTM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNCA9IDUzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNSA9IDUzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzUgPSA1MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM1ID0gNTM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM2ID0gNTM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNiA9IDUzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzYgPSA1MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzcgPSA1MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM3ID0gNTM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNyA9IDUzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzOCA9IDUzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzggPSA1MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM4ID0gNTM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM5ID0gNTM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzOSA9IDUzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzkgPSA1MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDAgPSA1NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQwID0gNTQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MCA9IDU0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MSA9IDU0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDEgPSA1NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQxID0gNTQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQyID0gNTQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MiA9IDU0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDIgPSA1NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDMgPSA1NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQzID0gNTQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MyA9IDU0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0NCA9IDU0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDQgPSA1NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ0ID0gNTQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ1ID0gNTQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0NSA9IDU0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDUgPSA1NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDYgPSA1NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ2ID0gNTQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0NiA9IDU0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0NyA9IDU0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDcgPSA1NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ3ID0gNTQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ4ID0gNTQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0OCA9IDU0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDggPSA1NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDkgPSA1NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ5ID0gNTQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0OSA9IDU0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1MCA9IDU1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTAgPSA1NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUwID0gNTUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUxID0gNTUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1MSA9IDU1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTEgPSA1NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTIgPSA1NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUyID0gNTUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1MiA9IDU1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1MyA9IDU1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTMgPSA1NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUzID0gNTUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU0ID0gNTU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NCA9IDU1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTQgPSA1NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTUgPSA1NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU1ID0gNTU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NSA9IDU1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NiA9IDU1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTYgPSA1NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU2ID0gNTU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU3ID0gNTU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NyA9IDU1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTcgPSA1NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTggPSA1NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU4ID0gNTU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1OCA9IDU1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NThCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1OSA9IDU1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTkgPSA1NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU5ID0gNTU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYwID0gNTYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MCA9IDU2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjAgPSA1NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjEgPSA1NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYxID0gNTYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MSA9IDU2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MiA9IDU2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjIgPSA1NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYyID0gNTYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYzID0gNTYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MyA9IDU2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjMgPSA1NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjQgPSA1NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY0ID0gNTY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NCA9IDU2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NSA9IDU2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjUgPSA1NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY1ID0gNTY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY2ID0gNTY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NiA9IDU2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjYgPSA1NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjcgPSA1NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY3ID0gNTY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NyA9IDU2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2OCA9IDU2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjggPSA1NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY4ID0gNTY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY5ID0gNTY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2OSA9IDU2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjkgPSA1NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzAgPSA1NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcwID0gNTcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MCA9IDU3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MSA9IDU3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzEgPSA1NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcxID0gNTcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcyID0gNTcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MiA9IDU3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzIgPSA1NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzMgPSA1NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTczID0gNTczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTczLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MyA9IDU3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NCA9IDU3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzQgPSA1NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc0ID0gNTc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc1ID0gNTc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NSA9IDU3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzUgPSA1NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzYgPSA1NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc2ID0gNTc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NiA9IDU3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NyA9IDU3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzcgPSA1NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc3ID0gNTc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc4ID0gNTc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3OCA9IDU3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzggPSA1NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzkgPSA1NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc5ID0gNTc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3OSA9IDU3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4MCA9IDU4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODAgPSA1ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgwID0gNTgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgxID0gNTgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4MSA9IDU4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODEgPSA1ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODIgPSA1ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgyID0gNTgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4MiA9IDU4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4MyA9IDU4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODMgPSA1ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgzID0gNTgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg0ID0gNTg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NCA9IDU4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODQgPSA1ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODUgPSA1ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg1ID0gNTg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NSA9IDU4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NiA9IDU4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODYgPSA1ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg2ID0gNTg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg3ID0gNTg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NyA9IDU4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODcgPSA1ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODggPSA1ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg4ID0gNTg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4OCA9IDU4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4OSA9IDU4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODkgPSA1ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg5ID0gNTg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkwID0gNTkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MCA9IDU5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTAgPSA1OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTEgPSA1OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkxID0gNTkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MSA9IDU5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MiA9IDU5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTIgPSA1OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkyID0gNTkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkzID0gNTkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MyA9IDU5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTMgPSA1OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTQgPSA1OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk0ID0gNTk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NCA9IDU5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NSA9IDU5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTUgPSA1OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk1ID0gNTk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk2ID0gNTk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NiA9IDU5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTYgPSA1OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTcgPSA1OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk3ID0gNTk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NyA9IDU5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5OCA9IDU5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTggPSA1OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk4ID0gNTk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk5ID0gNTk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5OSA9IDU5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTkgPSA1OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDAgPSA2MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAwID0gNjAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMCA9IDYwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMSA9IDYwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDEgPSA2MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAxID0gNjAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAyID0gNjAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMiA9IDYwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDIgPSA2MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDMgPSA2MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAzID0gNjAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMyA9IDYwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwNCA9IDYwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDQgPSA2MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA0ID0gNjA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA1ID0gNjA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwNSA9IDYwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDUgPSA2MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDYgPSA2MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA2ID0gNjA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwNiA9IDYwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwNyA9IDYwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDcgPSA2MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA3ID0gNjA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA4ID0gNjA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwOCA9IDYwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDggPSA2MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDkgPSA2MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA5ID0gNjA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwOSA9IDYwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxMCA9IDYxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTAgPSA2MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEwID0gNjEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjExID0gNjExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxMSA9IDYxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjExKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTEgPSA2MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjExLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjExQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTIgPSA2MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEyID0gNjEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxMiA9IDYxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxMyA9IDYxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTMgPSA2MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEzID0gNjEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE0ID0gNjE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNCA9IDYxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTQgPSA2MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTUgPSA2MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE1ID0gNjE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNSA9IDYxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNiA9IDYxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTYgPSA2MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE2ID0gNjE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE3ID0gNjE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNyA9IDYxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTcgPSA2MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTggPSA2MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE4ID0gNjE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxOCA9IDYxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MThCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxOSA9IDYxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTkgPSA2MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE5ID0gNjE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIwID0gNjIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMCA9IDYyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjAgPSA2MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjEgPSA2MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIxID0gNjIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMSA9IDYyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMiA9IDYyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjIgPSA2MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIyID0gNjIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIzID0gNjIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMyA9IDYyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjMgPSA2MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjQgPSA2MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI0ID0gNjI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNCA9IDYyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNSA9IDYyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjUgPSA2MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI1ID0gNjI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI2ID0gNjI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNiA9IDYyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjYgPSA2MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjcgPSA2MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI3ID0gNjI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNyA9IDYyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyOCA9IDYyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjggPSA2MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI4ID0gNjI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI5ID0gNjI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyOSA9IDYyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjkgPSA2MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzAgPSA2MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMwID0gNjMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMCA9IDYzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMSA9IDYzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzEgPSA2MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMxID0gNjMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMyID0gNjMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMiA9IDYzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzIgPSA2MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzMgPSA2MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMzID0gNjMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMyA9IDYzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzNCA9IDYzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzQgPSA2MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM0ID0gNjM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM1ID0gNjM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzNSA9IDYzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzUgPSA2MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzYgPSA2MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM2ID0gNjM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzNiA9IDYzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzNyA9IDYzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzcgPSA2MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM3ID0gNjM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM4ID0gNjM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzOCA9IDYzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzggPSA2MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzkgPSA2MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM5ID0gNjM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzOSA9IDYzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0MCA9IDY0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDAgPSA2NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQwID0gNjQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQxID0gNjQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0MSA9IDY0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDEgPSA2NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDIgPSA2NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQyID0gNjQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0MiA9IDY0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0MyA9IDY0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDMgPSA2NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQzID0gNjQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ0ID0gNjQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NCA9IDY0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDQgPSA2NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDUgPSA2NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ1ID0gNjQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NSA9IDY0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NiA9IDY0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDYgPSA2NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ2ID0gNjQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ3ID0gNjQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NyA9IDY0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDcgPSA2NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDggPSA2NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ4ID0gNjQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0OCA9IDY0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0OSA9IDY0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDkgPSA2NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ5ID0gNjQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUwID0gNjUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MCA9IDY1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTAgPSA2NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTEgPSA2NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUxID0gNjUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MSA9IDY1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MiA9IDY1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTIgPSA2NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUyID0gNjUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUzID0gNjUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MyA9IDY1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTMgPSA2NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTQgPSA2NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU0ID0gNjU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NCA9IDY1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NSA9IDY1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTUgPSA2NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU1ID0gNjU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU2ID0gNjU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NiA9IDY1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTYgPSA2NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTcgPSA2NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU3ID0gNjU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NyA9IDY1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1OCA9IDY1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTggPSA2NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU4ID0gNjU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU5ID0gNjU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1OSA9IDY1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTkgPSA2NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjAgPSA2NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYwID0gNjYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MCA9IDY2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MSA9IDY2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjEgPSA2NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYxID0gNjYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYyID0gNjYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MiA9IDY2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjIgPSA2NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjMgPSA2NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYzID0gNjYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MyA9IDY2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2NCA9IDY2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjQgPSA2NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY0ID0gNjY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY1ID0gNjY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2NSA9IDY2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjUgPSA2NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjYgPSA2NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY2ID0gNjY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2NiA9IDY2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2NyA9IDY2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjcgPSA2NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY3ID0gNjY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY4ID0gNjY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2OCA9IDY2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjggPSA2NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjkgPSA2NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY5ID0gNjY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2OSA9IDY2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3MCA9IDY3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzAgPSA2NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcwID0gNjcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcxID0gNjcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3MSA9IDY3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzEgPSA2NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzIgPSA2NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcyID0gNjcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3MiA9IDY3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3MyA9IDY3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjczIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjczKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzMgPSA2NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjczID0gNjczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc0ID0gNjc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NCA9IDY3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzQgPSA2NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzUgPSA2NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc1ID0gNjc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NSA9IDY3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NiA9IDY3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzYgPSA2NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc2ID0gNjc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc3ID0gNjc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NyA9IDY3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzcgPSA2NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzggPSA2NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc4ID0gNjc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3OCA9IDY3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3OSA9IDY3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzkgPSA2NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc5ID0gNjc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgwID0gNjgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MCA9IDY4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODAgPSA2ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODEgPSA2ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgxID0gNjgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MSA9IDY4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MiA9IDY4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODIgPSA2ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgyID0gNjgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgzID0gNjgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MyA9IDY4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODMgPSA2ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODQgPSA2ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg0ID0gNjg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NCA9IDY4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NSA9IDY4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODUgPSA2ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg1ID0gNjg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg2ID0gNjg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NiA9IDY4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODYgPSA2ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODcgPSA2ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg3ID0gNjg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NyA9IDY4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4OCA9IDY4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODggPSA2ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg4ID0gNjg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg5ID0gNjg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4OSA9IDY4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODkgPSA2ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTAgPSA2OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkwID0gNjkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MCA9IDY5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MSA9IDY5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTEgPSA2OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkxID0gNjkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkyID0gNjkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MiA9IDY5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTIgPSA2OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTMgPSA2OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkzID0gNjkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MyA9IDY5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5NCA9IDY5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTQgPSA2OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk0ID0gNjk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk1ID0gNjk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5NSA9IDY5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTUgPSA2OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTYgPSA2OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk2ID0gNjk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5NiA9IDY5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5NyA9IDY5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTcgPSA2OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk3ID0gNjk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk4ID0gNjk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5OCA9IDY5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTggPSA2OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTkgPSA2OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk5ID0gNjk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5OSA9IDY5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwMCA9IDcwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDAgPSA3MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAwID0gNzAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAxID0gNzAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwMSA9IDcwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDEgPSA3MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDIgPSA3MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAyID0gNzAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwMiA9IDcwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwMyA9IDcwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDMgPSA3MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAzID0gNzAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA0ID0gNzA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNCA9IDcwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDQgPSA3MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDUgPSA3MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA1ID0gNzA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNSA9IDcwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNiA9IDcwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDYgPSA3MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA2ID0gNzA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA3ID0gNzA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNyA9IDcwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDcgPSA3MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDggPSA3MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA4ID0gNzA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwOCA9IDcwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwOSA9IDcwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDkgPSA3MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA5ID0gNzA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEwID0gNzEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMCA9IDcxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTAgPSA3MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTEgPSA3MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzExID0gNzExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzExLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMSA9IDcxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMiA9IDcxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTIgPSA3MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEyID0gNzEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEzID0gNzEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMyA9IDcxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTMgPSA3MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTQgPSA3MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE0ID0gNzE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNCA9IDcxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNSA9IDcxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTUgPSA3MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE1ID0gNzE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE2ID0gNzE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNiA9IDcxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTYgPSA3MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTcgPSA3MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE3ID0gNzE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNyA9IDcxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxOCA9IDcxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTggPSA3MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE4ID0gNzE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE5ID0gNzE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxOSA9IDcxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTkgPSA3MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjAgPSA3MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIwID0gNzIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMCA9IDcyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMSA9IDcyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjEgPSA3MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIxID0gNzIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIyID0gNzIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMiA9IDcyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjIgPSA3MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjMgPSA3MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIzID0gNzIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMyA9IDcyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyNCA9IDcyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjQgPSA3MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI0ID0gNzI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI1ID0gNzI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyNSA9IDcyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjUgPSA3MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjYgPSA3MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI2ID0gNzI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyNiA9IDcyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyNyA9IDcyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjcgPSA3MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI3ID0gNzI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI4ID0gNzI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyOCA9IDcyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjggPSA3MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjkgPSA3MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI5ID0gNzI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyOSA9IDcyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMCA9IDczMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzAgPSA3MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMwID0gNzMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMxID0gNzMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMSA9IDczMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzEgPSA3MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzIgPSA3MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMyID0gNzMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMiA9IDczMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMyA9IDczMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzMgPSA3MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMzID0gNzMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM0ID0gNzM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNCA9IDczNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzQgPSA3MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzUgPSA3MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM1ID0gNzM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNSA9IDczNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNiA9IDczNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzYgPSA3MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM2ID0gNzM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM3ID0gNzM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNyA9IDczNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzcgPSA3MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzggPSA3MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM4ID0gNzM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczOCA9IDczOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczOSA9IDczOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzkgPSA3MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM5ID0gNzM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQwID0gNzQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MCA9IDc0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDAgPSA3NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDEgPSA3NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQxID0gNzQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MSA9IDc0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MiA9IDc0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDIgPSA3NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQyID0gNzQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQzID0gNzQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MyA9IDc0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDMgPSA3NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDQgPSA3NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ0ID0gNzQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NCA9IDc0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NSA9IDc0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDUgPSA3NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ1ID0gNzQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ2ID0gNzQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NiA9IDc0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDYgPSA3NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDcgPSA3NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ3ID0gNzQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NyA9IDc0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0OCA9IDc0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDggPSA3NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ4ID0gNzQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ5ID0gNzQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0OSA9IDc0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDkgPSA3NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTAgPSA3NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUwID0gNzUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MCA9IDc1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MSA9IDc1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTEgPSA3NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUxID0gNzUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUyID0gNzUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MiA9IDc1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTIgPSA3NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTMgPSA3NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUzID0gNzUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MyA9IDc1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NCA9IDc1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTQgPSA3NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU0ID0gNzU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU1ID0gNzU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NSA9IDc1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTUgPSA3NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTYgPSA3NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU2ID0gNzU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NiA9IDc1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NyA9IDc1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTcgPSA3NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU3ID0gNzU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU4ID0gNzU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1OCA9IDc1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTggPSA3NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTkgPSA3NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU5ID0gNzU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1OSA9IDc1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2MCA9IDc2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjAgPSA3NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYwID0gNzYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYxID0gNzYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2MSA9IDc2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjEgPSA3NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjIgPSA3NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYyID0gNzYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2MiA9IDc2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2MyA9IDc2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjMgPSA3NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYzID0gNzYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY0ID0gNzY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NCA9IDc2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjQgPSA3NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjUgPSA3NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY1ID0gNzY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NSA9IDc2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NiA9IDc2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjYgPSA3NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY2ID0gNzY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY3ID0gNzY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NyA9IDc2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjcgPSA3NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjggPSA3NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY4ID0gNzY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2OCA9IDc2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2OSA9IDc2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjkgPSA3NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY5ID0gNzY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcwID0gNzcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MCA9IDc3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzAgPSA3NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzEgPSA3NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcxID0gNzcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MSA9IDc3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MiA9IDc3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzIgPSA3NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcyID0gNzcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzczID0gNzczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MyA9IDc3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzczKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzMgPSA3NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzczLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzczQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzQgPSA3NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc0ID0gNzc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NCA9IDc3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NSA9IDc3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzUgPSA3NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc1ID0gNzc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc2ID0gNzc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NiA9IDc3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzYgPSA3NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzcgPSA3NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc3ID0gNzc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NyA9IDc3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3OCA9IDc3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzggPSA3NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc4ID0gNzc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc5ID0gNzc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3OSA9IDc3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzkgPSA3NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODAgPSA3ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgwID0gNzgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MCA9IDc4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MSA9IDc4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODEgPSA3ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgxID0gNzgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgyID0gNzgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MiA9IDc4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODIgPSA3ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODMgPSA3ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgzID0gNzgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MyA9IDc4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NCA9IDc4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODQgPSA3ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg0ID0gNzg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg1ID0gNzg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NSA9IDc4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODUgPSA3ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODYgPSA3ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg2ID0gNzg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NiA9IDc4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NyA9IDc4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODcgPSA3ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg3ID0gNzg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg4ID0gNzg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4OCA9IDc4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODggPSA3ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODkgPSA3ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg5ID0gNzg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4OSA9IDc4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MCA9IDc5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTAgPSA3OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkwID0gNzkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkxID0gNzkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MSA9IDc5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTEgPSA3OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTIgPSA3OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkyID0gNzkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MiA9IDc5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MyA9IDc5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTMgPSA3OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkzID0gNzkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk0ID0gNzk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NCA9IDc5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTQgPSA3OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTUgPSA3OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk1ID0gNzk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NSA9IDc5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NiA9IDc5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTYgPSA3OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk2ID0gNzk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk3ID0gNzk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NyA9IDc5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTcgPSA3OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTggPSA3OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk4ID0gNzk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5OCA9IDc5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OThCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5OSA9IDc5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTkgPSA3OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk5ID0gNzk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAwID0gODAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMCA9IDgwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDAgPSA4MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDEgPSA4MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAxID0gODAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMSA9IDgwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMiA9IDgwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDIgPSA4MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAyID0gODAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAzID0gODAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMyA9IDgwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDMgPSA4MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDQgPSA4MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA0ID0gODA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNCA9IDgwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNSA9IDgwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDUgPSA4MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA1ID0gODA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA2ID0gODA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNiA9IDgwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDYgPSA4MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDcgPSA4MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA3ID0gODA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNyA9IDgwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwOCA9IDgwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDggPSA4MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA4ID0gODA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA5ID0gODA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwOSA9IDgwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDkgPSA4MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTAgPSA4MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEwID0gODEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMCA9IDgxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMSA9IDgxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODExIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODExKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTEgPSA4MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODExID0gODExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEyID0gODEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMiA9IDgxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTIgPSA4MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTMgPSA4MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEzID0gODEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMyA9IDgxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNCA9IDgxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTQgPSA4MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE0ID0gODE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE1ID0gODE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNSA9IDgxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTUgPSA4MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTYgPSA4MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE2ID0gODE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNiA9IDgxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNyA9IDgxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTcgPSA4MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE3ID0gODE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE4ID0gODE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxOCA9IDgxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTggPSA4MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTkgPSA4MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE5ID0gODE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxOSA9IDgxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyMCA9IDgyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjAgPSA4MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIwID0gODIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIxID0gODIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyMSA9IDgyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjEgPSA4MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjIgPSA4MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIyID0gODIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyMiA9IDgyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyMyA9IDgyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjMgPSA4MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIzID0gODIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI0ID0gODI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNCA9IDgyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjQgPSA4MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjUgPSA4MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI1ID0gODI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNSA9IDgyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNiA9IDgyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjYgPSA4MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI2ID0gODI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI3ID0gODI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNyA9IDgyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjcgPSA4MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjggPSA4MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI4ID0gODI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyOCA9IDgyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyOSA9IDgyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjkgPSA4MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI5ID0gODI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMwID0gODMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMCA9IDgzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzAgPSA4MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzEgPSA4MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMxID0gODMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMSA9IDgzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMiA9IDgzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzIgPSA4MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMyID0gODMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMzID0gODMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMyA9IDgzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzMgPSA4MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzQgPSA4MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM0ID0gODM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNCA9IDgzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNSA9IDgzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzUgPSA4MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM1ID0gODM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM2ID0gODM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNiA9IDgzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzYgPSA4MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzcgPSA4MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM3ID0gODM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNyA9IDgzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzOCA9IDgzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzggPSA4MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM4ID0gODM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM5ID0gODM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzOSA9IDgzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzkgPSA4MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDAgPSA4NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQwID0gODQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MCA9IDg0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MSA9IDg0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDEgPSA4NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQxID0gODQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQyID0gODQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MiA9IDg0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDIgPSA4NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDMgPSA4NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQzID0gODQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MyA9IDg0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0NCA9IDg0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDQgPSA4NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ0ID0gODQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ1ID0gODQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0NSA9IDg0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDUgPSA4NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDYgPSA4NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ2ID0gODQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0NiA9IDg0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0NyA9IDg0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDcgPSA4NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ3ID0gODQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ4ID0gODQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0OCA9IDg0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDggPSA4NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDkgPSA4NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ5ID0gODQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0OSA9IDg0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1MCA9IDg1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTAgPSA4NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUwID0gODUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUxID0gODUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1MSA9IDg1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTEgPSA4NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTIgPSA4NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUyID0gODUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1MiA9IDg1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1MyA9IDg1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTMgPSA4NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUzID0gODUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU0ID0gODU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NCA9IDg1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTQgPSA4NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTUgPSA4NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU1ID0gODU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NSA9IDg1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NiA9IDg1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTYgPSA4NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU2ID0gODU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU3ID0gODU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NyA9IDg1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTcgPSA4NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTggPSA4NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU4ID0gODU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1OCA9IDg1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NThCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1OSA9IDg1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTkgPSA4NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU5ID0gODU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYwID0gODYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MCA9IDg2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjAgPSA4NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjEgPSA4NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYxID0gODYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MSA9IDg2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MiA9IDg2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjIgPSA4NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYyID0gODYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYzID0gODYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MyA9IDg2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjMgPSA4NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjQgPSA4NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY0ID0gODY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NCA9IDg2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NSA9IDg2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjUgPSA4NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY1ID0gODY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY2ID0gODY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NiA9IDg2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjYgPSA4NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjcgPSA4NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY3ID0gODY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NyA9IDg2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2OCA9IDg2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjggPSA4NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY4ID0gODY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY5ID0gODY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2OSA9IDg2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjkgPSA4NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzAgPSA4NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcwID0gODcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MCA9IDg3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MSA9IDg3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzEgPSA4NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcxID0gODcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcyID0gODcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MiA9IDg3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzIgPSA4NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzMgPSA4NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODczID0gODczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODczLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MyA9IDg3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3NCA9IDg3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzQgPSA4NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc0ID0gODc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc1ID0gODc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3NSA9IDg3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzUgPSA4NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzYgPSA4NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc2ID0gODc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3NiA9IDg3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3NyA9IDg3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzcgPSA4NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc3ID0gODc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc4ID0gODc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3OCA9IDg3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzggPSA4NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzkgPSA4NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc5ID0gODc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3OSA9IDg3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4MCA9IDg4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODAgPSA4ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgwID0gODgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgxID0gODgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4MSA9IDg4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODEgPSA4ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODIgPSA4ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgyID0gODgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4MiA9IDg4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4MyA9IDg4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODMgPSA4ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgzID0gODgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg0ID0gODg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NCA9IDg4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODQgPSA4ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODUgPSA4ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg1ID0gODg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NSA9IDg4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NiA9IDg4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODYgPSA4ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg2ID0gODg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg3ID0gODg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NyA9IDg4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODcgPSA4ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODggPSA4ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg4ID0gODg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4OCA9IDg4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4OSA9IDg4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODkgPSA4ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg5ID0gODg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkwID0gODkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MCA9IDg5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTAgPSA4OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTEgPSA4OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkxID0gODkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MSA9IDg5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MiA9IDg5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTIgPSA4OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkyID0gODkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkzID0gODkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MyA9IDg5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTMgPSA4OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTQgPSA4OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk0ID0gODk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NCA9IDg5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NSA9IDg5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTUgPSA4OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk1ID0gODk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk2ID0gODk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NiA9IDg5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTYgPSA4OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTcgPSA4OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk3ID0gODk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NyA9IDg5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5OCA9IDg5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTggPSA4OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk4ID0gODk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk5ID0gODk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5OSA9IDg5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTkgPSA4OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDAgPSA5MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAwID0gOTAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMCA9IDkwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMSA9IDkwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDEgPSA5MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAxID0gOTAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAyID0gOTAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMiA9IDkwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDIgPSA5MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDMgPSA5MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAzID0gOTAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMyA9IDkwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwNCA9IDkwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDQgPSA5MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA0ID0gOTA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA1ID0gOTA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwNSA9IDkwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDUgPSA5MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDYgPSA5MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA2ID0gOTA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwNiA9IDkwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwNyA9IDkwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDcgPSA5MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA3ID0gOTA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA4ID0gOTA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwOCA9IDkwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDggPSA5MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDkgPSA5MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA5ID0gOTA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwOSA9IDkwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxMCA9IDkxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTAgPSA5MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEwID0gOTEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTExID0gOTExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxMSA9IDkxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTExKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTEgPSA5MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTExLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTExQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTIgPSA5MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEyID0gOTEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxMiA9IDkxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxMyA9IDkxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTMgPSA5MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEzID0gOTEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE0ID0gOTE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNCA9IDkxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTQgPSA5MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTUgPSA5MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE1ID0gOTE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNSA9IDkxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNiA9IDkxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTYgPSA5MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE2ID0gOTE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE3ID0gOTE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNyA9IDkxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTcgPSA5MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTggPSA5MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE4ID0gOTE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxOCA9IDkxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MThCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxOSA9IDkxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTkgPSA5MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE5ID0gOTE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIwID0gOTIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMCA9IDkyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjAgPSA5MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjEgPSA5MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIxID0gOTIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMSA9IDkyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMiA9IDkyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjIgPSA5MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIyID0gOTIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIzID0gOTIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMyA9IDkyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjMgPSA5MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjQgPSA5MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI0ID0gOTI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNCA9IDkyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNSA9IDkyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjUgPSA5MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI1ID0gOTI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI2ID0gOTI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNiA9IDkyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjYgPSA5MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjcgPSA5MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI3ID0gOTI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNyA9IDkyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyOCA9IDkyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjggPSA5MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI4ID0gOTI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI5ID0gOTI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyOSA9IDkyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjkgPSA5MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzAgPSA5MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMwID0gOTMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMCA9IDkzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMSA9IDkzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzEgPSA5MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMxID0gOTMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMyID0gOTMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMiA9IDkzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzIgPSA5MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzMgPSA5MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMzID0gOTMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMyA9IDkzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzNCA9IDkzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzQgPSA5MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM0ID0gOTM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM1ID0gOTM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzNSA9IDkzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzUgPSA5MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzYgPSA5MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM2ID0gOTM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzNiA9IDkzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzNyA9IDkzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzcgPSA5MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM3ID0gOTM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM4ID0gOTM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzOCA9IDkzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzggPSA5MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzkgPSA5MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM5ID0gOTM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzOSA9IDkzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0MCA9IDk0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDAgPSA5NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQwID0gOTQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQxID0gOTQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0MSA9IDk0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDEgPSA5NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDIgPSA5NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQyID0gOTQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0MiA9IDk0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0MyA9IDk0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDMgPSA5NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQzID0gOTQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ0ID0gOTQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NCA9IDk0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDQgPSA5NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDUgPSA5NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ1ID0gOTQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NSA9IDk0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NiA9IDk0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDYgPSA5NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ2ID0gOTQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ3ID0gOTQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NyA9IDk0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDcgPSA5NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDggPSA5NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ4ID0gOTQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0OCA9IDk0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0OSA9IDk0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDkgPSA5NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ5ID0gOTQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUwID0gOTUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MCA9IDk1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTAgPSA5NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTEgPSA5NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUxID0gOTUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MSA9IDk1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MiA9IDk1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTIgPSA5NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUyID0gOTUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUzID0gOTUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MyA9IDk1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTMgPSA5NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTQgPSA5NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU0ID0gOTU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NCA9IDk1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NSA9IDk1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTUgPSA5NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU1ID0gOTU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU2ID0gOTU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NiA9IDk1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTYgPSA5NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTcgPSA5NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU3ID0gOTU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NyA9IDk1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1OCA9IDk1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTggPSA5NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU4ID0gOTU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU5ID0gOTU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1OSA9IDk1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTkgPSA5NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjAgPSA5NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYwID0gOTYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MCA9IDk2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MSA9IDk2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjEgPSA5NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYxID0gOTYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYyID0gOTYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MiA9IDk2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjIgPSA5NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjMgPSA5NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYzID0gOTYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MyA9IDk2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2NCA9IDk2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjQgPSA5NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY0ID0gOTY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY1ID0gOTY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2NSA9IDk2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjUgPSA5NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjYgPSA5NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY2ID0gOTY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2NiA9IDk2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2NyA9IDk2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjcgPSA5NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY3ID0gOTY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY4ID0gOTY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2OCA9IDk2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjggPSA5NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjkgPSA5NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY5ID0gOTY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2OSA9IDk2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MCA9IDk3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzAgPSA5NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcwID0gOTcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcxID0gOTcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MSA9IDk3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzEgPSA5NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzIgPSA5NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcyID0gOTcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MiA9IDk3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MyA9IDk3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTczIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTczKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzMgPSA5NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTczID0gOTczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3My4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3M0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc0ID0gOTc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NCA9IDk3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzQgPSA5NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzUgPSA5NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc1ID0gOTc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc1LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NSA9IDk3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NiA9IDk3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzYgPSA5NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzYuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc2ID0gOTc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Ni4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc3ID0gOTc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NyA9IDk3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Ny4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzcgPSA5NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzggPSA5NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc4ID0gOTc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3OCA9IDk3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3OSA9IDk3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzkgPSA5NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzkuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc5ID0gOTc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgwID0gOTgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MCA9IDk4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODAgPSA5ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODEgPSA5ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgxID0gOTgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MSA9IDk4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MiA9IDk4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODIgPSA5ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgyID0gOTgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Mi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgzID0gOTgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MyA9IDk4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4My4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODMgPSA5ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODQgPSA5ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg0ID0gOTg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NCA9IDk4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NSA9IDk4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODUgPSA5ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg1ID0gOTg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg2ID0gOTg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NiA9IDk4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Ni4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODYgPSA5ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg2LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODcgPSA5ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg3ID0gOTg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NyA9IDk4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4OCA9IDk4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODggPSA5ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg4ID0gOTg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg5ID0gOTg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4OSA9IDk4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODkgPSA5ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg5LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTAgPSA5OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkwID0gOTkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MCA9IDk5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MSA9IDk5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTEgPSA5OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkxID0gOTkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkyID0gOTkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MiA9IDk5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Mi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTIgPSA5OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTMgPSA5OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkzID0gOTkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MyA9IDk5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NCA9IDk5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTQgPSA5OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk0ID0gOTk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk1ID0gOTk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NSA9IDk5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTUgPSA5OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTYgPSA5OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk2ID0gOTk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NiA9IDk5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NyA9IDk5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTcgPSA5OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk3ID0gOTk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Ny4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5N0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk4ID0gOTk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5OCA9IDk5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTggPSA5OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTkgPSA5OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk5ID0gOTk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTkoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5OSA9IDk5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMDAgPSAxMDAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAwMCA9IDEwMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDAwID0gMTAwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMEJ5dGVzKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogY2xhbmctZm9ybWF0IG9mZgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEVub3Jtb3VzRGVzY3JpcHRvcn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVub3Jtb3VzRGVzY3JpcHRvcikKICAgICAgVGVzdEVub3Jtb3VzRGVzY3JpcHRvck9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdEVub3Jtb3VzRGVzY3JpcHRvci5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0RW5vcm1vdXNEZXNjcmlwdG9yKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdEVub3Jtb3VzRGVzY3JpcHRvcigpIHsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDExXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTczXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzExXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODczXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RFbm9ybW91c0Rlc2NyaXB0b3IoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW5vcm1vdXNEZXNjcmlwdG9yX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVub3Jtb3VzRGVzY3JpcHRvcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvci5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDFfOwogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQyXzsKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkM187CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDRfOwogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQ1XzsKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkNl87CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDdfOwogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQ4XzsKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkOV87CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDEwXzsKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMTFfOwogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQxMl87CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDEzXzsKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMTRfOwogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQxNV87CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDE2XzsKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMTdfOwogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQxOF87CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDE5XzsKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMjBfOwogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQyMV87CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDIyXzsKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMjNfOwogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQyNF87CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDI1XzsKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMjZfOwogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQyN187CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDI4XzsKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMjlfOwogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQzMF87CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDMxXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzFfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEgPSAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEgPSAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xID0gMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzJfRklFTERfTlVNQkVSID0gMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIgPSAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIgPSAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yID0gMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzNfRklFTERfTlVNQkVSID0gMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMgPSAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMgPSAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zID0gMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzRfRklFTERfTlVNQkVSID0gNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQgPSA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQgPSA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ID0gNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzVfRklFTERfTlVNQkVSID0gNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUgPSA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUgPSA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ID0gNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzZfRklFTERfTlVNQkVSID0gNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYgPSA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYgPSA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ID0gNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzdfRklFTERfTlVNQkVSID0gNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcgPSA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcgPSA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ID0gNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzhfRklFTERfTlVNQkVSID0gODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzggPSA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzggPSA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ID0gOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzlfRklFTERfTlVNQkVSID0gOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkgPSA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkgPSA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ID0gOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzEwX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwID0gMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMCA9IDEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAgPSAxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMV9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMSA9IDExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEgPSAxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTFfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExID0gMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTJfRklFTERfTlVNQkVSID0gMTI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIgPSAxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyID0gMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMiA9IDEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzEzX0ZJRUxEX05VTUJFUiA9IDEzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzID0gMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMyA9IDEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMgPSAxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxM0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNF9GSUVMRF9OVU1CRVIgPSAxNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNCA9IDE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQgPSAxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0ID0gMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTVfRklFTERfTlVNQkVSID0gMTU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUgPSAxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1ID0gMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNSA9IDE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE2X0ZJRUxEX05VTUJFUiA9IDE2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2ID0gMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNiA9IDE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYgPSAxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xN19GSUVMRF9OVU1CRVIgPSAxNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNyA9IDE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcgPSAxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3ID0gMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMThfRklFTERfTlVNQkVSID0gMTg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTggPSAxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4ID0gMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOCA9IDE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE5X0ZJRUxEX05VTUJFUiA9IDE5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5ID0gMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOSA9IDE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkgPSAxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMF9GSUVMRF9OVU1CRVIgPSAyMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMCA9IDIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwODAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAgPSAyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjBfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwID0gMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjBfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjFfRklFTERfTlVNQkVSID0gMjE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEgPSAyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxID0gMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMSA9IDIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIyX0ZJRUxEX05VTUJFUiA9IDIyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyID0gMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMiA9IDIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIgPSAyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yM19GSUVMRF9OVU1CRVIgPSAyMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMyA9IDIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMgPSAyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzID0gMjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjRfRklFTERfTlVNQkVSID0gMjQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQgPSAyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0ID0gMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNCA9IDI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI1X0ZJRUxEX05VTUJFUiA9IDI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1ID0gMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNSA9IDI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUgPSAyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNl9GSUVMRF9OVU1CRVIgPSAyNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNiA9IDI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYgPSAyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjZfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2ID0gMjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjZfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjdfRklFTERfTlVNQkVSID0gMjc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcgPSAyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3ID0gMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNyA9IDI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI4X0ZJRUxEX05VTUJFUiA9IDI4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4ID0gMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOCA9IDI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjggPSAyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yOV9GSUVMRF9OVU1CRVIgPSAyOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOSA9IDI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkgPSAyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjlfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5ID0gMjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMzBfRklFTERfTlVNQkVSID0gMzA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAgPSAzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwID0gMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMCA9IDMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzMxX0ZJRUxEX05VTUJFUiA9IDMxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxID0gMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMSA9IDMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEgPSAzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMl9GSUVMRF9OVU1CRVIgPSAzMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMiA9IDMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIgPSAzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyID0gMzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzJfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMzNfRklFTERfTlVNQkVSID0gMzM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMgPSAzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzID0gMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMyA9IDMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzM0X0ZJRUxEX05VTUJFUiA9IDM0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0ID0gMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNCA9IDM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQgPSAzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNV9GSUVMRF9OVU1CRVIgPSAzNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNSA9IDM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUgPSAzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1ID0gMzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzVfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMzZfRklFTERfTlVNQkVSID0gMzY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYgPSAzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2ID0gMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNiA9IDM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzM3X0ZJRUxEX05VTUJFUiA9IDM3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3ID0gMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNyA9IDM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcgPSAzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczN0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zOF9GSUVMRF9OVU1CRVIgPSAzODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOCA9IDM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzggPSAzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzhfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4ID0gMzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzhfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMzlfRklFTERfTlVNQkVSID0gMzk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkgPSAzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5ID0gMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOSA9IDM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzQwX0ZJRUxEX05VTUJFUiA9IDQwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwID0gNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MCA9IDQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAgPSA0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MV9GSUVMRF9OVU1CRVIgPSA0MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MSA9IDQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEgPSA0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDFfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxID0gNDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfNDJfRklFTERfTlVNQkVSID0gNDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIgPSA0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyID0gNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MiA9IDQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzQzX0ZJRUxEX05VTUJFUiA9IDQzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzID0gNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MyA9IDQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMgPSA0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0M0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NF9GSUVMRF9OVU1CRVIgPSA0NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NCA9IDQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQgPSA0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0ID0gNDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfNDVfRklFTERfTlVNQkVSID0gNDU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUgPSA0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1ID0gNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NSA9IDQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzQ2X0ZJRUxEX05VTUJFUiA9IDQ2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2ID0gNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NiA9IDQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYgPSA0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180N19GSUVMRF9OVU1CRVIgPSA0NzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NyA9IDQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcgPSA0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3ID0gNDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfNDhfRklFTERfTlVNQkVSID0gNDg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDggPSA0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4ID0gNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OCA9IDQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzQ5X0ZJRUxEX05VTUJFUiA9IDQ5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5ID0gNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OSA9IDQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkgPSA0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MF9GSUVMRF9OVU1CRVIgPSA1MDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MCA9IDUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAgPSA1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTBfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwID0gNTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTBfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfNTFfRklFTERfTlVNQkVSID0gNTE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEgPSA1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDQwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxID0gNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MSA9IDUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzUyX0ZJRUxEX05VTUJFUiA9IDUyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyID0gNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MiA9IDUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIgPSA1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181M19GSUVMRF9OVU1CRVIgPSA1MzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MyA9IDUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMgPSA1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzID0gNTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfNTRfRklFTERfTlVNQkVSID0gNTQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQgPSA1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0ID0gNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NCA9IDU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzU1X0ZJRUxEX05VTUJFUiA9IDU1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1ID0gNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NSA9IDU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUgPSA1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181Nl9GSUVMRF9OVU1CRVIgPSA1NjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NiA9IDU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYgPSA1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTZfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2ID0gNTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTZfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfNTdfRklFTERfTlVNQkVSID0gNTc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcgPSA1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3ID0gNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NyA9IDU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzU4X0ZJRUxEX05VTUJFUiA9IDU4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4ID0gNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OCA9IDU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNThfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTggPSA1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181OV9GSUVMRF9OVU1CRVIgPSA1OTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OSA9IDU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkgPSA1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTlfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5ID0gNTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfNjBfRklFTERfTlVNQkVSID0gNjA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAgPSA2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDA4MDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwID0gNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MCA9IDYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzYxX0ZJRUxEX05VTUJFUiA9IDYxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxID0gNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MSA9IDYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEgPSA2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182Ml9GSUVMRF9OVU1CRVIgPSA2MjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MiA9IDYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIgPSA2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyID0gNjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjJfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfNjNfRklFTERfTlVNQkVSID0gNjM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMgPSA2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDQwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzID0gNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MyA9IDYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzY0X0ZJRUxEX05VTUJFUiA9IDY0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0ID0gNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NCA9IDY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQgPSA2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NV9GSUVMRF9OVU1CRVIgPSA2NTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NSA9IDY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUgPSA2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1ID0gNjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjVfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfNjZfRklFTERfTlVNQkVSID0gNjY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYgPSA2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2ID0gNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NiA9IDY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzY3X0ZJRUxEX05VTUJFUiA9IDY3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3ID0gNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NyA9IDY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcgPSA2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2N0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182OF9GSUVMRF9OVU1CRVIgPSA2ODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OCA9IDY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjggPSA2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjhfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4ID0gNjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjhfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfNjlfRklFTERfTlVNQkVSID0gNjk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkgPSA2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5ID0gNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OSA9IDY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzcwX0ZJRUxEX05VTUJFUiA9IDcwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwID0gNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MCA9IDcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAgPSA3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MV9GSUVMRF9OVU1CRVIgPSA3MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MSA9IDcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEgPSA3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzFfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxID0gNzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfNzJfRklFTERfTlVNQkVSID0gNzI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIgPSA3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyID0gNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MiA9IDcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzczX0ZJRUxEX05VTUJFUiA9IDczOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczID0gNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MyA9IDczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMgPSA3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3M0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NF9GSUVMRF9OVU1CRVIgPSA3NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NCA9IDc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQgPSA3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0ID0gNzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfNzVfRklFTERfTlVNQkVSID0gNzU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUgPSA3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1ID0gNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NSA9IDc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzc2X0ZJRUxEX05VTUJFUiA9IDc2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2ID0gNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NiA9IDc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYgPSA3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183N19GSUVMRF9OVU1CRVIgPSA3NzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NyA9IDc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcgPSA3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3ID0gNzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfNzhfRklFTERfTlVNQkVSID0gNzg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzggPSA3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4ID0gNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OCA9IDc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzc5X0ZJRUxEX05VTUJFUiA9IDc5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5ID0gNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OSA9IDc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkgPSA3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MF9GSUVMRF9OVU1CRVIgPSA4MDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MCA9IDgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAgPSA4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODBfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwID0gODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODBfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfODFfRklFTERfTlVNQkVSID0gODE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEgPSA4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxID0gODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MSA9IDgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzgyX0ZJRUxEX05VTUJFUiA9IDgyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyID0gODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MiA9IDgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIgPSA4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184M19GSUVMRF9OVU1CRVIgPSA4MzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MyA9IDgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMgPSA4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzID0gODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfODRfRklFTERfTlVNQkVSID0gODQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQgPSA4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0ID0gODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NCA9IDg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzg1X0ZJRUxEX05VTUJFUiA9IDg1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1ID0gODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NSA9IDg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUgPSA4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184Nl9GSUVMRF9OVU1CRVIgPSA4NjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NiA9IDg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYgPSA4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODZfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2ID0gODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODZfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfODdfRklFTERfTlVNQkVSID0gODc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcgPSA4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3ID0gODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NyA9IDg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzg4X0ZJRUxEX05VTUJFUiA9IDg4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4ID0gODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OCA9IDg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODggPSA4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184OV9GSUVMRF9OVU1CRVIgPSA4OTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OSA9IDg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkgPSA4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODlfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5ID0gODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfOTBfRklFTERfTlVNQkVSID0gOTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAgPSA5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwID0gOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MCA9IDkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzkxX0ZJRUxEX05VTUJFUiA9IDkxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxID0gOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MSA9IDkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEgPSA5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185Ml9GSUVMRF9OVU1CRVIgPSA5MjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MiA9IDkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIgPSA5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyID0gOTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTJfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfOTNfRklFTERfTlVNQkVSID0gOTM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMgPSA5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzID0gOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MyA9IDkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzk0X0ZJRUxEX05VTUJFUiA9IDk0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0ID0gOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NCA9IDk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQgPSA5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NV9GSUVMRF9OVU1CRVIgPSA5NTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NSA9IDk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUgPSA5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1ID0gOTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTVfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfOTZfRklFTERfTlVNQkVSID0gOTY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYgPSA5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2ID0gOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NiA9IDk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzk3X0ZJRUxEX05VTUJFUiA9IDk3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3ID0gOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NyA9IDk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcgPSA5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5N0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185OF9GSUVMRF9OVU1CRVIgPSA5ODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OCA9IDk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTggPSA5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOThfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4ID0gOTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOThfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOThfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfOTlfRklFTERfTlVNQkVSID0gOTk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkgPSA5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5ID0gOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OSA9IDk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzEwMF9GSUVMRF9OVU1CRVIgPSAxMDA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMCA9IDEwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAwID0gMTAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDBfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMCA9IDEwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDBfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTAxX0ZJRUxEX05VTUJFUiA9IDEwMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAxID0gMTAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDEgPSAxMDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAxID0gMTAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMDJfRklFTERfTlVNQkVSID0gMTAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDIgPSAxMDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMiA9IDEwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDIgPSAxMDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzEwM19GSUVMRF9OVU1CRVIgPSAxMDM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMyA9IDEwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAzID0gMTAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMyA9IDEwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTA0X0ZJRUxEX05VTUJFUiA9IDEwNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA0ID0gMTA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDQgPSAxMDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA0ID0gMTA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMDVfRklFTERfTlVNQkVSID0gMTA1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDUgPSAxMDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNSA9IDEwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDUgPSAxMDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzEwNl9GSUVMRF9OVU1CRVIgPSAxMDY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNiA9IDEwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA2ID0gMTA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA2KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDZfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNiA9IDEwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA2Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDZfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTA3X0ZJRUxEX05VTUJFUiA9IDEwNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA3ID0gMTA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDcgPSAxMDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA3ID0gMTA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMDhfRklFTERfTlVNQkVSID0gMTA4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDggPSAxMDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwOCA9IDEwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDggPSAxMDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzEwOV9GSUVMRF9OVU1CRVIgPSAxMDk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwOSA9IDEwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA5ID0gMTA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDlfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwOSA9IDEwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA5Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTEwX0ZJRUxEX05VTUJFUiA9IDExMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEwID0gMTEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTAgPSAxMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEwID0gMTEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMTFfRklFTERfTlVNQkVSID0gMTExOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTEgPSAxMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMSA9IDExMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTEgPSAxMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzExMl9GSUVMRF9OVU1CRVIgPSAxMTI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMiA9IDExMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEyID0gMTEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEyKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMiA9IDExMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEyQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTJfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTEzX0ZJRUxEX05VTUJFUiA9IDExMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEzID0gMTEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTMgPSAxMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEzID0gMTEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMTRfRklFTERfTlVNQkVSID0gMTE0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTQgPSAxMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNCA9IDExNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTQgPSAxMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzExNV9GSUVMRF9OVU1CRVIgPSAxMTU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNSA9IDExNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE1ID0gMTE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE1KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNSA9IDExNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE1Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTVfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTE2X0ZJRUxEX05VTUJFUiA9IDExNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE2ID0gMTE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTYgPSAxMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE2ID0gMTE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMTdfRklFTERfTlVNQkVSID0gMTE3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTcgPSAxMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNyA9IDExNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTcgPSAxMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExN0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzExOF9GSUVMRF9OVU1CRVIgPSAxMTg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExOCA9IDExOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE4ID0gMTE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE4KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMThfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMThfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExOCA9IDExOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE4Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMThfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTE5X0ZJRUxEX05VTUJFUiA9IDExOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE5ID0gMTE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTkgPSAxMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE5ID0gMTE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMjBfRklFTERfTlVNQkVSID0gMTIwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjAgPSAxMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMCA9IDEyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjAgPSAxMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzEyMV9GSUVMRF9OVU1CRVIgPSAxMjE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMSA9IDEyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIxID0gMTIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIxKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjFfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMSA9IDEyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIxQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTIyX0ZJRUxEX05VTUJFUiA9IDEyMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIyID0gMTIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjIgPSAxMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIyID0gMTIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMjNfRklFTERfTlVNQkVSID0gMTIzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjMgPSAxMjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMyA9IDEyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjMgPSAxMjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyM0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzEyNF9GSUVMRF9OVU1CRVIgPSAxMjQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNCA9IDEyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI0ID0gMTI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNCA9IDEyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTI1X0ZJRUxEX05VTUJFUiA9IDEyNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI1ID0gMTI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjUgPSAxMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI1ID0gMTI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMjZfRklFTERfTlVNQkVSID0gMTI2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjYgPSAxMjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNiA9IDEyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjYgPSAxMjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzEyN19GSUVMRF9OVU1CRVIgPSAxMjc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNyA9IDEyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI3ID0gMTI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI3KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNyA9IDEyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI3Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTI4X0ZJRUxEX05VTUJFUiA9IDEyODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI4ID0gMTI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjggPSAxMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI4ID0gMTI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMjlfRklFTERfTlVNQkVSID0gMTI5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjkgPSAxMjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyOSA9IDEyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjkgPSAxMjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzEzMF9GSUVMRF9OVU1CRVIgPSAxMzA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMCA9IDEzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMwID0gMTMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzBfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMCA9IDEzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzBfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTMxX0ZJRUxEX05VTUJFUiA9IDEzMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMxID0gMTMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzEgPSAxMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMxID0gMTMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMzJfRklFTERfTlVNQkVSID0gMTMyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzIgPSAxMzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMiA9IDEzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzIgPSAxMzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzEzM19GSUVMRF9OVU1CRVIgPSAxMzM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMyA9IDEzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMzID0gMTMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMyA9IDEzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTM0X0ZJRUxEX05VTUJFUiA9IDEzNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM0ID0gMTM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzQgPSAxMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM0ID0gMTM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMzVfRklFTERfTlVNQkVSID0gMTM1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzUgPSAxMzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNSA9IDEzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzUgPSAxMzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzEzNl9GSUVMRF9OVU1CRVIgPSAxMzY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNiA9IDEzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwMDAwODApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM2ID0gMTM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzZfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNiA9IDEzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzZfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTM3X0ZJRUxEX05VTUJFUiA9IDEzNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM3ID0gMTM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzcgPSAxMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM3ID0gMTM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMzhfRklFTERfTlVNQkVSID0gMTM4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzggPSAxMzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzOCA9IDEzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzggPSAxMzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzEzOV9GSUVMRF9OVU1CRVIgPSAxMzk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzOSA9IDEzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM5ID0gMTM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzlfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzOSA9IDEzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTQwX0ZJRUxEX05VTUJFUiA9IDE0MDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQwID0gMTQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDAgPSAxNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQwID0gMTQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNDFfRklFTERfTlVNQkVSID0gMTQxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDEgPSAxNDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MSA9IDE0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDEgPSAxNDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE0Ml9GSUVMRF9OVU1CRVIgPSAxNDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MiA9IDE0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQyID0gMTQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MiA9IDE0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDJfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTQzX0ZJRUxEX05VTUJFUiA9IDE0MzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQzID0gMTQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDMgPSAxNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQzID0gMTQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNDRfRklFTERfTlVNQkVSID0gMTQ0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDQgPSAxNDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NCA9IDE0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDQgPSAxNDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE0NV9GSUVMRF9OVU1CRVIgPSAxNDU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NSA9IDE0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ1ID0gMTQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NSA9IDE0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDVfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTQ2X0ZJRUxEX05VTUJFUiA9IDE0NjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ2ID0gMTQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDYgPSAxNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ2ID0gMTQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNDdfRklFTERfTlVNQkVSID0gMTQ3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDcgPSAxNDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMDQwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NyA9IDE0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDcgPSAxNDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0N0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE0OF9GSUVMRF9OVU1CRVIgPSAxNDg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0OCA9IDE0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwODAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ4ID0gMTQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDhfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0OCA9IDE0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDhfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTQ5X0ZJRUxEX05VTUJFUiA9IDE0OTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ5ID0gMTQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDkgPSAxNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ5ID0gMTQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNTBfRklFTERfTlVNQkVSID0gMTUwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTAgPSAxNTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MCA9IDE1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTAgPSAxNTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE1MV9GSUVMRF9OVU1CRVIgPSAxNTE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MSA9IDE1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUxID0gMTUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTFfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MSA9IDE1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTUyX0ZJRUxEX05VTUJFUiA9IDE1MjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUyID0gMTUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTIgPSAxNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUyID0gMTUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNTNfRklFTERfTlVNQkVSID0gMTUzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTMgPSAxNTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MyA9IDE1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTMgPSAxNTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1M0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE1NF9GSUVMRF9OVU1CRVIgPSAxNTQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NCA9IDE1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU0ID0gMTU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NCA9IDE1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTU1X0ZJRUxEX05VTUJFUiA9IDE1NTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU1ID0gMTU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTUgPSAxNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU1ID0gMTU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNTZfRklFTERfTlVNQkVSID0gMTU2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTYgPSAxNTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDA4MDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NiA9IDE1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTYgPSAxNTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE1N19GSUVMRF9OVU1CRVIgPSAxNTc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NyA9IDE1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU3ID0gMTU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NyA9IDE1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTU4X0ZJRUxEX05VTUJFUiA9IDE1ODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU4ID0gMTU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTggPSAxNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU4ID0gMTU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNTlfRklFTERfTlVNQkVSID0gMTU5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTkgPSAxNTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDQwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1OSA9IDE1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTkgPSAxNTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE2MF9GSUVMRF9OVU1CRVIgPSAxNjA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MCA9IDE2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYwID0gMTYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjBfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MCA9IDE2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjBfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTYxX0ZJRUxEX05VTUJFUiA9IDE2MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYxID0gMTYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjEgPSAxNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYxID0gMTYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNjJfRklFTERfTlVNQkVSID0gMTYyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjIgPSAxNjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MiA9IDE2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjIgPSAxNjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE2M19GSUVMRF9OVU1CRVIgPSAxNjM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MyA9IDE2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYzID0gMTYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MyA9IDE2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTY0X0ZJRUxEX05VTUJFUiA9IDE2NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY0ID0gMTY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjQgPSAxNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY0ID0gMTY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNjVfRklFTERfTlVNQkVSID0gMTY1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjUgPSAxNjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NSA9IDE2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjUgPSAxNjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE2Nl9GSUVMRF9OVU1CRVIgPSAxNjY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NiA9IDE2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY2ID0gMTY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjZfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NiA9IDE2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjZfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTY3X0ZJRUxEX05VTUJFUiA9IDE2NzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY3ID0gMTY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjcgPSAxNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY3ID0gMTY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNjhfRklFTERfTlVNQkVSID0gMTY4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjggPSAxNjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2OCA9IDE2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjggPSAxNjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE2OV9GSUVMRF9OVU1CRVIgPSAxNjk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2OSA9IDE2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY5ID0gMTY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjlfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2OSA9IDE2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTcwX0ZJRUxEX05VTUJFUiA9IDE3MDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcwID0gMTcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzAgPSAxNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcwID0gMTcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNzFfRklFTERfTlVNQkVSID0gMTcxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzEgPSAxNzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MSA9IDE3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzEgPSAxNzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE3Ml9GSUVMRF9OVU1CRVIgPSAxNzI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MiA9IDE3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcyID0gMTcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MiA9IDE3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzJfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTczX0ZJRUxEX05VTUJFUiA9IDE3MzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTczID0gMTczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTczKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzMgPSAxNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTczID0gMTczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTczXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNzRfRklFTERfTlVNQkVSID0gMTc0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzQgPSAxNzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NCA9IDE3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzQgPSAxNzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE3NV9GSUVMRF9OVU1CRVIgPSAxNzU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NSA9IDE3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc1ID0gMTc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NSA9IDE3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzVfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTc2X0ZJRUxEX05VTUJFUiA9IDE3NjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc2ID0gMTc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzYgPSAxNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc2ID0gMTc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xNzdfRklFTERfTlVNQkVSID0gMTc3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzcgPSAxNzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NyA9IDE3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzcgPSAxNzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3N0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE3OF9GSUVMRF9OVU1CRVIgPSAxNzg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3OCA9IDE3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc4ID0gMTc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzhfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3OCA9IDE3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzhfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTc5X0ZJRUxEX05VTUJFUiA9IDE3OTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc5ID0gMTc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzkgPSAxNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc5ID0gMTc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xODBfRklFTERfTlVNQkVSID0gMTgwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODAgPSAxODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MCA9IDE4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODAgPSAxODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE4MV9GSUVMRF9OVU1CRVIgPSAxODE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MSA9IDE4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgxID0gMTgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODFfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MSA9IDE4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTgyX0ZJRUxEX05VTUJFUiA9IDE4MjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgyID0gMTgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODIgPSAxODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgyID0gMTgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xODNfRklFTERfTlVNQkVSID0gMTgzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODMgPSAxODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MyA9IDE4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODMgPSAxODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4M0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE4NF9GSUVMRF9OVU1CRVIgPSAxODQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NCA9IDE4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg0ID0gMTg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NCA9IDE4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTg1X0ZJRUxEX05VTUJFUiA9IDE4NTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg1ID0gMTg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODUgPSAxODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg1ID0gMTg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xODZfRklFTERfTlVNQkVSID0gMTg2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODYgPSAxODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NiA9IDE4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODYgPSAxODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE4N19GSUVMRF9OVU1CRVIgPSAxODc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NyA9IDE4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg3ID0gMTg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NyA9IDE4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTg4X0ZJRUxEX05VTUJFUiA9IDE4ODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg4ID0gMTg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODggPSAxODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg4ID0gMTg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xODlfRklFTERfTlVNQkVSID0gMTg5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODkgPSAxODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4OSA9IDE4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODkgPSAxODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE5MF9GSUVMRF9OVU1CRVIgPSAxOTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MCA9IDE5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkwID0gMTkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTBfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MCA9IDE5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTBfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTkxX0ZJRUxEX05VTUJFUiA9IDE5MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkxID0gMTkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTEgPSAxOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkxID0gMTkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xOTJfRklFTERfTlVNQkVSID0gMTkyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTIgPSAxOTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MiA9IDE5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTIgPSAxOTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE5M19GSUVMRF9OVU1CRVIgPSAxOTM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MyA9IDE5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkzID0gMTkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MyA9IDE5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTk0X0ZJRUxEX05VTUJFUiA9IDE5NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk0ID0gMTk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTQgPSAxOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk0ID0gMTk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xOTVfRklFTERfTlVNQkVSID0gMTk1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTUgPSAxOTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NSA9IDE5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTUgPSAxOTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE5Nl9GSUVMRF9OVU1CRVIgPSAxOTY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NiA9IDE5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk2ID0gMTk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk2KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTZfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NiA9IDE5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk2Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTZfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMTk3X0ZJRUxEX05VTUJFUiA9IDE5NzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk3ID0gMTk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTcgPSAxOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk3ID0gMTk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xOThfRklFTERfTlVNQkVSID0gMTk4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTggPSAxOTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5OCA9IDE5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTggPSAxOTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOThfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzE5OV9GSUVMRF9OVU1CRVIgPSAxOTk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5OSA9IDE5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk5ID0gMTk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTlfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5OSA9IDE5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk5Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjAwX0ZJRUxEX05VTUJFUiA9IDIwMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAwID0gMjAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDAgPSAyMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAwID0gMjAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMDFfRklFTERfTlVNQkVSID0gMjAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDEgPSAyMDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMSA9IDIwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDEgPSAyMDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIwMl9GSUVMRF9OVU1CRVIgPSAyMDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMiA9IDIwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAyID0gMjAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAyKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMiA9IDIwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAyQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDJfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjAzX0ZJRUxEX05VTUJFUiA9IDIwMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAzID0gMjAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDMgPSAyMDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAzID0gMjAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMDRfRklFTERfTlVNQkVSID0gMjA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDQgPSAyMDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNCA9IDIwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDQgPSAyMDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIwNV9GSUVMRF9OVU1CRVIgPSAyMDU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNSA9IDIwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA1ID0gMjA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA1KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNSA9IDIwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA1Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDVfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjA2X0ZJRUxEX05VTUJFUiA9IDIwNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA2ID0gMjA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDYgPSAyMDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA2ID0gMjA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMDdfRklFTERfTlVNQkVSID0gMjA3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDcgPSAyMDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNyA9IDIwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDcgPSAyMDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwN0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIwOF9GSUVMRF9OVU1CRVIgPSAyMDg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwOCA9IDIwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA4ID0gMjA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA4KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDhfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwOCA9IDIwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA4Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDhfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjA5X0ZJRUxEX05VTUJFUiA9IDIwOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA5ID0gMjA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDkgPSAyMDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA5ID0gMjA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMTBfRklFTERfTlVNQkVSID0gMjEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTAgPSAyMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMCA9IDIxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTAgPSAyMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIxMV9GSUVMRF9OVU1CRVIgPSAyMTE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjExXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMSA9IDIxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjExIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjExID0gMjExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjExLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjExKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTFfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMSA9IDIxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjExQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjEyX0ZJRUxEX05VTUJFUiA9IDIxMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEyID0gMjEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTIgPSAyMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEyID0gMjEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMTNfRklFTERfTlVNQkVSID0gMjEzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTMgPSAyMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMyA9IDIxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTMgPSAyMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxM0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIxNF9GSUVMRF9OVU1CRVIgPSAyMTQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNCA9IDIxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE0ID0gMjE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNCA9IDIxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjE1X0ZJRUxEX05VTUJFUiA9IDIxNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE1ID0gMjE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTUgPSAyMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE1ID0gMjE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMTZfRklFTERfTlVNQkVSID0gMjE2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTYgPSAyMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNiA9IDIxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTYgPSAyMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIxN19GSUVMRF9OVU1CRVIgPSAyMTc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNyA9IDIxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE3ID0gMjE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE3KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNyA9IDIxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE3Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjE4X0ZJRUxEX05VTUJFUiA9IDIxODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE4ID0gMjE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTggPSAyMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE4ID0gMjE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMTlfRklFTERfTlVNQkVSID0gMjE5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTkgPSAyMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxOSA9IDIxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTkgPSAyMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIyMF9GSUVMRF9OVU1CRVIgPSAyMjA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMCA9IDIyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIwID0gMjIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIwKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjBfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMCA9IDIyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIwQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjBfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjIxX0ZJRUxEX05VTUJFUiA9IDIyMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIxID0gMjIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjEgPSAyMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIxID0gMjIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMjJfRklFTERfTlVNQkVSID0gMjIyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjIgPSAyMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMiA9IDIyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjIgPSAyMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIyM19GSUVMRF9OVU1CRVIgPSAyMjM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMyA9IDIyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIzID0gMjIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMyA9IDIyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjI0X0ZJRUxEX05VTUJFUiA9IDIyNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI0ID0gMjI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjQgPSAyMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI0ID0gMjI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMjVfRklFTERfTlVNQkVSID0gMjI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjUgPSAyMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNSA9IDIyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjUgPSAyMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIyNl9GSUVMRF9OVU1CRVIgPSAyMjY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNiA9IDIyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI2ID0gMjI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjZfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNiA9IDIyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjZfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjI3X0ZJRUxEX05VTUJFUiA9IDIyNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI3ID0gMjI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjcgPSAyMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI3ID0gMjI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMjhfRklFTERfTlVNQkVSID0gMjI4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjggPSAyMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyOCA9IDIyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjggPSAyMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIyOV9GSUVMRF9OVU1CRVIgPSAyMjk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyOSA9IDIyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI5ID0gMjI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjlfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyOSA9IDIyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjMwX0ZJRUxEX05VTUJFUiA9IDIzMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMwID0gMjMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzAgPSAyMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMwID0gMjMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMzFfRklFTERfTlVNQkVSID0gMjMxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzEgPSAyMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMSA9IDIzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzEgPSAyMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIzMl9GSUVMRF9OVU1CRVIgPSAyMzI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMiA9IDIzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwMDAwODApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMyID0gMjMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMiA9IDIzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzJfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjMzX0ZJRUxEX05VTUJFUiA9IDIzMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMzID0gMjMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzMgPSAyMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMzID0gMjMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMzRfRklFTERfTlVNQkVSID0gMjM0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzQgPSAyMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNCA9IDIzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzQgPSAyMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIzNV9GSUVMRF9OVU1CRVIgPSAyMzU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNSA9IDIzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM1ID0gMjM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNSA9IDIzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzVfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjM2X0ZJRUxEX05VTUJFUiA9IDIzNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM2ID0gMjM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzYgPSAyMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM2ID0gMjM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yMzdfRklFTERfTlVNQkVSID0gMjM3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzcgPSAyMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNyA9IDIzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzcgPSAyMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzN0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzIzOF9GSUVMRF9OVU1CRVIgPSAyMzg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzOCA9IDIzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM4ID0gMjM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzhfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzOCA9IDIzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzhfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjM5X0ZJRUxEX05VTUJFUiA9IDIzOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM5ID0gMjM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzkgPSAyMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM5ID0gMjM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNDBfRklFTERfTlVNQkVSID0gMjQwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDAgPSAyNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MCA9IDI0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDAgPSAyNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI0MV9GSUVMRF9OVU1CRVIgPSAyNDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MSA9IDI0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQxID0gMjQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDFfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MSA9IDI0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjQyX0ZJRUxEX05VTUJFUiA9IDI0MjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQyID0gMjQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDIgPSAyNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQyID0gMjQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNDNfRklFTERfTlVNQkVSID0gMjQzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDMgPSAyNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMDQwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MyA9IDI0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDMgPSAyNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0M0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI0NF9GSUVMRF9OVU1CRVIgPSAyNDQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NCA9IDI0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwODAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ0ID0gMjQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NCA9IDI0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjQ1X0ZJRUxEX05VTUJFUiA9IDI0NTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ1ID0gMjQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDUgPSAyNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ1ID0gMjQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNDZfRklFTERfTlVNQkVSID0gMjQ2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDYgPSAyNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NiA9IDI0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDYgPSAyNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI0N19GSUVMRF9OVU1CRVIgPSAyNDc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NyA9IDI0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ3ID0gMjQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NyA9IDI0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjQ4X0ZJRUxEX05VTUJFUiA9IDI0ODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ4ID0gMjQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDggPSAyNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ4ID0gMjQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNDlfRklFTERfTlVNQkVSID0gMjQ5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDkgPSAyNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0OSA9IDI0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDkgPSAyNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI1MF9GSUVMRF9OVU1CRVIgPSAyNTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MCA9IDI1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUwID0gMjUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTBfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MCA9IDI1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTBfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjUxX0ZJRUxEX05VTUJFUiA9IDI1MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUxID0gMjUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTEgPSAyNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUxID0gMjUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNTJfRklFTERfTlVNQkVSID0gMjUyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTIgPSAyNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDA4MDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MiA9IDI1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTIgPSAyNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI1M19GSUVMRF9OVU1CRVIgPSAyNTM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MyA9IDI1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUzID0gMjUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MyA9IDI1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjU0X0ZJRUxEX05VTUJFUiA9IDI1NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU0ID0gMjU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTQgPSAyNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU0ID0gMjU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNTVfRklFTERfTlVNQkVSID0gMjU1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTUgPSAyNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDQwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NSA9IDI1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTUgPSAyNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI1Nl9GSUVMRF9OVU1CRVIgPSAyNTY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NiA9IDI1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU2ID0gMjU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTZfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NiA9IDI1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTZfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjU3X0ZJRUxEX05VTUJFUiA9IDI1NzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU3ID0gMjU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTcgPSAyNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU3ID0gMjU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNThfRklFTERfTlVNQkVSID0gMjU4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTggPSAyNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1OCA9IDI1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTggPSAyNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNThfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI1OV9GSUVMRF9OVU1CRVIgPSAyNTk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1OSA9IDI1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU5ID0gMjU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTlfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1OSA9IDI1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjYwX0ZJRUxEX05VTUJFUiA9IDI2MDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYwID0gMjYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjAgPSAyNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYwID0gMjYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNjFfRklFTERfTlVNQkVSID0gMjYxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjEgPSAyNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MSA9IDI2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjEgPSAyNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI2Ml9GSUVMRF9OVU1CRVIgPSAyNjI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MiA9IDI2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYyID0gMjYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MiA9IDI2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjJfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjYzX0ZJRUxEX05VTUJFUiA9IDI2MzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYzID0gMjYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjMgPSAyNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYzID0gMjYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNjRfRklFTERfTlVNQkVSID0gMjY0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjQgPSAyNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NCA9IDI2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjQgPSAyNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI2NV9GSUVMRF9OVU1CRVIgPSAyNjU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NSA9IDI2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY1ID0gMjY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NSA9IDI2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjVfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjY2X0ZJRUxEX05VTUJFUiA9IDI2NjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY2ID0gMjY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjYgPSAyNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY2ID0gMjY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNjdfRklFTERfTlVNQkVSID0gMjY3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjcgPSAyNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NyA9IDI2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjcgPSAyNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2N0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI2OF9GSUVMRF9OVU1CRVIgPSAyNjg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2OCA9IDI2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY4ID0gMjY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjhfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2OCA9IDI2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjhfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjY5X0ZJRUxEX05VTUJFUiA9IDI2OTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY5ID0gMjY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjkgPSAyNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY5ID0gMjY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNzBfRklFTERfTlVNQkVSID0gMjcwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzAgPSAyNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MCA9IDI3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzAgPSAyNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI3MV9GSUVMRF9OVU1CRVIgPSAyNzE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MSA9IDI3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcxID0gMjcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzFfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MSA9IDI3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjcyX0ZJRUxEX05VTUJFUiA9IDI3MjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcyID0gMjcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzIgPSAyNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcyID0gMjcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNzNfRklFTERfTlVNQkVSID0gMjczOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzMgPSAyNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MyA9IDI3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzMgPSAyNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3M0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI3NF9GSUVMRF9OVU1CRVIgPSAyNzQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NCA9IDI3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc0ID0gMjc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NCA9IDI3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjc1X0ZJRUxEX05VTUJFUiA9IDI3NTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc1ID0gMjc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzUgPSAyNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc1ID0gMjc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNzZfRklFTERfTlVNQkVSID0gMjc2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzYgPSAyNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NiA9IDI3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzYgPSAyNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI3N19GSUVMRF9OVU1CRVIgPSAyNzc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NyA9IDI3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc3ID0gMjc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NyA9IDI3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjc4X0ZJRUxEX05VTUJFUiA9IDI3ODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc4ID0gMjc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzggPSAyNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc4ID0gMjc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yNzlfRklFTERfTlVNQkVSID0gMjc5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzkgPSAyNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3OSA9IDI3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzkgPSAyNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI4MF9GSUVMRF9OVU1CRVIgPSAyODA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MCA9IDI4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgwID0gMjgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODBfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MCA9IDI4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODBfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjgxX0ZJRUxEX05VTUJFUiA9IDI4MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgxID0gMjgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODEgPSAyODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgxID0gMjgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yODJfRklFTERfTlVNQkVSID0gMjgyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODIgPSAyODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MiA9IDI4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODIgPSAyODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI4M19GSUVMRF9OVU1CRVIgPSAyODM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MyA9IDI4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgzID0gMjgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MyA9IDI4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjg0X0ZJRUxEX05VTUJFUiA9IDI4NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg0ID0gMjg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODQgPSAyODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg0ID0gMjg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yODVfRklFTERfTlVNQkVSID0gMjg1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODUgPSAyODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NSA9IDI4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODUgPSAyODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI4Nl9GSUVMRF9OVU1CRVIgPSAyODY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NiA9IDI4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg2ID0gMjg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODZfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NiA9IDI4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODZfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjg3X0ZJRUxEX05VTUJFUiA9IDI4NzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg3ID0gMjg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODcgPSAyODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg3ID0gMjg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yODhfRklFTERfTlVNQkVSID0gMjg4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODggPSAyODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4OCA9IDI4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODggPSAyODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI4OV9GSUVMRF9OVU1CRVIgPSAyODk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4OSA9IDI4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg5ID0gMjg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODlfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4OSA9IDI4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg5Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjkwX0ZJRUxEX05VTUJFUiA9IDI5MDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkwID0gMjkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTAgPSAyOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkwID0gMjkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yOTFfRklFTERfTlVNQkVSID0gMjkxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTEgPSAyOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MSA9IDI5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTEgPSAyOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI5Ml9GSUVMRF9OVU1CRVIgPSAyOTI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MiA9IDI5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkyID0gMjkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkyKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MiA9IDI5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkyQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTJfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjkzX0ZJRUxEX05VTUJFUiA9IDI5MzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkzID0gMjkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTMgPSAyOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkzID0gMjkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yOTRfRklFTERfTlVNQkVSID0gMjk0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTQgPSAyOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NCA9IDI5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTQgPSAyOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI5NV9GSUVMRF9OVU1CRVIgPSAyOTU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NSA9IDI5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk1ID0gMjk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk1KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NSA9IDI5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk1Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTVfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjk2X0ZJRUxEX05VTUJFUiA9IDI5NjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk2ID0gMjk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTYgPSAyOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk2ID0gMjk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18yOTdfRklFTERfTlVNQkVSID0gMjk3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTcgPSAyOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NyA9IDI5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTcgPSAyOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5N0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzI5OF9GSUVMRF9OVU1CRVIgPSAyOTg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5OCA9IDI5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk4ID0gMjk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk4KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOThfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOThfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5OCA9IDI5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk4Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOThfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMjk5X0ZJRUxEX05VTUJFUiA9IDI5OTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk5ID0gMjk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTkgPSAyOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk5ID0gMjk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMDBfRklFTERfTlVNQkVSID0gMzAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDAgPSAzMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMCA9IDMwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDAgPSAzMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzMwMV9GSUVMRF9OVU1CRVIgPSAzMDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMSA9IDMwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAxID0gMzAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAxKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDFfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMSA9IDMwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAxQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMzAyX0ZJRUxEX05VTUJFUiA9IDMwMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAyID0gMzAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDIgPSAzMDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAyID0gMzAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMDNfRklFTERfTlVNQkVSID0gMzAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDMgPSAzMDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMyA9IDMwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDMgPSAzMDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwM0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzMwNF9GSUVMRF9OVU1CRVIgPSAzMDQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNCA9IDMwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA0ID0gMzA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNCA9IDMwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMzA1X0ZJRUxEX05VTUJFUiA9IDMwNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA1ID0gMzA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDUgPSAzMDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA1ID0gMzA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMDZfRklFTERfTlVNQkVSID0gMzA2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDYgPSAzMDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNiA9IDMwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDYgPSAzMDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzMwN19GSUVMRF9OVU1CRVIgPSAzMDc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNyA9IDMwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA3ID0gMzA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA3KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNyA9IDMwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA3Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMzA4X0ZJRUxEX05VTUJFUiA9IDMwODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA4ID0gMzA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDggPSAzMDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA4ID0gMzA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMDlfRklFTERfTlVNQkVSID0gMzA5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDkgPSAzMDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwOSA9IDMwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDkgPSAzMDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzMxMF9GSUVMRF9OVU1CRVIgPSAzMTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMCA9IDMxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEwID0gMzEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEwKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTBfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMCA9IDMxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEwQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTBfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMzExX0ZJRUxEX05VTUJFUiA9IDMxMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzExID0gMzExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzExKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTEgPSAzMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzExID0gMzExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzExXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMTJfRklFTERfTlVNQkVSID0gMzEyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTIgPSAzMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMiA9IDMxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTIgPSAzMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzMxM19GSUVMRF9OVU1CRVIgPSAzMTM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMyA9IDMxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEzID0gMzEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMyA9IDMxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMzE0X0ZJRUxEX05VTUJFUiA9IDMxNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE0ID0gMzE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTQgPSAzMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE0ID0gMzE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMTVfRklFTERfTlVNQkVSID0gMzE1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTUgPSAzMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNSA9IDMxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTUgPSAzMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzMxNl9GSUVMRF9OVU1CRVIgPSAzMTY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNiA9IDMxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE2ID0gMzE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE2KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTZfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNiA9IDMxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE2Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTZfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMzE3X0ZJRUxEX05VTUJFUiA9IDMxNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE3ID0gMzE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTcgPSAzMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE3ID0gMzE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMThfRklFTERfTlVNQkVSID0gMzE4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTggPSAzMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxOCA9IDMxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTggPSAzMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMThfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExPTkdfRklFTERfTkFNRV9JU19MT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT05HXzMxOV9GSUVMRF9OVU1CRVIgPSAzMTk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxOSA9IDMxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE5ID0gMzE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTlfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxOSA9IDMxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE5Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTE9OR19GSUVMRF9OQU1FX0lTX0xPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PTkdfMzIwX0ZJRUxEX05VTUJFUiA9IDMyMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIwID0gMzIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjAgPSAzMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIwID0gMzIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMjFfRklFTERfTlVNQkVSID0gMzIxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjEgPSAzMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjEgPSAzMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIxID0gMzIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMjJfRklFTERfTlVNQkVSID0gMzIyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjIgPSAzMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjIgPSAzMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIyID0gMzIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMjNfRklFTERfTlVNQkVSID0gMzIzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjMgPSAzMjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjMgPSAzMjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIzID0gMzIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMjRfRklFTERfTlVNQkVSID0gMzI0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjQgPSAzMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjQgPSAzMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI0ID0gMzI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMjVfRklFTERfTlVNQkVSID0gMzI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjUgPSAzMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjUgPSAzMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI1ID0gMzI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMjZfRklFTERfTlVNQkVSID0gMzI2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjYgPSAzMjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjYgPSAzMjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI2ID0gMzI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMjdfRklFTERfTlVNQkVSID0gMzI3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjcgPSAzMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjcgPSAzMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI3ID0gMzI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMjhfRklFTERfTlVNQkVSID0gMzI4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjggPSAzMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjggPSAzMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI4ID0gMzI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMjlfRklFTERfTlVNQkVSID0gMzI5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjkgPSAzMjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjkgPSAzMjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI5ID0gMzI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMzBfRklFTERfTlVNQkVSID0gMzMwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzAgPSAzMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzAgPSAzMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMwID0gMzMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMzFfRklFTERfTlVNQkVSID0gMzMxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzEgPSAzMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzEgPSAzMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMxID0gMzMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMzJfRklFTERfTlVNQkVSID0gMzMyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzIgPSAzMzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzIgPSAzMzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMyID0gMzMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMzNfRklFTERfTlVNQkVSID0gMzMzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzMgPSAzMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzMgPSAzMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMzID0gMzMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMzRfRklFTERfTlVNQkVSID0gMzM0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzQgPSAzMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzQgPSAzMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM0ID0gMzM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMzVfRklFTERfTlVNQkVSID0gMzM1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzUgPSAzMzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzUgPSAzMzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM1ID0gMzM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMzZfRklFTERfTlVNQkVSID0gMzM2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzYgPSAzMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzYgPSAzMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM2ID0gMzM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMzdfRklFTERfTlVNQkVSID0gMzM3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzcgPSAzMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzcgPSAzMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM3ID0gMzM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMzhfRklFTERfTlVNQkVSID0gMzM4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzggPSAzMzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzggPSAzMzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM4ID0gMzM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zMzlfRklFTERfTlVNQkVSID0gMzM5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzkgPSAzMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzkgPSAzMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM5ID0gMzM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNDBfRklFTERfTlVNQkVSID0gMzQwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDAgPSAzNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDAgPSAzNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQwID0gMzQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNDFfRklFTERfTlVNQkVSID0gMzQxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDEgPSAzNDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDEgPSAzNDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQxID0gMzQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNDJfRklFTERfTlVNQkVSID0gMzQyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDIgPSAzNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDIgPSAzNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQyID0gMzQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNDNfRklFTERfTlVNQkVSID0gMzQzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDMgPSAzNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDMgPSAzNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQzID0gMzQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNDRfRklFTERfTlVNQkVSID0gMzQ0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDQgPSAzNDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDQgPSAzNDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ0ID0gMzQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNDVfRklFTERfTlVNQkVSID0gMzQ1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDUgPSAzNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDUgPSAzNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ1ID0gMzQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNDZfRklFTERfTlVNQkVSID0gMzQ2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDYgPSAzNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDYgPSAzNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ2ID0gMzQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNDdfRklFTERfTlVNQkVSID0gMzQ3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDcgPSAzNDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDcgPSAzNDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ3ID0gMzQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNDhfRklFTERfTlVNQkVSID0gMzQ4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDggPSAzNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDggPSAzNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ4ID0gMzQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNDlfRklFTERfTlVNQkVSID0gMzQ5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDkgPSAzNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDkgPSAzNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ5ID0gMzQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNTBfRklFTERfTlVNQkVSID0gMzUwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTAgPSAzNTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTAgPSAzNTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUwID0gMzUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNTFfRklFTERfTlVNQkVSID0gMzUxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTEgPSAzNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTEgPSAzNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUxID0gMzUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNTJfRklFTERfTlVNQkVSID0gMzUyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTIgPSAzNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTIgPSAzNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUyID0gMzUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNTNfRklFTERfTlVNQkVSID0gMzUzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTMgPSAzNTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTMgPSAzNTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUzID0gMzUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNTRfRklFTERfTlVNQkVSID0gMzU0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTQgPSAzNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTQgPSAzNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU0ID0gMzU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNTVfRklFTERfTlVNQkVSID0gMzU1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTUgPSAzNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTUgPSAzNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU1ID0gMzU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNTZfRklFTERfTlVNQkVSID0gMzU2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTYgPSAzNTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTYgPSAzNTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU2ID0gMzU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNTdfRklFTERfTlVNQkVSID0gMzU3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTcgPSAzNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTcgPSAzNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU3ID0gMzU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNThfRklFTERfTlVNQkVSID0gMzU4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTggPSAzNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTggPSAzNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU4ID0gMzU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNTlfRklFTERfTlVNQkVSID0gMzU5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTkgPSAzNTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTkgPSAzNTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU5ID0gMzU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNjBfRklFTERfTlVNQkVSID0gMzYwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjAgPSAzNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjAgPSAzNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYwID0gMzYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNjFfRklFTERfTlVNQkVSID0gMzYxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjEgPSAzNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjEgPSAzNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYxID0gMzYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNjJfRklFTERfTlVNQkVSID0gMzYyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjIgPSAzNjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjIgPSAzNjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYyID0gMzYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNjNfRklFTERfTlVNQkVSID0gMzYzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjMgPSAzNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjMgPSAzNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYzID0gMzYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNjRfRklFTERfTlVNQkVSID0gMzY0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjQgPSAzNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjQgPSAzNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY0ID0gMzY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNjVfRklFTERfTlVNQkVSID0gMzY1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjUgPSAzNjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjUgPSAzNjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY1ID0gMzY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNjZfRklFTERfTlVNQkVSID0gMzY2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjYgPSAzNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjYgPSAzNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY2ID0gMzY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNjdfRklFTERfTlVNQkVSID0gMzY3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjcgPSAzNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjcgPSAzNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY3ID0gMzY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNjhfRklFTERfTlVNQkVSID0gMzY4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjggPSAzNjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjggPSAzNjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY4ID0gMzY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNjlfRklFTERfTlVNQkVSID0gMzY5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjkgPSAzNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjkgPSAzNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY5ID0gMzY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNzBfRklFTERfTlVNQkVSID0gMzcwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzAgPSAzNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzAgPSAzNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcwID0gMzcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNzFfRklFTERfTlVNQkVSID0gMzcxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzEgPSAzNzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzEgPSAzNzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcxID0gMzcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNzJfRklFTERfTlVNQkVSID0gMzcyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzIgPSAzNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzIgPSAzNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcyID0gMzcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNzNfRklFTERfTlVNQkVSID0gMzczOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzMgPSAzNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzMgPSAzNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzczID0gMzczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzczXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNzRfRklFTERfTlVNQkVSID0gMzc0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzQgPSAzNzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzQgPSAzNzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc0ID0gMzc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNzVfRklFTERfTlVNQkVSID0gMzc1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzUgPSAzNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzUgPSAzNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc1ID0gMzc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNzZfRklFTERfTlVNQkVSID0gMzc2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzYgPSAzNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzYgPSAzNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc2ID0gMzc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNzdfRklFTERfTlVNQkVSID0gMzc3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzcgPSAzNzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzcgPSAzNzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc3ID0gMzc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNzhfRklFTERfTlVNQkVSID0gMzc4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzggPSAzNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzggPSAzNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc4ID0gMzc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zNzlfRklFTERfTlVNQkVSID0gMzc5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzkgPSAzNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzkgPSAzNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc5ID0gMzc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zODBfRklFTERfTlVNQkVSID0gMzgwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODAgPSAzODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODAgPSAzODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgwID0gMzgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zODFfRklFTERfTlVNQkVSID0gMzgxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODEgPSAzODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODEgPSAzODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgxID0gMzgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zODJfRklFTERfTlVNQkVSID0gMzgyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODIgPSAzODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODIgPSAzODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgyID0gMzgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zODNfRklFTERfTlVNQkVSID0gMzgzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODMgPSAzODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODMgPSAzODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgzID0gMzgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zODRfRklFTERfTlVNQkVSID0gMzg0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODQgPSAzODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODQgPSAzODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg0ID0gMzg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zODVfRklFTERfTlVNQkVSID0gMzg1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODUgPSAzODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODUgPSAzODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg1ID0gMzg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zODZfRklFTERfTlVNQkVSID0gMzg2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODYgPSAzODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODYgPSAzODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg2ID0gMzg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zODdfRklFTERfTlVNQkVSID0gMzg3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODcgPSAzODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODcgPSAzODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg3ID0gMzg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zODhfRklFTERfTlVNQkVSID0gMzg4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODggPSAzODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODggPSAzODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg4ID0gMzg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zODlfRklFTERfTlVNQkVSID0gMzg5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODkgPSAzODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODkgPSAzODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg5ID0gMzg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zOTBfRklFTERfTlVNQkVSID0gMzkwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTAgPSAzOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTAgPSAzOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkwID0gMzkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zOTFfRklFTERfTlVNQkVSID0gMzkxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTEgPSAzOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTEgPSAzOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkxID0gMzkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zOTJfRklFTERfTlVNQkVSID0gMzkyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTIgPSAzOTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTIgPSAzOTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkyID0gMzkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zOTNfRklFTERfTlVNQkVSID0gMzkzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTMgPSAzOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTMgPSAzOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkzID0gMzkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zOTRfRklFTERfTlVNQkVSID0gMzk0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTQgPSAzOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTQgPSAzOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk0ID0gMzk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zOTVfRklFTERfTlVNQkVSID0gMzk1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTUgPSAzOTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTUgPSAzOTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk1ID0gMzk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zOTZfRklFTERfTlVNQkVSID0gMzk2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTYgPSAzOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTYgPSAzOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk2ID0gMzk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zOTdfRklFTERfTlVNQkVSID0gMzk3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTcgPSAzOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTcgPSAzOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk3ID0gMzk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zOThfRklFTERfTlVNQkVSID0gMzk4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTggPSAzOTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTggPSAzOTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk4ID0gMzk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18zOTlfRklFTERfTlVNQkVSID0gMzk5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTkgPSAzOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTkgPSAzOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk5ID0gMzk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MDBfRklFTERfTlVNQkVSID0gNDAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDAgPSA0MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDAgPSA0MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAwID0gNDAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MDFfRklFTERfTlVNQkVSID0gNDAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDEgPSA0MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDEgPSA0MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAxID0gNDAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MDJfRklFTERfTlVNQkVSID0gNDAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDIgPSA0MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDIgPSA0MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAyID0gNDAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MDNfRklFTERfTlVNQkVSID0gNDAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDMgPSA0MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDMgPSA0MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAzID0gNDAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MDRfRklFTERfTlVNQkVSID0gNDA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDQgPSA0MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDQgPSA0MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA0ID0gNDA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MDVfRklFTERfTlVNQkVSID0gNDA1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDUgPSA0MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDUgPSA0MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA1ID0gNDA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MDZfRklFTERfTlVNQkVSID0gNDA2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDYgPSA0MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDYgPSA0MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA2ID0gNDA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MDdfRklFTERfTlVNQkVSID0gNDA3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDcgPSA0MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDcgPSA0MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA3ID0gNDA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MDhfRklFTERfTlVNQkVSID0gNDA4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDggPSA0MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDggPSA0MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA4ID0gNDA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MDlfRklFTERfTlVNQkVSID0gNDA5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDkgPSA0MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDkgPSA0MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA5ID0gNDA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MTBfRklFTERfTlVNQkVSID0gNDEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTAgPSA0MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTAgPSA0MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEwID0gNDEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MTFfRklFTERfTlVNQkVSID0gNDExOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTEgPSA0MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTEgPSA0MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDExID0gNDExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDExXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MTJfRklFTERfTlVNQkVSID0gNDEyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTIgPSA0MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTIgPSA0MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEyID0gNDEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MTNfRklFTERfTlVNQkVSID0gNDEzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTMgPSA0MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTMgPSA0MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEzID0gNDEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MTRfRklFTERfTlVNQkVSID0gNDE0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTQgPSA0MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTQgPSA0MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE0ID0gNDE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MTVfRklFTERfTlVNQkVSID0gNDE1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTUgPSA0MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTUgPSA0MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE1ID0gNDE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MTZfRklFTERfTlVNQkVSID0gNDE2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTYgPSA0MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTYgPSA0MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE2ID0gNDE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MTdfRklFTERfTlVNQkVSID0gNDE3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTcgPSA0MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTcgPSA0MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE3ID0gNDE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MThfRklFTERfTlVNQkVSID0gNDE4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTggPSA0MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTggPSA0MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE4ID0gNDE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MTlfRklFTERfTlVNQkVSID0gNDE5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTkgPSA0MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTkgPSA0MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE5ID0gNDE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MjBfRklFTERfTlVNQkVSID0gNDIwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjAgPSA0MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjAgPSA0MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIwID0gNDIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MjFfRklFTERfTlVNQkVSID0gNDIxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjEgPSA0MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjEgPSA0MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIxID0gNDIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MjJfRklFTERfTlVNQkVSID0gNDIyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjIgPSA0MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjIgPSA0MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIyID0gNDIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MjNfRklFTERfTlVNQkVSID0gNDIzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjMgPSA0MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjMgPSA0MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIzID0gNDIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MjRfRklFTERfTlVNQkVSID0gNDI0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjQgPSA0MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjQgPSA0MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI0ID0gNDI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MjVfRklFTERfTlVNQkVSID0gNDI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjUgPSA0MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjUgPSA0MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI1ID0gNDI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MjZfRklFTERfTlVNQkVSID0gNDI2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjYgPSA0MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjYgPSA0MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI2ID0gNDI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MjdfRklFTERfTlVNQkVSID0gNDI3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjcgPSA0MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjcgPSA0MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI3ID0gNDI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MjhfRklFTERfTlVNQkVSID0gNDI4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjggPSA0MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjggPSA0MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI4ID0gNDI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MjlfRklFTERfTlVNQkVSID0gNDI5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjkgPSA0MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjkgPSA0MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI5ID0gNDI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MzBfRklFTERfTlVNQkVSID0gNDMwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzAgPSA0MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzAgPSA0MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMwID0gNDMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MzFfRklFTERfTlVNQkVSID0gNDMxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzEgPSA0MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzEgPSA0MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMxID0gNDMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MzJfRklFTERfTlVNQkVSID0gNDMyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzIgPSA0MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzIgPSA0MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMyID0gNDMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MzNfRklFTERfTlVNQkVSID0gNDMzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzMgPSA0MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzMgPSA0MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMzID0gNDMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MzRfRklFTERfTlVNQkVSID0gNDM0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzQgPSA0MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzQgPSA0MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM0ID0gNDM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MzVfRklFTERfTlVNQkVSID0gNDM1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzUgPSA0MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzUgPSA0MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM1ID0gNDM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MzZfRklFTERfTlVNQkVSID0gNDM2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzYgPSA0MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzYgPSA0MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM2ID0gNDM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MzdfRklFTERfTlVNQkVSID0gNDM3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzcgPSA0MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzcgPSA0MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM3ID0gNDM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MzhfRklFTERfTlVNQkVSID0gNDM4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzggPSA0MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzggPSA0MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM4ID0gNDM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180MzlfRklFTERfTlVNQkVSID0gNDM5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzkgPSA0MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzkgPSA0MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM5ID0gNDM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NDBfRklFTERfTlVNQkVSID0gNDQwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDAgPSA0NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDAgPSA0NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQwID0gNDQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NDFfRklFTERfTlVNQkVSID0gNDQxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDEgPSA0NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDEgPSA0NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQxID0gNDQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NDJfRklFTERfTlVNQkVSID0gNDQyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDIgPSA0NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDIgPSA0NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQyID0gNDQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NDNfRklFTERfTlVNQkVSID0gNDQzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDMgPSA0NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDMgPSA0NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQzID0gNDQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NDRfRklFTERfTlVNQkVSID0gNDQ0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDQgPSA0NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDQgPSA0NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ0ID0gNDQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NDVfRklFTERfTlVNQkVSID0gNDQ1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDUgPSA0NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDUgPSA0NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ1ID0gNDQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NDZfRklFTERfTlVNQkVSID0gNDQ2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDYgPSA0NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDYgPSA0NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ2ID0gNDQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NDdfRklFTERfTlVNQkVSID0gNDQ3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDcgPSA0NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDcgPSA0NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ3ID0gNDQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NDhfRklFTERfTlVNQkVSID0gNDQ4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDggPSA0NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDggPSA0NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ4ID0gNDQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NDlfRklFTERfTlVNQkVSID0gNDQ5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDkgPSA0NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDkgPSA0NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ5ID0gNDQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NTBfRklFTERfTlVNQkVSID0gNDUwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTAgPSA0NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTAgPSA0NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUwID0gNDUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NTFfRklFTERfTlVNQkVSID0gNDUxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTEgPSA0NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTEgPSA0NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUxID0gNDUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NTJfRklFTERfTlVNQkVSID0gNDUyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTIgPSA0NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTIgPSA0NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUyID0gNDUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NTNfRklFTERfTlVNQkVSID0gNDUzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTMgPSA0NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTMgPSA0NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUzID0gNDUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NTRfRklFTERfTlVNQkVSID0gNDU0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTQgPSA0NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTQgPSA0NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU0ID0gNDU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NTVfRklFTERfTlVNQkVSID0gNDU1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTUgPSA0NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTUgPSA0NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU1ID0gNDU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NTZfRklFTERfTlVNQkVSID0gNDU2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTYgPSA0NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTYgPSA0NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU2ID0gNDU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NTdfRklFTERfTlVNQkVSID0gNDU3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTcgPSA0NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTcgPSA0NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU3ID0gNDU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NThfRklFTERfTlVNQkVSID0gNDU4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTggPSA0NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTggPSA0NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU4ID0gNDU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NTlfRklFTERfTlVNQkVSID0gNDU5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTkgPSA0NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTkgPSA0NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU5ID0gNDU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NjBfRklFTERfTlVNQkVSID0gNDYwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjAgPSA0NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjAgPSA0NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYwID0gNDYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NjFfRklFTERfTlVNQkVSID0gNDYxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjEgPSA0NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjEgPSA0NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYxID0gNDYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NjJfRklFTERfTlVNQkVSID0gNDYyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjIgPSA0NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjIgPSA0NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYyID0gNDYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NjNfRklFTERfTlVNQkVSID0gNDYzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjMgPSA0NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjMgPSA0NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYzID0gNDYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NjRfRklFTERfTlVNQkVSID0gNDY0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjQgPSA0NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjQgPSA0NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY0ID0gNDY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NjVfRklFTERfTlVNQkVSID0gNDY1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjUgPSA0NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjUgPSA0NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY1ID0gNDY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NjZfRklFTERfTlVNQkVSID0gNDY2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjYgPSA0NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjYgPSA0NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY2ID0gNDY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NjdfRklFTERfTlVNQkVSID0gNDY3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjcgPSA0NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjcgPSA0NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY3ID0gNDY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NjhfRklFTERfTlVNQkVSID0gNDY4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjggPSA0NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjggPSA0NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY4ID0gNDY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NjlfRklFTERfTlVNQkVSID0gNDY5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjkgPSA0NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjkgPSA0NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY5ID0gNDY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NzBfRklFTERfTlVNQkVSID0gNDcwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzAgPSA0NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzAgPSA0NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcwID0gNDcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NzFfRklFTERfTlVNQkVSID0gNDcxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzEgPSA0NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzEgPSA0NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcxID0gNDcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NzJfRklFTERfTlVNQkVSID0gNDcyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzIgPSA0NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzIgPSA0NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcyID0gNDcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NzNfRklFTERfTlVNQkVSID0gNDczOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzMgPSA0NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzMgPSA0NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDczID0gNDczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDczXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NzRfRklFTERfTlVNQkVSID0gNDc0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzQgPSA0NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzQgPSA0NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc0ID0gNDc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NzVfRklFTERfTlVNQkVSID0gNDc1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzUgPSA0NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzUgPSA0NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc1ID0gNDc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NzZfRklFTERfTlVNQkVSID0gNDc2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzYgPSA0NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzYgPSA0NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc2ID0gNDc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NzdfRklFTERfTlVNQkVSID0gNDc3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzcgPSA0NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzcgPSA0NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc3ID0gNDc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NzhfRklFTERfTlVNQkVSID0gNDc4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzggPSA0NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzggPSA0NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc4ID0gNDc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180NzlfRklFTERfTlVNQkVSID0gNDc5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzkgPSA0NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzkgPSA0NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc5ID0gNDc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180ODBfRklFTERfTlVNQkVSID0gNDgwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODAgPSA0ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODAgPSA0ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgwID0gNDgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180ODFfRklFTERfTlVNQkVSID0gNDgxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODEgPSA0ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODEgPSA0ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgxID0gNDgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180ODJfRklFTERfTlVNQkVSID0gNDgyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODIgPSA0ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODIgPSA0ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgyID0gNDgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180ODNfRklFTERfTlVNQkVSID0gNDgzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODMgPSA0ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODMgPSA0ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgzID0gNDgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180ODRfRklFTERfTlVNQkVSID0gNDg0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODQgPSA0ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODQgPSA0ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg0ID0gNDg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180ODVfRklFTERfTlVNQkVSID0gNDg1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODUgPSA0ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODUgPSA0ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg1ID0gNDg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180ODZfRklFTERfTlVNQkVSID0gNDg2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODYgPSA0ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODYgPSA0ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg2ID0gNDg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180ODdfRklFTERfTlVNQkVSID0gNDg3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODcgPSA0ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODcgPSA0ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg3ID0gNDg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180ODhfRklFTERfTlVNQkVSID0gNDg4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODggPSA0ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODggPSA0ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg4ID0gNDg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180ODlfRklFTERfTlVNQkVSID0gNDg5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODkgPSA0ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODkgPSA0ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg5ID0gNDg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180OTBfRklFTERfTlVNQkVSID0gNDkwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTAgPSA0OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTAgPSA0OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkwID0gNDkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180OTFfRklFTERfTlVNQkVSID0gNDkxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTEgPSA0OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTEgPSA0OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkxID0gNDkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180OTJfRklFTERfTlVNQkVSID0gNDkyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTIgPSA0OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTIgPSA0OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkyID0gNDkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180OTNfRklFTERfTlVNQkVSID0gNDkzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTMgPSA0OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTMgPSA0OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkzID0gNDkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180OTRfRklFTERfTlVNQkVSID0gNDk0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTQgPSA0OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTQgPSA0OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk0ID0gNDk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180OTVfRklFTERfTlVNQkVSID0gNDk1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTUgPSA0OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTUgPSA0OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk1ID0gNDk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180OTZfRklFTERfTlVNQkVSID0gNDk2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTYgPSA0OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTYgPSA0OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk2ID0gNDk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180OTdfRklFTERfTlVNQkVSID0gNDk3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTcgPSA0OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTcgPSA0OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk3ID0gNDk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180OThfRklFTERfTlVNQkVSID0gNDk4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTggPSA0OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTggPSA0OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk4ID0gNDk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR180OTlfRklFTERfTlVNQkVSID0gNDk5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTkgPSA0OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTkgPSA0OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk5ID0gNDk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MDBfRklFTERfTlVNQkVSID0gNTAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDAgPSA1MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDAgPSA1MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAwID0gNTAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MDFfRklFTERfTlVNQkVSID0gNTAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDEgPSA1MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDEgPSA1MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAxID0gNTAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MDJfRklFTERfTlVNQkVSID0gNTAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDIgPSA1MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDIgPSA1MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAyID0gNTAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MDNfRklFTERfTlVNQkVSID0gNTAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDMgPSA1MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDMgPSA1MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAzID0gNTAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MDRfRklFTERfTlVNQkVSID0gNTA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDQgPSA1MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDQgPSA1MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA0ID0gNTA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MDVfRklFTERfTlVNQkVSID0gNTA1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDUgPSA1MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDUgPSA1MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA1ID0gNTA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MDZfRklFTERfTlVNQkVSID0gNTA2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDYgPSA1MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDYgPSA1MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA2ID0gNTA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MDdfRklFTERfTlVNQkVSID0gNTA3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDcgPSA1MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDcgPSA1MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA3ID0gNTA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MDhfRklFTERfTlVNQkVSID0gNTA4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDggPSA1MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDggPSA1MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA4ID0gNTA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MDlfRklFTERfTlVNQkVSID0gNTA5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDkgPSA1MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDkgPSA1MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA5ID0gNTA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MTBfRklFTERfTlVNQkVSID0gNTEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTAgPSA1MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTAgPSA1MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEwID0gNTEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MTFfRklFTERfTlVNQkVSID0gNTExOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTEgPSA1MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTEgPSA1MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTExID0gNTExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTExXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MTJfRklFTERfTlVNQkVSID0gNTEyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTIgPSA1MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTIgPSA1MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEyID0gNTEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MTNfRklFTERfTlVNQkVSID0gNTEzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTMgPSA1MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTMgPSA1MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEzID0gNTEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MTRfRklFTERfTlVNQkVSID0gNTE0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTQgPSA1MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTQgPSA1MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE0ID0gNTE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MTVfRklFTERfTlVNQkVSID0gNTE1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTUgPSA1MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTUgPSA1MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE1ID0gNTE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MTZfRklFTERfTlVNQkVSID0gNTE2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTYgPSA1MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTYgPSA1MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE2ID0gNTE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MTdfRklFTERfTlVNQkVSID0gNTE3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTcgPSA1MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTcgPSA1MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE3ID0gNTE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MThfRklFTERfTlVNQkVSID0gNTE4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTggPSA1MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTggPSA1MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE4ID0gNTE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MTlfRklFTERfTlVNQkVSID0gNTE5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTkgPSA1MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTkgPSA1MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE5ID0gNTE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MjBfRklFTERfTlVNQkVSID0gNTIwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjAgPSA1MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjAgPSA1MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIwID0gNTIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MjFfRklFTERfTlVNQkVSID0gNTIxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjEgPSA1MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjEgPSA1MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIxID0gNTIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MjJfRklFTERfTlVNQkVSID0gNTIyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjIgPSA1MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjIgPSA1MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIyID0gNTIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MjNfRklFTERfTlVNQkVSID0gNTIzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjMgPSA1MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjMgPSA1MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIzID0gNTIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MjRfRklFTERfTlVNQkVSID0gNTI0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjQgPSA1MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjQgPSA1MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI0ID0gNTI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MjVfRklFTERfTlVNQkVSID0gNTI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjUgPSA1MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjUgPSA1MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI1ID0gNTI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MjZfRklFTERfTlVNQkVSID0gNTI2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjYgPSA1MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjYgPSA1MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI2ID0gNTI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MjdfRklFTERfTlVNQkVSID0gNTI3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjcgPSA1MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjcgPSA1MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI3ID0gNTI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MjhfRklFTERfTlVNQkVSID0gNTI4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjggPSA1MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjggPSA1MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI4ID0gNTI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MjlfRklFTERfTlVNQkVSID0gNTI5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjkgPSA1MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjkgPSA1MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI5ID0gNTI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MzBfRklFTERfTlVNQkVSID0gNTMwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzAgPSA1MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzAgPSA1MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMwID0gNTMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MzFfRklFTERfTlVNQkVSID0gNTMxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzEgPSA1MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzEgPSA1MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMxID0gNTMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MzJfRklFTERfTlVNQkVSID0gNTMyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzIgPSA1MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzIgPSA1MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMyID0gNTMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MzNfRklFTERfTlVNQkVSID0gNTMzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzMgPSA1MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzMgPSA1MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMzID0gNTMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MzRfRklFTERfTlVNQkVSID0gNTM0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzQgPSA1MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzQgPSA1MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM0ID0gNTM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MzVfRklFTERfTlVNQkVSID0gNTM1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzUgPSA1MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzUgPSA1MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM1ID0gNTM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MzZfRklFTERfTlVNQkVSID0gNTM2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzYgPSA1MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzYgPSA1MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM2ID0gNTM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MzdfRklFTERfTlVNQkVSID0gNTM3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzcgPSA1MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzcgPSA1MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM3ID0gNTM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MzhfRklFTERfTlVNQkVSID0gNTM4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzggPSA1MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzggPSA1MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM4ID0gNTM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181MzlfRklFTERfTlVNQkVSID0gNTM5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzkgPSA1MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzkgPSA1MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM5ID0gNTM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NDBfRklFTERfTlVNQkVSID0gNTQwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDAgPSA1NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDAgPSA1NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQwID0gNTQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NDFfRklFTERfTlVNQkVSID0gNTQxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDEgPSA1NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDEgPSA1NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQxID0gNTQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NDJfRklFTERfTlVNQkVSID0gNTQyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDIgPSA1NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDIgPSA1NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQyID0gNTQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NDNfRklFTERfTlVNQkVSID0gNTQzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDMgPSA1NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDMgPSA1NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQzID0gNTQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NDRfRklFTERfTlVNQkVSID0gNTQ0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDQgPSA1NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDQgPSA1NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ0ID0gNTQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NDVfRklFTERfTlVNQkVSID0gNTQ1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDUgPSA1NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDUgPSA1NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ1ID0gNTQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NDZfRklFTERfTlVNQkVSID0gNTQ2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDYgPSA1NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDYgPSA1NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ2ID0gNTQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NDdfRklFTERfTlVNQkVSID0gNTQ3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDcgPSA1NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDcgPSA1NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ3ID0gNTQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NDhfRklFTERfTlVNQkVSID0gNTQ4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDggPSA1NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDggPSA1NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ4ID0gNTQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NDlfRklFTERfTlVNQkVSID0gNTQ5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDkgPSA1NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDkgPSA1NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ5ID0gNTQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NTBfRklFTERfTlVNQkVSID0gNTUwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTAgPSA1NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTAgPSA1NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUwID0gNTUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NTFfRklFTERfTlVNQkVSID0gNTUxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTEgPSA1NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTEgPSA1NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUxID0gNTUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NTJfRklFTERfTlVNQkVSID0gNTUyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTIgPSA1NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTIgPSA1NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUyID0gNTUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NTNfRklFTERfTlVNQkVSID0gNTUzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTMgPSA1NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTMgPSA1NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUzID0gNTUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NTRfRklFTERfTlVNQkVSID0gNTU0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTQgPSA1NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTQgPSA1NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU0ID0gNTU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NTVfRklFTERfTlVNQkVSID0gNTU1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTUgPSA1NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTUgPSA1NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU1ID0gNTU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NTZfRklFTERfTlVNQkVSID0gNTU2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTYgPSA1NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTYgPSA1NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU2ID0gNTU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NTdfRklFTERfTlVNQkVSID0gNTU3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTcgPSA1NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTcgPSA1NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU3ID0gNTU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NThfRklFTERfTlVNQkVSID0gNTU4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTggPSA1NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTggPSA1NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU4ID0gNTU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NTlfRklFTERfTlVNQkVSID0gNTU5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTkgPSA1NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTkgPSA1NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU5ID0gNTU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NjBfRklFTERfTlVNQkVSID0gNTYwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjAgPSA1NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjAgPSA1NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYwID0gNTYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NjFfRklFTERfTlVNQkVSID0gNTYxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjEgPSA1NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjEgPSA1NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYxID0gNTYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NjJfRklFTERfTlVNQkVSID0gNTYyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjIgPSA1NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjIgPSA1NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYyID0gNTYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NjNfRklFTERfTlVNQkVSID0gNTYzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjMgPSA1NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjMgPSA1NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYzID0gNTYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NjRfRklFTERfTlVNQkVSID0gNTY0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjQgPSA1NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjQgPSA1NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY0ID0gNTY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NjVfRklFTERfTlVNQkVSID0gNTY1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjUgPSA1NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjUgPSA1NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY1ID0gNTY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NjZfRklFTERfTlVNQkVSID0gNTY2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjYgPSA1NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjYgPSA1NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY2ID0gNTY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NjdfRklFTERfTlVNQkVSID0gNTY3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjcgPSA1NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjcgPSA1NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY3ID0gNTY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NjhfRklFTERfTlVNQkVSID0gNTY4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjggPSA1NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjggPSA1NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY4ID0gNTY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NjlfRklFTERfTlVNQkVSID0gNTY5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjkgPSA1NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjkgPSA1NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY5ID0gNTY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NzBfRklFTERfTlVNQkVSID0gNTcwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzAgPSA1NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzAgPSA1NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcwID0gNTcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NzFfRklFTERfTlVNQkVSID0gNTcxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzEgPSA1NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzEgPSA1NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcxID0gNTcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NzJfRklFTERfTlVNQkVSID0gNTcyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzIgPSA1NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzIgPSA1NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcyID0gNTcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NzNfRklFTERfTlVNQkVSID0gNTczOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzMgPSA1NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzMgPSA1NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTczID0gNTczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTczXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NzRfRklFTERfTlVNQkVSID0gNTc0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzQgPSA1NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzQgPSA1NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc0ID0gNTc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NzVfRklFTERfTlVNQkVSID0gNTc1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzUgPSA1NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzUgPSA1NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc1ID0gNTc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NzZfRklFTERfTlVNQkVSID0gNTc2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzYgPSA1NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzYgPSA1NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc2ID0gNTc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NzdfRklFTERfTlVNQkVSID0gNTc3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzcgPSA1NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzcgPSA1NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc3ID0gNTc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NzhfRklFTERfTlVNQkVSID0gNTc4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzggPSA1NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzggPSA1NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc4ID0gNTc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181NzlfRklFTERfTlVNQkVSID0gNTc5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzkgPSA1NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzkgPSA1NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc5ID0gNTc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181ODBfRklFTERfTlVNQkVSID0gNTgwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODAgPSA1ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODAgPSA1ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgwID0gNTgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181ODFfRklFTERfTlVNQkVSID0gNTgxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODEgPSA1ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODEgPSA1ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgxID0gNTgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181ODJfRklFTERfTlVNQkVSID0gNTgyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODIgPSA1ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODIgPSA1ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgyID0gNTgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181ODNfRklFTERfTlVNQkVSID0gNTgzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODMgPSA1ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODMgPSA1ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgzID0gNTgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181ODRfRklFTERfTlVNQkVSID0gNTg0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODQgPSA1ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODQgPSA1ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg0ID0gNTg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181ODVfRklFTERfTlVNQkVSID0gNTg1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODUgPSA1ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODUgPSA1ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg1ID0gNTg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181ODZfRklFTERfTlVNQkVSID0gNTg2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODYgPSA1ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODYgPSA1ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg2ID0gNTg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181ODdfRklFTERfTlVNQkVSID0gNTg3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODcgPSA1ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODcgPSA1ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg3ID0gNTg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181ODhfRklFTERfTlVNQkVSID0gNTg4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODggPSA1ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODggPSA1ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg4ID0gNTg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181ODlfRklFTERfTlVNQkVSID0gNTg5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODkgPSA1ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODkgPSA1ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg5ID0gNTg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181OTBfRklFTERfTlVNQkVSID0gNTkwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTAgPSA1OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTAgPSA1OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkwID0gNTkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181OTFfRklFTERfTlVNQkVSID0gNTkxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTEgPSA1OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTEgPSA1OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkxID0gNTkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181OTJfRklFTERfTlVNQkVSID0gNTkyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTIgPSA1OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTIgPSA1OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkyID0gNTkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181OTNfRklFTERfTlVNQkVSID0gNTkzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTMgPSA1OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTMgPSA1OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkzID0gNTkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181OTRfRklFTERfTlVNQkVSID0gNTk0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTQgPSA1OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTQgPSA1OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk0ID0gNTk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181OTVfRklFTERfTlVNQkVSID0gNTk1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTUgPSA1OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTUgPSA1OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk1ID0gNTk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181OTZfRklFTERfTlVNQkVSID0gNTk2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTYgPSA1OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTYgPSA1OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk2ID0gNTk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181OTdfRklFTERfTlVNQkVSID0gNTk3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTcgPSA1OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTcgPSA1OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk3ID0gNTk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181OThfRklFTERfTlVNQkVSID0gNTk4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTggPSA1OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTggPSA1OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk4ID0gNTk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR181OTlfRklFTERfTlVNQkVSID0gNTk5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTkgPSA1OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTkgPSA1OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk5ID0gNTk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MDBfRklFTERfTlVNQkVSID0gNjAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDAgPSA2MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDAgPSA2MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAwID0gNjAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MDFfRklFTERfTlVNQkVSID0gNjAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDEgPSA2MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDEgPSA2MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAxID0gNjAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MDJfRklFTERfTlVNQkVSID0gNjAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDIgPSA2MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDIgPSA2MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAyID0gNjAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MDNfRklFTERfTlVNQkVSID0gNjAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDMgPSA2MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDMgPSA2MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAzID0gNjAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MDRfRklFTERfTlVNQkVSID0gNjA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDQgPSA2MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDQgPSA2MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA0ID0gNjA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MDVfRklFTERfTlVNQkVSID0gNjA1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDUgPSA2MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDUgPSA2MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA1ID0gNjA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MDZfRklFTERfTlVNQkVSID0gNjA2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDYgPSA2MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDYgPSA2MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA2ID0gNjA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MDdfRklFTERfTlVNQkVSID0gNjA3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDcgPSA2MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDcgPSA2MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA3ID0gNjA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MDhfRklFTERfTlVNQkVSID0gNjA4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDggPSA2MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDggPSA2MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA4ID0gNjA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MDlfRklFTERfTlVNQkVSID0gNjA5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDkgPSA2MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDkgPSA2MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA5ID0gNjA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MTBfRklFTERfTlVNQkVSID0gNjEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTAgPSA2MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTAgPSA2MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEwID0gNjEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MTFfRklFTERfTlVNQkVSID0gNjExOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTEgPSA2MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTEgPSA2MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjExID0gNjExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjExXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MTJfRklFTERfTlVNQkVSID0gNjEyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTIgPSA2MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTIgPSA2MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEyID0gNjEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MTNfRklFTERfTlVNQkVSID0gNjEzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTMgPSA2MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTMgPSA2MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEzID0gNjEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MTRfRklFTERfTlVNQkVSID0gNjE0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTQgPSA2MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTQgPSA2MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE0ID0gNjE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MTVfRklFTERfTlVNQkVSID0gNjE1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTUgPSA2MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTUgPSA2MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE1ID0gNjE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MTZfRklFTERfTlVNQkVSID0gNjE2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTYgPSA2MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTYgPSA2MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE2ID0gNjE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MTdfRklFTERfTlVNQkVSID0gNjE3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTcgPSA2MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTcgPSA2MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE3ID0gNjE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MThfRklFTERfTlVNQkVSID0gNjE4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTggPSA2MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTggPSA2MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE4ID0gNjE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MTlfRklFTERfTlVNQkVSID0gNjE5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTkgPSA2MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTkgPSA2MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE5ID0gNjE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MjBfRklFTERfTlVNQkVSID0gNjIwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjAgPSA2MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjAgPSA2MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIwID0gNjIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MjFfRklFTERfTlVNQkVSID0gNjIxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjEgPSA2MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjEgPSA2MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIxID0gNjIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MjJfRklFTERfTlVNQkVSID0gNjIyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjIgPSA2MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjIgPSA2MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIyID0gNjIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MjNfRklFTERfTlVNQkVSID0gNjIzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjMgPSA2MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjMgPSA2MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIzID0gNjIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MjRfRklFTERfTlVNQkVSID0gNjI0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjQgPSA2MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjQgPSA2MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI0ID0gNjI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MjVfRklFTERfTlVNQkVSID0gNjI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjUgPSA2MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjUgPSA2MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI1ID0gNjI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MjZfRklFTERfTlVNQkVSID0gNjI2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjYgPSA2MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjYgPSA2MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI2ID0gNjI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MjdfRklFTERfTlVNQkVSID0gNjI3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjcgPSA2MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjcgPSA2MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI3ID0gNjI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MjhfRklFTERfTlVNQkVSID0gNjI4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjggPSA2MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjggPSA2MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI4ID0gNjI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MjlfRklFTERfTlVNQkVSID0gNjI5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjkgPSA2MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjkgPSA2MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI5ID0gNjI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MzBfRklFTERfTlVNQkVSID0gNjMwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzAgPSA2MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzAgPSA2MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMwID0gNjMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MzFfRklFTERfTlVNQkVSID0gNjMxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzEgPSA2MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzEgPSA2MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMxID0gNjMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MzJfRklFTERfTlVNQkVSID0gNjMyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzIgPSA2MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzIgPSA2MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMyID0gNjMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MzNfRklFTERfTlVNQkVSID0gNjMzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzMgPSA2MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzMgPSA2MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMzID0gNjMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MzRfRklFTERfTlVNQkVSID0gNjM0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzQgPSA2MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzQgPSA2MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM0ID0gNjM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MzVfRklFTERfTlVNQkVSID0gNjM1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzUgPSA2MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzUgPSA2MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM1ID0gNjM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MzZfRklFTERfTlVNQkVSID0gNjM2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzYgPSA2MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzYgPSA2MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM2ID0gNjM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MzdfRklFTERfTlVNQkVSID0gNjM3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzcgPSA2MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzcgPSA2MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM3ID0gNjM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MzhfRklFTERfTlVNQkVSID0gNjM4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzggPSA2MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzggPSA2MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM4ID0gNjM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182MzlfRklFTERfTlVNQkVSID0gNjM5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzkgPSA2MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzkgPSA2MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM5ID0gNjM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NDBfRklFTERfTlVNQkVSID0gNjQwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDAgPSA2NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDAgPSA2NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQwID0gNjQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NDFfRklFTERfTlVNQkVSID0gNjQxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDEgPSA2NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDEgPSA2NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQxID0gNjQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NDJfRklFTERfTlVNQkVSID0gNjQyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDIgPSA2NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDIgPSA2NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQyID0gNjQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NDNfRklFTERfTlVNQkVSID0gNjQzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDMgPSA2NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDMgPSA2NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQzID0gNjQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NDRfRklFTERfTlVNQkVSID0gNjQ0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDQgPSA2NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDQgPSA2NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ0ID0gNjQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NDVfRklFTERfTlVNQkVSID0gNjQ1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDUgPSA2NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDUgPSA2NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ1ID0gNjQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NDZfRklFTERfTlVNQkVSID0gNjQ2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDYgPSA2NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDYgPSA2NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ2ID0gNjQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NDdfRklFTERfTlVNQkVSID0gNjQ3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDcgPSA2NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDcgPSA2NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ3ID0gNjQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NDhfRklFTERfTlVNQkVSID0gNjQ4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDggPSA2NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDggPSA2NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ4ID0gNjQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NDlfRklFTERfTlVNQkVSID0gNjQ5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDkgPSA2NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDkgPSA2NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ5ID0gNjQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NTBfRklFTERfTlVNQkVSID0gNjUwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTAgPSA2NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTAgPSA2NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUwID0gNjUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NTFfRklFTERfTlVNQkVSID0gNjUxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTEgPSA2NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTEgPSA2NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUxID0gNjUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NTJfRklFTERfTlVNQkVSID0gNjUyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTIgPSA2NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTIgPSA2NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUyID0gNjUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NTNfRklFTERfTlVNQkVSID0gNjUzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTMgPSA2NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTMgPSA2NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUzID0gNjUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NTRfRklFTERfTlVNQkVSID0gNjU0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTQgPSA2NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTQgPSA2NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU0ID0gNjU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NTVfRklFTERfTlVNQkVSID0gNjU1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTUgPSA2NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTUgPSA2NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU1ID0gNjU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NTZfRklFTERfTlVNQkVSID0gNjU2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTYgPSA2NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTYgPSA2NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU2ID0gNjU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NTdfRklFTERfTlVNQkVSID0gNjU3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTcgPSA2NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTcgPSA2NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU3ID0gNjU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NThfRklFTERfTlVNQkVSID0gNjU4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTggPSA2NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTggPSA2NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU4ID0gNjU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NTlfRklFTERfTlVNQkVSID0gNjU5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTkgPSA2NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTkgPSA2NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU5ID0gNjU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NjBfRklFTERfTlVNQkVSID0gNjYwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjAgPSA2NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjAgPSA2NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYwID0gNjYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NjFfRklFTERfTlVNQkVSID0gNjYxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjEgPSA2NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjEgPSA2NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYxID0gNjYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NjJfRklFTERfTlVNQkVSID0gNjYyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjIgPSA2NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjIgPSA2NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYyID0gNjYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NjNfRklFTERfTlVNQkVSID0gNjYzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjMgPSA2NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjMgPSA2NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYzID0gNjYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NjRfRklFTERfTlVNQkVSID0gNjY0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjQgPSA2NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjQgPSA2NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY0ID0gNjY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NjVfRklFTERfTlVNQkVSID0gNjY1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjUgPSA2NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjUgPSA2NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY1ID0gNjY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NjZfRklFTERfTlVNQkVSID0gNjY2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjYgPSA2NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjYgPSA2NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY2ID0gNjY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NjdfRklFTERfTlVNQkVSID0gNjY3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjcgPSA2NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjcgPSA2NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY3ID0gNjY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NjhfRklFTERfTlVNQkVSID0gNjY4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjggPSA2NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjggPSA2NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY4ID0gNjY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NjlfRklFTERfTlVNQkVSID0gNjY5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjkgPSA2NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjkgPSA2NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY5ID0gNjY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NzBfRklFTERfTlVNQkVSID0gNjcwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzAgPSA2NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzAgPSA2NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcwID0gNjcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NzFfRklFTERfTlVNQkVSID0gNjcxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzEgPSA2NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzEgPSA2NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcxID0gNjcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NzJfRklFTERfTlVNQkVSID0gNjcyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzIgPSA2NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzIgPSA2NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcyID0gNjcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NzNfRklFTERfTlVNQkVSID0gNjczOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzMgPSA2NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzMgPSA2NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjczID0gNjczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjczXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NzRfRklFTERfTlVNQkVSID0gNjc0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzQgPSA2NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzQgPSA2NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc0ID0gNjc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NzVfRklFTERfTlVNQkVSID0gNjc1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzUgPSA2NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzUgPSA2NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc1ID0gNjc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NzZfRklFTERfTlVNQkVSID0gNjc2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzYgPSA2NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzYgPSA2NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc2ID0gNjc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NzdfRklFTERfTlVNQkVSID0gNjc3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzcgPSA2NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzcgPSA2NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc3ID0gNjc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NzhfRklFTERfTlVNQkVSID0gNjc4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzggPSA2NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzggPSA2NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc4ID0gNjc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182NzlfRklFTERfTlVNQkVSID0gNjc5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzkgPSA2NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzkgPSA2NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc5ID0gNjc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182ODBfRklFTERfTlVNQkVSID0gNjgwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODAgPSA2ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODAgPSA2ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgwID0gNjgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182ODFfRklFTERfTlVNQkVSID0gNjgxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODEgPSA2ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODEgPSA2ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgxID0gNjgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182ODJfRklFTERfTlVNQkVSID0gNjgyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODIgPSA2ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODIgPSA2ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgyID0gNjgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182ODNfRklFTERfTlVNQkVSID0gNjgzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODMgPSA2ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODMgPSA2ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgzID0gNjgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182ODRfRklFTERfTlVNQkVSID0gNjg0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODQgPSA2ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODQgPSA2ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg0ID0gNjg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182ODVfRklFTERfTlVNQkVSID0gNjg1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODUgPSA2ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODUgPSA2ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg1ID0gNjg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182ODZfRklFTERfTlVNQkVSID0gNjg2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODYgPSA2ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODYgPSA2ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg2ID0gNjg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182ODdfRklFTERfTlVNQkVSID0gNjg3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODcgPSA2ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODcgPSA2ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg3ID0gNjg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182ODhfRklFTERfTlVNQkVSID0gNjg4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODggPSA2ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODggPSA2ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg4ID0gNjg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182ODlfRklFTERfTlVNQkVSID0gNjg5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODkgPSA2ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODkgPSA2ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg5ID0gNjg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182OTBfRklFTERfTlVNQkVSID0gNjkwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTAgPSA2OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTAgPSA2OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkwID0gNjkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182OTFfRklFTERfTlVNQkVSID0gNjkxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTEgPSA2OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTEgPSA2OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkxID0gNjkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182OTJfRklFTERfTlVNQkVSID0gNjkyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTIgPSA2OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTIgPSA2OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkyID0gNjkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182OTNfRklFTERfTlVNQkVSID0gNjkzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTMgPSA2OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTMgPSA2OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkzID0gNjkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182OTRfRklFTERfTlVNQkVSID0gNjk0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTQgPSA2OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTQgPSA2OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk0ID0gNjk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182OTVfRklFTERfTlVNQkVSID0gNjk1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTUgPSA2OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTUgPSA2OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk1ID0gNjk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182OTZfRklFTERfTlVNQkVSID0gNjk2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTYgPSA2OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTYgPSA2OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk2ID0gNjk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182OTdfRklFTERfTlVNQkVSID0gNjk3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTcgPSA2OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTcgPSA2OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk3ID0gNjk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182OThfRklFTERfTlVNQkVSID0gNjk4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTggPSA2OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTggPSA2OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk4ID0gNjk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR182OTlfRklFTERfTlVNQkVSID0gNjk5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTkgPSA2OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTkgPSA2OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk5ID0gNjk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MDBfRklFTERfTlVNQkVSID0gNzAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDAgPSA3MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDAgPSA3MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAwID0gNzAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MDFfRklFTERfTlVNQkVSID0gNzAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDEgPSA3MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDEgPSA3MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAxID0gNzAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MDJfRklFTERfTlVNQkVSID0gNzAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDIgPSA3MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDIgPSA3MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAyID0gNzAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MDNfRklFTERfTlVNQkVSID0gNzAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDMgPSA3MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDMgPSA3MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAzID0gNzAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MDRfRklFTERfTlVNQkVSID0gNzA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDQgPSA3MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDQgPSA3MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA0ID0gNzA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MDVfRklFTERfTlVNQkVSID0gNzA1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDUgPSA3MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDUgPSA3MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA1ID0gNzA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MDZfRklFTERfTlVNQkVSID0gNzA2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDYgPSA3MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDYgPSA3MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA2ID0gNzA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MDdfRklFTERfTlVNQkVSID0gNzA3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDcgPSA3MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDcgPSA3MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA3ID0gNzA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MDhfRklFTERfTlVNQkVSID0gNzA4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDggPSA3MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDggPSA3MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA4ID0gNzA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MDlfRklFTERfTlVNQkVSID0gNzA5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDkgPSA3MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDkgPSA3MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA5ID0gNzA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MTBfRklFTERfTlVNQkVSID0gNzEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTAgPSA3MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTAgPSA3MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEwID0gNzEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MTFfRklFTERfTlVNQkVSID0gNzExOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTEgPSA3MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTEgPSA3MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzExID0gNzExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzExXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MTJfRklFTERfTlVNQkVSID0gNzEyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTIgPSA3MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTIgPSA3MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEyID0gNzEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MTNfRklFTERfTlVNQkVSID0gNzEzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTMgPSA3MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTMgPSA3MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEzID0gNzEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MTRfRklFTERfTlVNQkVSID0gNzE0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTQgPSA3MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTQgPSA3MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE0ID0gNzE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MTVfRklFTERfTlVNQkVSID0gNzE1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTUgPSA3MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTUgPSA3MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE1ID0gNzE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MTZfRklFTERfTlVNQkVSID0gNzE2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTYgPSA3MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTYgPSA3MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE2ID0gNzE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MTdfRklFTERfTlVNQkVSID0gNzE3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTcgPSA3MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTcgPSA3MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE3ID0gNzE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MThfRklFTERfTlVNQkVSID0gNzE4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTggPSA3MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTggPSA3MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE4ID0gNzE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MTlfRklFTERfTlVNQkVSID0gNzE5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTkgPSA3MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTkgPSA3MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE5ID0gNzE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MjBfRklFTERfTlVNQkVSID0gNzIwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjAgPSA3MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjAgPSA3MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIwID0gNzIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MjFfRklFTERfTlVNQkVSID0gNzIxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjEgPSA3MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjEgPSA3MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIxID0gNzIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MjJfRklFTERfTlVNQkVSID0gNzIyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjIgPSA3MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjIgPSA3MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIyID0gNzIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MjNfRklFTERfTlVNQkVSID0gNzIzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjMgPSA3MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjMgPSA3MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIzID0gNzIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MjRfRklFTERfTlVNQkVSID0gNzI0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjQgPSA3MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjQgPSA3MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI0ID0gNzI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MjVfRklFTERfTlVNQkVSID0gNzI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjUgPSA3MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjUgPSA3MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI1ID0gNzI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MjZfRklFTERfTlVNQkVSID0gNzI2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjYgPSA3MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjYgPSA3MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI2ID0gNzI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MjdfRklFTERfTlVNQkVSID0gNzI3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjcgPSA3MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjcgPSA3MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI3ID0gNzI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MjhfRklFTERfTlVNQkVSID0gNzI4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjggPSA3MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjggPSA3MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI4ID0gNzI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MjlfRklFTERfTlVNQkVSID0gNzI5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjkgPSA3MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjkgPSA3MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI5ID0gNzI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MzBfRklFTERfTlVNQkVSID0gNzMwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzAgPSA3MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzAgPSA3MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMwID0gNzMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MzFfRklFTERfTlVNQkVSID0gNzMxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzEgPSA3MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzEgPSA3MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMxID0gNzMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MzJfRklFTERfTlVNQkVSID0gNzMyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzIgPSA3MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzIgPSA3MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMyID0gNzMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MzNfRklFTERfTlVNQkVSID0gNzMzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzMgPSA3MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzMgPSA3MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMzID0gNzMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MzRfRklFTERfTlVNQkVSID0gNzM0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzQgPSA3MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzQgPSA3MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM0ID0gNzM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MzVfRklFTERfTlVNQkVSID0gNzM1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzUgPSA3MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzUgPSA3MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM1ID0gNzM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MzZfRklFTERfTlVNQkVSID0gNzM2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzYgPSA3MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzYgPSA3MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM2ID0gNzM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MzdfRklFTERfTlVNQkVSID0gNzM3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzcgPSA3MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzcgPSA3MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM3ID0gNzM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MzhfRklFTERfTlVNQkVSID0gNzM4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzggPSA3MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzggPSA3MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM4ID0gNzM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183MzlfRklFTERfTlVNQkVSID0gNzM5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzkgPSA3MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzkgPSA3MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM5ID0gNzM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NDBfRklFTERfTlVNQkVSID0gNzQwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDAgPSA3NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDAgPSA3NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQwID0gNzQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NDFfRklFTERfTlVNQkVSID0gNzQxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDEgPSA3NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDEgPSA3NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQxID0gNzQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NDJfRklFTERfTlVNQkVSID0gNzQyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDIgPSA3NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDIgPSA3NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQyID0gNzQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NDNfRklFTERfTlVNQkVSID0gNzQzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDMgPSA3NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDMgPSA3NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQzID0gNzQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NDRfRklFTERfTlVNQkVSID0gNzQ0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDQgPSA3NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDQgPSA3NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ0ID0gNzQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NDVfRklFTERfTlVNQkVSID0gNzQ1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDUgPSA3NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDUgPSA3NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ1ID0gNzQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NDZfRklFTERfTlVNQkVSID0gNzQ2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDYgPSA3NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDYgPSA3NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ2ID0gNzQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NDdfRklFTERfTlVNQkVSID0gNzQ3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDcgPSA3NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDcgPSA3NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ3ID0gNzQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NDhfRklFTERfTlVNQkVSID0gNzQ4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDggPSA3NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDggPSA3NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ4ID0gNzQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NDlfRklFTERfTlVNQkVSID0gNzQ5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDkgPSA3NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDkgPSA3NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ5ID0gNzQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NTBfRklFTERfTlVNQkVSID0gNzUwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTAgPSA3NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTAgPSA3NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUwID0gNzUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NTFfRklFTERfTlVNQkVSID0gNzUxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTEgPSA3NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTEgPSA3NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUxID0gNzUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NTJfRklFTERfTlVNQkVSID0gNzUyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTIgPSA3NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTIgPSA3NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUyID0gNzUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NTNfRklFTERfTlVNQkVSID0gNzUzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTMgPSA3NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTMgPSA3NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUzID0gNzUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NTRfRklFTERfTlVNQkVSID0gNzU0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTQgPSA3NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTQgPSA3NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU0ID0gNzU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NTVfRklFTERfTlVNQkVSID0gNzU1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTUgPSA3NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTUgPSA3NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU1ID0gNzU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NTZfRklFTERfTlVNQkVSID0gNzU2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTYgPSA3NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTYgPSA3NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU2ID0gNzU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NTdfRklFTERfTlVNQkVSID0gNzU3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTcgPSA3NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTcgPSA3NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU3ID0gNzU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NThfRklFTERfTlVNQkVSID0gNzU4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTggPSA3NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTggPSA3NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU4ID0gNzU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NTlfRklFTERfTlVNQkVSID0gNzU5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTkgPSA3NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTkgPSA3NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU5ID0gNzU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NjBfRklFTERfTlVNQkVSID0gNzYwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjAgPSA3NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjAgPSA3NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYwID0gNzYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NjFfRklFTERfTlVNQkVSID0gNzYxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjEgPSA3NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjEgPSA3NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYxID0gNzYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NjJfRklFTERfTlVNQkVSID0gNzYyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjIgPSA3NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjIgPSA3NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYyID0gNzYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NjNfRklFTERfTlVNQkVSID0gNzYzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjMgPSA3NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjMgPSA3NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYzID0gNzYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NjRfRklFTERfTlVNQkVSID0gNzY0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjQgPSA3NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjQgPSA3NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY0ID0gNzY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NjVfRklFTERfTlVNQkVSID0gNzY1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjUgPSA3NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjUgPSA3NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY1ID0gNzY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NjZfRklFTERfTlVNQkVSID0gNzY2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjYgPSA3NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjYgPSA3NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY2ID0gNzY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NjdfRklFTERfTlVNQkVSID0gNzY3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjcgPSA3NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjcgPSA3NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY3ID0gNzY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NjhfRklFTERfTlVNQkVSID0gNzY4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjggPSA3NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjggPSA3NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY4ID0gNzY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NjlfRklFTERfTlVNQkVSID0gNzY5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjkgPSA3NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjkgPSA3NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY5ID0gNzY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NzBfRklFTERfTlVNQkVSID0gNzcwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzAgPSA3NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzAgPSA3NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcwID0gNzcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NzFfRklFTERfTlVNQkVSID0gNzcxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzEgPSA3NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzEgPSA3NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcxID0gNzcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NzJfRklFTERfTlVNQkVSID0gNzcyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzIgPSA3NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzIgPSA3NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcyID0gNzcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NzNfRklFTERfTlVNQkVSID0gNzczOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzMgPSA3NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzMgPSA3NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzczID0gNzczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzczXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NzRfRklFTERfTlVNQkVSID0gNzc0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzQgPSA3NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzQgPSA3NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc0ID0gNzc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NzVfRklFTERfTlVNQkVSID0gNzc1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzUgPSA3NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzUgPSA3NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc1ID0gNzc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NzZfRklFTERfTlVNQkVSID0gNzc2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzYgPSA3NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzYgPSA3NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc2ID0gNzc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NzdfRklFTERfTlVNQkVSID0gNzc3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzcgPSA3NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzcgPSA3NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc3ID0gNzc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NzhfRklFTERfTlVNQkVSID0gNzc4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzggPSA3NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzggPSA3NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc4ID0gNzc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183NzlfRklFTERfTlVNQkVSID0gNzc5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzkgPSA3NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzkgPSA3NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc5ID0gNzc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183ODBfRklFTERfTlVNQkVSID0gNzgwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODAgPSA3ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODAgPSA3ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgwID0gNzgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183ODFfRklFTERfTlVNQkVSID0gNzgxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODEgPSA3ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODEgPSA3ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgxID0gNzgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183ODJfRklFTERfTlVNQkVSID0gNzgyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODIgPSA3ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODIgPSA3ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgyID0gNzgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183ODNfRklFTERfTlVNQkVSID0gNzgzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODMgPSA3ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODMgPSA3ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgzID0gNzgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183ODRfRklFTERfTlVNQkVSID0gNzg0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODQgPSA3ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODQgPSA3ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg0ID0gNzg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183ODVfRklFTERfTlVNQkVSID0gNzg1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODUgPSA3ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODUgPSA3ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg1ID0gNzg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183ODZfRklFTERfTlVNQkVSID0gNzg2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODYgPSA3ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODYgPSA3ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg2ID0gNzg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183ODdfRklFTERfTlVNQkVSID0gNzg3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODcgPSA3ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODcgPSA3ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg3ID0gNzg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183ODhfRklFTERfTlVNQkVSID0gNzg4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODggPSA3ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODggPSA3ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg4ID0gNzg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183ODlfRklFTERfTlVNQkVSID0gNzg5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODkgPSA3ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODkgPSA3ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg5ID0gNzg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183OTBfRklFTERfTlVNQkVSID0gNzkwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTAgPSA3OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTAgPSA3OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkwID0gNzkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183OTFfRklFTERfTlVNQkVSID0gNzkxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTEgPSA3OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTEgPSA3OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkxID0gNzkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183OTJfRklFTERfTlVNQkVSID0gNzkyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTIgPSA3OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTIgPSA3OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkyID0gNzkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183OTNfRklFTERfTlVNQkVSID0gNzkzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTMgPSA3OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTMgPSA3OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkzID0gNzkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183OTRfRklFTERfTlVNQkVSID0gNzk0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTQgPSA3OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTQgPSA3OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk0ID0gNzk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183OTVfRklFTERfTlVNQkVSID0gNzk1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTUgPSA3OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTUgPSA3OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk1ID0gNzk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183OTZfRklFTERfTlVNQkVSID0gNzk2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTYgPSA3OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTYgPSA3OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk2ID0gNzk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183OTdfRklFTERfTlVNQkVSID0gNzk3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTcgPSA3OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTcgPSA3OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk3ID0gNzk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183OThfRklFTERfTlVNQkVSID0gNzk4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTggPSA3OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTggPSA3OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk4ID0gNzk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR183OTlfRklFTERfTlVNQkVSID0gNzk5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTkgPSA3OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTkgPSA3OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk5ID0gNzk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MDBfRklFTERfTlVNQkVSID0gODAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDAgPSA4MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDAgPSA4MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAwID0gODAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MDFfRklFTERfTlVNQkVSID0gODAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDEgPSA4MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDEgPSA4MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAxID0gODAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MDJfRklFTERfTlVNQkVSID0gODAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDIgPSA4MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDIgPSA4MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAyID0gODAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MDNfRklFTERfTlVNQkVSID0gODAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDMgPSA4MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDMgPSA4MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAzID0gODAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MDRfRklFTERfTlVNQkVSID0gODA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDQgPSA4MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDQgPSA4MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA0ID0gODA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MDVfRklFTERfTlVNQkVSID0gODA1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDUgPSA4MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDUgPSA4MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA1ID0gODA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MDZfRklFTERfTlVNQkVSID0gODA2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDYgPSA4MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDYgPSA4MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA2ID0gODA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MDdfRklFTERfTlVNQkVSID0gODA3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDcgPSA4MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDcgPSA4MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA3ID0gODA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MDhfRklFTERfTlVNQkVSID0gODA4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDggPSA4MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDggPSA4MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA4ID0gODA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MDlfRklFTERfTlVNQkVSID0gODA5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDkgPSA4MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDkgPSA4MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA5ID0gODA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MTBfRklFTERfTlVNQkVSID0gODEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTAgPSA4MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTAgPSA4MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEwID0gODEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MTFfRklFTERfTlVNQkVSID0gODExOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTEgPSA4MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTEgPSA4MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODExID0gODExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODExXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MTJfRklFTERfTlVNQkVSID0gODEyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTIgPSA4MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTIgPSA4MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEyID0gODEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MTNfRklFTERfTlVNQkVSID0gODEzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTMgPSA4MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTMgPSA4MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEzID0gODEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MTRfRklFTERfTlVNQkVSID0gODE0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTQgPSA4MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTQgPSA4MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE0ID0gODE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MTVfRklFTERfTlVNQkVSID0gODE1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTUgPSA4MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTUgPSA4MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE1ID0gODE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MTZfRklFTERfTlVNQkVSID0gODE2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTYgPSA4MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTYgPSA4MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE2ID0gODE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MTdfRklFTERfTlVNQkVSID0gODE3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTcgPSA4MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTcgPSA4MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE3ID0gODE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MThfRklFTERfTlVNQkVSID0gODE4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTggPSA4MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTggPSA4MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE4ID0gODE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MTlfRklFTERfTlVNQkVSID0gODE5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTkgPSA4MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTkgPSA4MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE5ID0gODE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MjBfRklFTERfTlVNQkVSID0gODIwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjAgPSA4MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjAgPSA4MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIwID0gODIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MjFfRklFTERfTlVNQkVSID0gODIxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjEgPSA4MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjEgPSA4MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIxID0gODIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MjJfRklFTERfTlVNQkVSID0gODIyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjIgPSA4MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjIgPSA4MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIyID0gODIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MjNfRklFTERfTlVNQkVSID0gODIzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjMgPSA4MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjMgPSA4MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIzID0gODIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MjRfRklFTERfTlVNQkVSID0gODI0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjQgPSA4MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjQgPSA4MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI0ID0gODI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MjVfRklFTERfTlVNQkVSID0gODI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjUgPSA4MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjUgPSA4MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI1ID0gODI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MjZfRklFTERfTlVNQkVSID0gODI2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjYgPSA4MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjYgPSA4MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI2ID0gODI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MjdfRklFTERfTlVNQkVSID0gODI3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjcgPSA4MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjcgPSA4MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI3ID0gODI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MjhfRklFTERfTlVNQkVSID0gODI4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjggPSA4MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjggPSA4MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI4ID0gODI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MjlfRklFTERfTlVNQkVSID0gODI5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjkgPSA4MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjkgPSA4MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI5ID0gODI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MzBfRklFTERfTlVNQkVSID0gODMwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzAgPSA4MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzAgPSA4MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMwID0gODMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MzFfRklFTERfTlVNQkVSID0gODMxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzEgPSA4MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzEgPSA4MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMxID0gODMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MzJfRklFTERfTlVNQkVSID0gODMyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzIgPSA4MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzIgPSA4MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMyID0gODMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MzNfRklFTERfTlVNQkVSID0gODMzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzMgPSA4MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzMgPSA4MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMzID0gODMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MzRfRklFTERfTlVNQkVSID0gODM0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzQgPSA4MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzQgPSA4MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM0ID0gODM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MzVfRklFTERfTlVNQkVSID0gODM1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzUgPSA4MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzUgPSA4MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM1ID0gODM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MzZfRklFTERfTlVNQkVSID0gODM2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzYgPSA4MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzYgPSA4MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM2ID0gODM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MzdfRklFTERfTlVNQkVSID0gODM3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzcgPSA4MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzcgPSA4MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM3ID0gODM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MzhfRklFTERfTlVNQkVSID0gODM4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzggPSA4MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzggPSA4MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM4ID0gODM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184MzlfRklFTERfTlVNQkVSID0gODM5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzkgPSA4MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzkgPSA4MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM5ID0gODM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NDBfRklFTERfTlVNQkVSID0gODQwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDAgPSA4NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDAgPSA4NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQwID0gODQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NDFfRklFTERfTlVNQkVSID0gODQxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDEgPSA4NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDEgPSA4NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQxID0gODQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NDJfRklFTERfTlVNQkVSID0gODQyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDIgPSA4NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDIgPSA4NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQyID0gODQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NDNfRklFTERfTlVNQkVSID0gODQzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDMgPSA4NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDMgPSA4NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQzID0gODQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NDRfRklFTERfTlVNQkVSID0gODQ0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDQgPSA4NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDQgPSA4NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ0ID0gODQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NDVfRklFTERfTlVNQkVSID0gODQ1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDUgPSA4NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDUgPSA4NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ1ID0gODQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NDZfRklFTERfTlVNQkVSID0gODQ2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDYgPSA4NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDYgPSA4NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ2ID0gODQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NDdfRklFTERfTlVNQkVSID0gODQ3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDcgPSA4NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDcgPSA4NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ3ID0gODQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NDhfRklFTERfTlVNQkVSID0gODQ4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDggPSA4NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDggPSA4NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ4ID0gODQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NDlfRklFTERfTlVNQkVSID0gODQ5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDkgPSA4NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDkgPSA4NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ5ID0gODQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NTBfRklFTERfTlVNQkVSID0gODUwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTAgPSA4NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTAgPSA4NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUwID0gODUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NTFfRklFTERfTlVNQkVSID0gODUxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTEgPSA4NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTEgPSA4NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUxID0gODUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NTJfRklFTERfTlVNQkVSID0gODUyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTIgPSA4NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTIgPSA4NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUyID0gODUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NTNfRklFTERfTlVNQkVSID0gODUzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTMgPSA4NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTMgPSA4NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUzID0gODUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NTRfRklFTERfTlVNQkVSID0gODU0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTQgPSA4NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTQgPSA4NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU0ID0gODU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NTVfRklFTERfTlVNQkVSID0gODU1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTUgPSA4NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTUgPSA4NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU1ID0gODU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NTZfRklFTERfTlVNQkVSID0gODU2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTYgPSA4NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTYgPSA4NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU2ID0gODU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NTdfRklFTERfTlVNQkVSID0gODU3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTcgPSA4NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTcgPSA4NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU3ID0gODU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NThfRklFTERfTlVNQkVSID0gODU4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTggPSA4NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTggPSA4NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU4ID0gODU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NTlfRklFTERfTlVNQkVSID0gODU5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTkgPSA4NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTkgPSA4NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU5ID0gODU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NjBfRklFTERfTlVNQkVSID0gODYwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjAgPSA4NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjAgPSA4NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYwID0gODYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NjFfRklFTERfTlVNQkVSID0gODYxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjEgPSA4NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjEgPSA4NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYxID0gODYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NjJfRklFTERfTlVNQkVSID0gODYyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjIgPSA4NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjIgPSA4NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYyID0gODYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NjNfRklFTERfTlVNQkVSID0gODYzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjMgPSA4NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjMgPSA4NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYzID0gODYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NjRfRklFTERfTlVNQkVSID0gODY0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjQgPSA4NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjQgPSA4NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY0ID0gODY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NjVfRklFTERfTlVNQkVSID0gODY1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjUgPSA4NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjUgPSA4NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY1ID0gODY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NjZfRklFTERfTlVNQkVSID0gODY2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjYgPSA4NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjYgPSA4NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY2ID0gODY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NjdfRklFTERfTlVNQkVSID0gODY3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjcgPSA4NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjcgPSA4NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY3ID0gODY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NjhfRklFTERfTlVNQkVSID0gODY4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjggPSA4NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjggPSA4NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY4ID0gODY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NjlfRklFTERfTlVNQkVSID0gODY5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjkgPSA4NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjkgPSA4NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY5ID0gODY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NzBfRklFTERfTlVNQkVSID0gODcwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzAgPSA4NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzAgPSA4NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcwID0gODcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NzFfRklFTERfTlVNQkVSID0gODcxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzEgPSA4NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzEgPSA4NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcxID0gODcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NzJfRklFTERfTlVNQkVSID0gODcyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzIgPSA4NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzIgPSA4NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcyID0gODcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NzNfRklFTERfTlVNQkVSID0gODczOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzMgPSA4NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzMgPSA4NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODczID0gODczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODczXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NzRfRklFTERfTlVNQkVSID0gODc0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzQgPSA4NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzQgPSA4NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc0ID0gODc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NzVfRklFTERfTlVNQkVSID0gODc1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzUgPSA4NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzUgPSA4NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc1ID0gODc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NzZfRklFTERfTlVNQkVSID0gODc2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzYgPSA4NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzYgPSA4NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc2ID0gODc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NzdfRklFTERfTlVNQkVSID0gODc3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzcgPSA4NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzcgPSA4NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc3ID0gODc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NzhfRklFTERfTlVNQkVSID0gODc4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzggPSA4NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzggPSA4NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc4ID0gODc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184NzlfRklFTERfTlVNQkVSID0gODc5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzkgPSA4NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzkgPSA4NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc5ID0gODc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184ODBfRklFTERfTlVNQkVSID0gODgwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODAgPSA4ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODAgPSA4ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgwID0gODgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184ODFfRklFTERfTlVNQkVSID0gODgxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODEgPSA4ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODEgPSA4ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgxID0gODgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184ODJfRklFTERfTlVNQkVSID0gODgyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODIgPSA4ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODIgPSA4ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgyID0gODgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184ODNfRklFTERfTlVNQkVSID0gODgzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODMgPSA4ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODMgPSA4ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgzID0gODgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184ODRfRklFTERfTlVNQkVSID0gODg0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODQgPSA4ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODQgPSA4ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg0ID0gODg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184ODVfRklFTERfTlVNQkVSID0gODg1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODUgPSA4ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODUgPSA4ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg1ID0gODg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184ODZfRklFTERfTlVNQkVSID0gODg2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODYgPSA4ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODYgPSA4ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg2ID0gODg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184ODdfRklFTERfTlVNQkVSID0gODg3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODcgPSA4ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODcgPSA4ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg3ID0gODg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184ODhfRklFTERfTlVNQkVSID0gODg4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODggPSA4ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODggPSA4ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg4ID0gODg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184ODlfRklFTERfTlVNQkVSID0gODg5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODkgPSA4ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODkgPSA4ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg5ID0gODg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184OTBfRklFTERfTlVNQkVSID0gODkwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTAgPSA4OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTAgPSA4OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkwID0gODkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184OTFfRklFTERfTlVNQkVSID0gODkxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTEgPSA4OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTEgPSA4OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkxID0gODkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184OTJfRklFTERfTlVNQkVSID0gODkyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTIgPSA4OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTIgPSA4OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkyID0gODkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184OTNfRklFTERfTlVNQkVSID0gODkzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTMgPSA4OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTMgPSA4OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkzID0gODkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184OTRfRklFTERfTlVNQkVSID0gODk0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTQgPSA4OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTQgPSA4OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk0ID0gODk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184OTVfRklFTERfTlVNQkVSID0gODk1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTUgPSA4OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTUgPSA4OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk1ID0gODk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184OTZfRklFTERfTlVNQkVSID0gODk2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTYgPSA4OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTYgPSA4OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk2ID0gODk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184OTdfRklFTERfTlVNQkVSID0gODk3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTcgPSA4OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTcgPSA4OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk3ID0gODk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184OThfRklFTERfTlVNQkVSID0gODk4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTggPSA4OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTggPSA4OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk4ID0gODk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR184OTlfRklFTERfTlVNQkVSID0gODk5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTkgPSA4OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTkgPSA4OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk5ID0gODk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MDBfRklFTERfTlVNQkVSID0gOTAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDAgPSA5MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDAgPSA5MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAwID0gOTAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MDFfRklFTERfTlVNQkVSID0gOTAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDEgPSA5MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDEgPSA5MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAxID0gOTAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MDJfRklFTERfTlVNQkVSID0gOTAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDIgPSA5MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDIgPSA5MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAyID0gOTAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MDNfRklFTERfTlVNQkVSID0gOTAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDMgPSA5MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDMgPSA5MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAzID0gOTAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MDRfRklFTERfTlVNQkVSID0gOTA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDQgPSA5MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDQgPSA5MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA0ID0gOTA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MDVfRklFTERfTlVNQkVSID0gOTA1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDUgPSA5MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDUgPSA5MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA1ID0gOTA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MDZfRklFTERfTlVNQkVSID0gOTA2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDYgPSA5MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDYgPSA5MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA2ID0gOTA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MDdfRklFTERfTlVNQkVSID0gOTA3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDcgPSA5MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDcgPSA5MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA3ID0gOTA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MDhfRklFTERfTlVNQkVSID0gOTA4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDggPSA5MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDggPSA5MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA4ID0gOTA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MDlfRklFTERfTlVNQkVSID0gOTA5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDkgPSA5MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDkgPSA5MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA5ID0gOTA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MTBfRklFTERfTlVNQkVSID0gOTEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTAgPSA5MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTAgPSA5MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEwID0gOTEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MTFfRklFTERfTlVNQkVSID0gOTExOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTEgPSA5MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTEgPSA5MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTExID0gOTExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTExXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MTJfRklFTERfTlVNQkVSID0gOTEyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTIgPSA5MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTIgPSA5MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEyID0gOTEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MTNfRklFTERfTlVNQkVSID0gOTEzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTMgPSA5MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTMgPSA5MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEzID0gOTEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MTRfRklFTERfTlVNQkVSID0gOTE0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTQgPSA5MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTQgPSA5MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE0ID0gOTE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MTVfRklFTERfTlVNQkVSID0gOTE1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTUgPSA5MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTUgPSA5MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE1ID0gOTE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MTZfRklFTERfTlVNQkVSID0gOTE2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTYgPSA5MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTYgPSA5MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE2ID0gOTE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MTdfRklFTERfTlVNQkVSID0gOTE3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTcgPSA5MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTcgPSA5MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE3ID0gOTE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MThfRklFTERfTlVNQkVSID0gOTE4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTggPSA5MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTggPSA5MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE4ID0gOTE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MTlfRklFTERfTlVNQkVSID0gOTE5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTkgPSA5MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTkgPSA5MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE5ID0gOTE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MjBfRklFTERfTlVNQkVSID0gOTIwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjAgPSA5MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjAgPSA5MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIwID0gOTIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MjFfRklFTERfTlVNQkVSID0gOTIxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjEgPSA5MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjEgPSA5MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIxID0gOTIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MjJfRklFTERfTlVNQkVSID0gOTIyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjIgPSA5MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjIgPSA5MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIyID0gOTIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MjNfRklFTERfTlVNQkVSID0gOTIzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjMgPSA5MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjMgPSA5MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIzID0gOTIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MjRfRklFTERfTlVNQkVSID0gOTI0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjQgPSA5MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjQgPSA5MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI0ID0gOTI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MjVfRklFTERfTlVNQkVSID0gOTI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjUgPSA5MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjUgPSA5MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI1ID0gOTI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MjZfRklFTERfTlVNQkVSID0gOTI2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjYgPSA5MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjYgPSA5MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI2ID0gOTI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MjdfRklFTERfTlVNQkVSID0gOTI3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjcgPSA5MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjcgPSA5MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI3ID0gOTI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MjhfRklFTERfTlVNQkVSID0gOTI4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjggPSA5MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjggPSA5MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI4ID0gOTI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MjlfRklFTERfTlVNQkVSID0gOTI5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjkgPSA5MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjkgPSA5MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI5ID0gOTI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MzBfRklFTERfTlVNQkVSID0gOTMwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzAgPSA5MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzAgPSA5MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMwID0gOTMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MzFfRklFTERfTlVNQkVSID0gOTMxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzEgPSA5MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzEgPSA5MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMxID0gOTMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MzJfRklFTERfTlVNQkVSID0gOTMyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzIgPSA5MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzIgPSA5MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMyID0gOTMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MzNfRklFTERfTlVNQkVSID0gOTMzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzMgPSA5MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzMgPSA5MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzM187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMzID0gOTMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MzRfRklFTERfTlVNQkVSID0gOTM0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzQgPSA5MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzQgPSA5MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM0ID0gOTM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MzVfRklFTERfTlVNQkVSID0gOTM1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzUgPSA5MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzUgPSA5MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM1ID0gOTM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MzZfRklFTERfTlVNQkVSID0gOTM2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzYgPSA5MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzYgPSA5MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM2ID0gOTM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MzdfRklFTERfTlVNQkVSID0gOTM3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzcgPSA5MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzcgPSA5MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM3ID0gOTM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzN18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MzhfRklFTERfTlVNQkVSID0gOTM4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzggPSA5MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzggPSA5MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM4ID0gOTM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185MzlfRklFTERfTlVNQkVSID0gOTM5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzkgPSA5MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzkgPSA5MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM5ID0gOTM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NDBfRklFTERfTlVNQkVSID0gOTQwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDAgPSA5NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDAgPSA5NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQwID0gOTQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NDFfRklFTERfTlVNQkVSID0gOTQxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDEgPSA5NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDEgPSA5NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQxID0gOTQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NDJfRklFTERfTlVNQkVSID0gOTQyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDIgPSA5NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDIgPSA5NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQyID0gOTQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NDNfRklFTERfTlVNQkVSID0gOTQzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDMgPSA5NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDMgPSA5NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQzID0gOTQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NDRfRklFTERfTlVNQkVSID0gOTQ0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDQgPSA5NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDQgPSA5NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ0ID0gOTQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NDVfRklFTERfTlVNQkVSID0gOTQ1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDUgPSA5NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDUgPSA5NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ1ID0gOTQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NDZfRklFTERfTlVNQkVSID0gOTQ2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDYgPSA5NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDYgPSA5NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ2ID0gOTQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NDdfRklFTERfTlVNQkVSID0gOTQ3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDcgPSA5NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDcgPSA5NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ3ID0gOTQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NDhfRklFTERfTlVNQkVSID0gOTQ4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDggPSA5NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDggPSA5NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ4ID0gOTQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NDlfRklFTERfTlVNQkVSID0gOTQ5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDkgPSA5NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDkgPSA5NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ5ID0gOTQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NTBfRklFTERfTlVNQkVSID0gOTUwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTAgPSA5NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTAgPSA5NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUwID0gOTUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NTFfRklFTERfTlVNQkVSID0gOTUxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTEgPSA5NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTEgPSA5NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUxID0gOTUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NTJfRklFTERfTlVNQkVSID0gOTUyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTIgPSA5NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTIgPSA5NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUyID0gOTUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NTNfRklFTERfTlVNQkVSID0gOTUzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTMgPSA5NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTMgPSA5NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUzID0gOTUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NTRfRklFTERfTlVNQkVSID0gOTU0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTQgPSA5NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTQgPSA5NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU0ID0gOTU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NTVfRklFTERfTlVNQkVSID0gOTU1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTUgPSA5NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTUgPSA5NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU1ID0gOTU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NTZfRklFTERfTlVNQkVSID0gOTU2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTYgPSA5NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTYgPSA5NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU2ID0gOTU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NTdfRklFTERfTlVNQkVSID0gOTU3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTcgPSA5NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTcgPSA5NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU3ID0gOTU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NThfRklFTERfTlVNQkVSID0gOTU4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTggPSA5NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTggPSA5NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU4ID0gOTU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NTlfRklFTERfTlVNQkVSID0gOTU5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTkgPSA5NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTkgPSA5NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU5ID0gOTU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NjBfRklFTERfTlVNQkVSID0gOTYwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjAgPSA5NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjAgPSA5NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYwID0gOTYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NjFfRklFTERfTlVNQkVSID0gOTYxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjEgPSA5NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjEgPSA5NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYxID0gOTYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NjJfRklFTERfTlVNQkVSID0gOTYyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjIgPSA5NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjIgPSA5NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYyID0gOTYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NjNfRklFTERfTlVNQkVSID0gOTYzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjMgPSA5NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjMgPSA5NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYzID0gOTYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NjRfRklFTERfTlVNQkVSID0gOTY0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjQgPSA5NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjQgPSA5NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY0ID0gOTY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NjVfRklFTERfTlVNQkVSID0gOTY1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjUgPSA5NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjUgPSA5NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY1ID0gOTY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NjZfRklFTERfTlVNQkVSID0gOTY2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjYgPSA5NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjYgPSA5NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY2ID0gOTY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NjdfRklFTERfTlVNQkVSID0gOTY3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjcgPSA5NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjcgPSA5NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY3ID0gOTY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NjhfRklFTERfTlVNQkVSID0gOTY4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjggPSA5NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjggPSA5NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY4ID0gOTY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NjlfRklFTERfTlVNQkVSID0gOTY5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjkgPSA5NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjkgPSA5NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY5ID0gOTY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NzBfRklFTERfTlVNQkVSID0gOTcwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzAgPSA5NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzAgPSA5NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcwID0gOTcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NzFfRklFTERfTlVNQkVSID0gOTcxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzEgPSA5NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzEgPSA5NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcxID0gOTcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NzJfRklFTERfTlVNQkVSID0gOTcyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzIgPSA5NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzIgPSA5NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcyID0gOTcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NzNfRklFTERfTlVNQkVSID0gOTczOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzMgPSA5NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzMgPSA5NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTczID0gOTczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTczXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NzRfRklFTERfTlVNQkVSID0gOTc0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzQgPSA5NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzQgPSA5NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc0ID0gOTc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NzVfRklFTERfTlVNQkVSID0gOTc1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzUgPSA5NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzUgPSA5NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc1ID0gOTc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NzZfRklFTERfTlVNQkVSID0gOTc2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzYgPSA5NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzYgPSA5NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc2ID0gOTc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NzdfRklFTERfTlVNQkVSID0gOTc3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzcgPSA5NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzcgPSA5NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc3ID0gOTc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NzhfRklFTERfTlVNQkVSID0gOTc4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzggPSA5NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzggPSA5NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc4ID0gOTc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185NzlfRklFTERfTlVNQkVSID0gOTc5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzkgPSA5NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzkgPSA5NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc5ID0gOTc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185ODBfRklFTERfTlVNQkVSID0gOTgwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODAgPSA5ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODAgPSA5ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgwID0gOTgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185ODFfRklFTERfTlVNQkVSID0gOTgxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODEgPSA5ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODEgPSA5ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgxID0gOTgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185ODJfRklFTERfTlVNQkVSID0gOTgyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODIgPSA5ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODIgPSA5ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgyID0gOTgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185ODNfRklFTERfTlVNQkVSID0gOTgzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODMgPSA5ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODMgPSA5ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgzID0gOTgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185ODRfRklFTERfTlVNQkVSID0gOTg0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODQgPSA5ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODQgPSA5ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg0ID0gOTg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185ODVfRklFTERfTlVNQkVSID0gOTg1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODUgPSA5ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODUgPSA5ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg1ID0gOTg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185ODZfRklFTERfTlVNQkVSID0gOTg2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODYgPSA5ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODYgPSA5ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg2ID0gOTg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185ODdfRklFTERfTlVNQkVSID0gOTg3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODcgPSA5ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODcgPSA5ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg3ID0gOTg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185ODhfRklFTERfTlVNQkVSID0gOTg4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODggPSA5ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODggPSA5ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg4ID0gOTg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185ODlfRklFTERfTlVNQkVSID0gOTg5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODkgPSA5ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODkgPSA5ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg5ID0gOTg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185OTBfRklFTERfTlVNQkVSID0gOTkwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTAgPSA5OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTAgPSA5OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkwID0gOTkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185OTFfRklFTERfTlVNQkVSID0gOTkxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTEgPSA5OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTEgPSA5OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkxID0gOTkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185OTJfRklFTERfTlVNQkVSID0gOTkyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTIgPSA5OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTIgPSA5OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Ml87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Ml8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkyID0gOTkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Ml8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185OTNfRklFTERfTlVNQkVSID0gOTkzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTMgPSA5OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzFfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTMgPSA5OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5M187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5M18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkzID0gOTkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5M18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185OTRfRklFTERfTlVNQkVSID0gOTk0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTQgPSA5OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzFfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTQgPSA5OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk0ID0gOTk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185OTVfRklFTERfTlVNQkVSID0gOTk1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTUgPSA5OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzFfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTUgPSA5OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk1ID0gOTk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk1XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185OTZfRklFTERfTlVNQkVSID0gOTk2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTYgPSA5OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzFfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTYgPSA5OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Nl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Nl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk2ID0gOTk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTZCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Nl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185OTdfRklFTERfTlVNQkVSID0gOTk3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTcgPSA5OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzFfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTcgPSA5OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5N187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5N18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk3ID0gOTk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Ny4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5N18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185OThfRklFTERfTlVNQkVSID0gOTk4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTggPSA5OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzFfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTggPSA5OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk4ID0gOTk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk4XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR185OTlfRklFTERfTlVNQkVSID0gOTk5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTkgPSA5OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMzFfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTkgPSA5OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk5ID0gOTk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTlCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HX0ZJRUxEX05BTUVfSVNfTE9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09OR18xMDAwX0ZJRUxEX05VTUJFUiA9IDEwMDA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDAwID0gMTAwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDMxXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAwMCA9IDEwMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMDBfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMDAgPSAxMDAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMDBfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvciBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvciBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvciBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogY2xhbmctZm9ybWF0IG9mZgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEVub3Jtb3VzRGVzY3JpcHRvcn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbm9ybW91c0Rlc2NyaXB0b3JfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVub3Jtb3VzRGVzY3JpcHRvcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvci5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvci5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgYml0RmllbGQxXyA9IDA7CiAgICAgICAgYml0RmllbGQyXyA9IDA7CiAgICAgICAgYml0RmllbGQzXyA9IDA7CiAgICAgICAgYml0RmllbGQ0XyA9IDA7CiAgICAgICAgYml0RmllbGQ1XyA9IDA7CiAgICAgICAgYml0RmllbGQ2XyA9IDA7CiAgICAgICAgYml0RmllbGQ3XyA9IDA7CiAgICAgICAgYml0RmllbGQ4XyA9IDA7CiAgICAgICAgYml0RmllbGQ5XyA9IDA7CiAgICAgICAgYml0RmllbGQxMF8gPSAwOwogICAgICAgIGJpdEZpZWxkMTFfID0gMDsKICAgICAgICBiaXRGaWVsZDEyXyA9IDA7CiAgICAgICAgYml0RmllbGQxM18gPSAwOwogICAgICAgIGJpdEZpZWxkMTRfID0gMDsKICAgICAgICBiaXRGaWVsZDE1XyA9IDA7CiAgICAgICAgYml0RmllbGQxNl8gPSAwOwogICAgICAgIGJpdEZpZWxkMTdfID0gMDsKICAgICAgICBiaXRGaWVsZDE4XyA9IDA7CiAgICAgICAgYml0RmllbGQxOV8gPSAwOwogICAgICAgIGJpdEZpZWxkMjBfID0gMDsKICAgICAgICBiaXRGaWVsZDIxXyA9IDA7CiAgICAgICAgYml0RmllbGQyMl8gPSAwOwogICAgICAgIGJpdEZpZWxkMjNfID0gMDsKICAgICAgICBiaXRGaWVsZDI0XyA9IDA7CiAgICAgICAgYml0RmllbGQyNV8gPSAwOwogICAgICAgIGJpdEZpZWxkMjZfID0gMDsKICAgICAgICBiaXRGaWVsZDI3XyA9IDA7CiAgICAgICAgYml0RmllbGQyOF8gPSAwOwogICAgICAgIGJpdEZpZWxkMjlfID0gMDsKICAgICAgICBiaXRGaWVsZDMwXyA9IDA7CiAgICAgICAgYml0RmllbGQzMV8gPSAwOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVub3Jtb3VzRGVzY3JpcHRvcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvcih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDFfICE9IDApIHsgYnVpbGRQYXJ0aWFsMShyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMl8gIT0gMCkgeyBidWlsZFBhcnRpYWwyKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQzXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDMocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDRfICE9IDApIHsgYnVpbGRQYXJ0aWFsNChyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkNV8gIT0gMCkgeyBidWlsZFBhcnRpYWw1KHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQ2XyAhPSAwKSB7IGJ1aWxkUGFydGlhbDYocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDdfICE9IDApIHsgYnVpbGRQYXJ0aWFsNyhyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkOF8gIT0gMCkgeyBidWlsZFBhcnRpYWw4KHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQ5XyAhPSAwKSB7IGJ1aWxkUGFydGlhbDkocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDEwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDEwKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQxMV8gIT0gMCkgeyBidWlsZFBhcnRpYWwxMShyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMTJfICE9IDApIHsgYnVpbGRQYXJ0aWFsMTIocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDEzXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDEzKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQxNF8gIT0gMCkgeyBidWlsZFBhcnRpYWwxNChyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMTVfICE9IDApIHsgYnVpbGRQYXJ0aWFsMTUocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDE2XyAhPSAwKSB7IGJ1aWxkUGFydGlhbDE2KHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQxN18gIT0gMCkgeyBidWlsZFBhcnRpYWwxNyhyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMThfICE9IDApIHsgYnVpbGRQYXJ0aWFsMTgocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDE5XyAhPSAwKSB7IGJ1aWxkUGFydGlhbDE5KHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQyMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwyMChyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMjFfICE9IDApIHsgYnVpbGRQYXJ0aWFsMjEocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDIyXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDIyKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQyM18gIT0gMCkgeyBidWlsZFBhcnRpYWwyMyhyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMjRfICE9IDApIHsgYnVpbGRQYXJ0aWFsMjQocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDI1XyAhPSAwKSB7IGJ1aWxkUGFydGlhbDI1KHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQyNl8gIT0gMCkgeyBidWlsZFBhcnRpYWwyNihyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMjdfICE9IDApIHsgYnVpbGRQYXJ0aWFsMjcocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDI4XyAhPSAwKSB7IGJ1aWxkUGFydGlhbDI4KHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQyOV8gIT0gMCkgeyBidWlsZFBhcnRpYWwyOShyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMzBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMzAocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDMxXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDMxKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzZfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzlfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTBfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTZfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxN18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMThfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTlfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjBfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjZfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyN18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjhfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjlfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzBfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMShjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQxXyA9IGJpdEZpZWxkMV87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMV8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczM187CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNF87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNV87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNl87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczN187CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOF87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOV87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MF87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MV87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0M187CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NF87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NV87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0N187CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OF87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OV87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MF87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MV87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1M187CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NF87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NV87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1N187CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OF87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OV87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MF87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MV87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2M187CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDFfIHw9IHRvX2JpdEZpZWxkMV87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwyKGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDJfID0gYml0RmllbGQyXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQyXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAwODAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwNDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgwODAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHg0MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMl8gfD0gdG9fYml0RmllbGQyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDMoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkM18gPSBiaXRGaWVsZDNfOwogICAgICAgIGludCB0b19iaXRGaWVsZDNfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTdfOwogICAgICAgICAgdG9fYml0RmllbGQzXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOThfOwogICAgICAgICAgdG9fYml0RmllbGQzXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTlfOwogICAgICAgICAgdG9fYml0RmllbGQzXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMF87CiAgICAgICAgICB0b19iaXRGaWVsZDNfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkM18gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDJfOwogICAgICAgICAgdG9fYml0RmllbGQzXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwM187CiAgICAgICAgICB0b19iaXRGaWVsZDNfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkM18gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDVfOwogICAgICAgICAgdG9fYml0RmllbGQzXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNl87CiAgICAgICAgICB0b19iaXRGaWVsZDNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwN18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkM18gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDhfOwogICAgICAgICAgdG9fYml0RmllbGQzXyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOV87CiAgICAgICAgICB0b19iaXRGaWVsZDNfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkM18gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTFfOwogICAgICAgICAgdG9fYml0RmllbGQzXyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMl87CiAgICAgICAgICB0b19iaXRGaWVsZDNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkM18gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTRfOwogICAgICAgICAgdG9fYml0RmllbGQzXyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNV87CiAgICAgICAgICB0b19iaXRGaWVsZDNfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkM18gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTdfOwogICAgICAgICAgdG9fYml0RmllbGQzXyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMThfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOF87CiAgICAgICAgICB0b19iaXRGaWVsZDNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkM18gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjBfOwogICAgICAgICAgdG9fYml0RmllbGQzXyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMV87CiAgICAgICAgICB0b19iaXRGaWVsZDNfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjNfOwogICAgICAgICAgdG9fYml0RmllbGQzXyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNF87CiAgICAgICAgICB0b19iaXRGaWVsZDNfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkM18gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDNfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjZfOwogICAgICAgICAgdG9fYml0RmllbGQzXyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkM18gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyN187CiAgICAgICAgICB0b19iaXRGaWVsZDNfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkM18gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkM18gfD0gdG9fYml0RmllbGQzXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDQoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkNF8gPSBiaXRGaWVsZDRfOwogICAgICAgIGludCB0b19iaXRGaWVsZDRfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOV87CiAgICAgICAgICB0b19iaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ0XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzFfOwogICAgICAgICAgdG9fYml0RmllbGQ0XyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMl87CiAgICAgICAgICB0b19iaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ0XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzRfOwogICAgICAgICAgdG9fYml0RmllbGQ0XyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNV87CiAgICAgICAgICB0b19iaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ0XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzdfOwogICAgICAgICAgdG9fYml0RmllbGQ0XyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOF87CiAgICAgICAgICB0b19iaXRGaWVsZDRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ0XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDBfOwogICAgICAgICAgdG9fYml0RmllbGQ0XyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MV87CiAgICAgICAgICB0b19iaXRGaWVsZDRfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ0XyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDNfOwogICAgICAgICAgdG9fYml0RmllbGQ0XyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NF87CiAgICAgICAgICB0b19iaXRGaWVsZDRfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ0XyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDZfOwogICAgICAgICAgdG9fYml0RmllbGQ0XyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0N187CiAgICAgICAgICB0b19iaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ0XyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDlfOwogICAgICAgICAgdG9fYml0RmllbGQ0XyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MF87CiAgICAgICAgICB0b19iaXRGaWVsZDRfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ0XyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTJfOwogICAgICAgICAgdG9fYml0RmllbGQ0XyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1M187CiAgICAgICAgICB0b19iaXRGaWVsZDRfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ0XyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTVfOwogICAgICAgICAgdG9fYml0RmllbGQ0XyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDRfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ0XyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDRfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNThfOwogICAgICAgICAgdG9fYml0RmllbGQ0XyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OV87CiAgICAgICAgICB0b19iaXRGaWVsZDRfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ0XyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkNF8gfD0gdG9fYml0RmllbGQ0XzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDUoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkNV8gPSBiaXRGaWVsZDVfOwogICAgICAgIGludCB0b19iaXRGaWVsZDVfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNV8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MV87CiAgICAgICAgICB0b19iaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjNfOwogICAgICAgICAgdG9fYml0RmllbGQ1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNV8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjZfOwogICAgICAgICAgdG9fYml0RmllbGQ1XyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNV8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2N187CiAgICAgICAgICB0b19iaXRGaWVsZDVfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjlfOwogICAgICAgICAgdG9fYml0RmllbGQ1XyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNV8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MF87CiAgICAgICAgICB0b19iaXRGaWVsZDVfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzJfOwogICAgICAgICAgdG9fYml0RmllbGQ1XyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3M187CiAgICAgICAgICB0b19iaXRGaWVsZDVfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzVfOwogICAgICAgICAgdG9fYml0RmllbGQ1XyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNV8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDVfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzhfOwogICAgICAgICAgdG9fYml0RmllbGQ1XyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNV8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OV87CiAgICAgICAgICB0b19iaXRGaWVsZDVfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODFfOwogICAgICAgICAgdG9fYml0RmllbGQ1XyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNV8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDVfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODRfOwogICAgICAgICAgdG9fYml0RmllbGQ1XyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNV8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NV87CiAgICAgICAgICB0b19iaXRGaWVsZDVfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODdfOwogICAgICAgICAgdG9fYml0RmllbGQ1XyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNV8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OF87CiAgICAgICAgICB0b19iaXRGaWVsZDVfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDVfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTBfOwogICAgICAgICAgdG9fYml0RmllbGQ1XyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNV8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MV87CiAgICAgICAgICB0b19iaXRGaWVsZDVfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ1XyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkNV8gfD0gdG9fYml0RmllbGQ1XzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDYoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkNl8gPSBiaXRGaWVsZDZfOwogICAgICAgIGludCB0b19iaXRGaWVsZDZfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5M187CiAgICAgICAgICB0b19iaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTVfOwogICAgICAgICAgdG9fYml0RmllbGQ2XyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOThfOwogICAgICAgICAgdG9fYml0RmllbGQ2XyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OV87CiAgICAgICAgICB0b19iaXRGaWVsZDZfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDFfOwogICAgICAgICAgdG9fYml0RmllbGQ2XyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMl87CiAgICAgICAgICB0b19iaXRGaWVsZDZfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDRfOwogICAgICAgICAgdG9fYml0RmllbGQ2XyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNV87CiAgICAgICAgICB0b19iaXRGaWVsZDZfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDdfOwogICAgICAgICAgdG9fYml0RmllbGQ2XyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOF87CiAgICAgICAgICB0b19iaXRGaWVsZDZfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTBfOwogICAgICAgICAgdG9fYml0RmllbGQ2XyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMV87CiAgICAgICAgICB0b19iaXRGaWVsZDZfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTNfOwogICAgICAgICAgdG9fYml0RmllbGQ2XyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNF87CiAgICAgICAgICB0b19iaXRGaWVsZDZfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTZfOwogICAgICAgICAgdG9fYml0RmllbGQ2XyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxN187CiAgICAgICAgICB0b19iaXRGaWVsZDZfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTlfOwogICAgICAgICAgdG9fYml0RmllbGQ2XyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMF87CiAgICAgICAgICB0b19iaXRGaWVsZDZfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkNl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDZfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjJfOwogICAgICAgICAgdG9fYml0RmllbGQ2XyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkNl8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyM187CiAgICAgICAgICB0b19iaXRGaWVsZDZfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ2XyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkNl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkNl8gfD0gdG9fYml0RmllbGQ2XzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDcoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkN18gPSBiaXRGaWVsZDdfOwogICAgICAgIGludCB0b19iaXRGaWVsZDdfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkN18gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNV87CiAgICAgICAgICB0b19iaXRGaWVsZDdfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ3XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkN18gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDdfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjdfOwogICAgICAgICAgdG9fYml0RmllbGQ3XyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkN18gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOF87CiAgICAgICAgICB0b19iaXRGaWVsZDdfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ3XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkN18gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDdfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzBfOwogICAgICAgICAgdG9fYml0RmllbGQ3XyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkN18gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMV87CiAgICAgICAgICB0b19iaXRGaWVsZDdfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ3XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkN18gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDdfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzNfOwogICAgICAgICAgdG9fYml0RmllbGQ3XyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkN18gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNF87CiAgICAgICAgICB0b19iaXRGaWVsZDdfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ3XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkN18gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDdfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzZfOwogICAgICAgICAgdG9fYml0RmllbGQ3XyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkN18gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzN187CiAgICAgICAgICB0b19iaXRGaWVsZDdfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ3XyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkN18gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDdfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzlfOwogICAgICAgICAgdG9fYml0RmllbGQ3XyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkN18gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MF87CiAgICAgICAgICB0b19iaXRGaWVsZDdfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ3XyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkN18gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDdfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDJfOwogICAgICAgICAgdG9fYml0RmllbGQ3XyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkN18gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0M187CiAgICAgICAgICB0b19iaXRGaWVsZDdfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ3XyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkN18gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDdfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDVfOwogICAgICAgICAgdG9fYml0RmllbGQ3XyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkN18gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDdfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ3XyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkN18gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDdfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDhfOwogICAgICAgICAgdG9fYml0RmllbGQ3XyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkN18gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OV87CiAgICAgICAgICB0b19iaXRGaWVsZDdfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ3XyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkN18gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDdfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTFfOwogICAgICAgICAgdG9fYml0RmllbGQ3XyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkN18gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDdfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ3XyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkN18gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDdfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTRfOwogICAgICAgICAgdG9fYml0RmllbGQ3XyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkN18gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NV87CiAgICAgICAgICB0b19iaXRGaWVsZDdfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ3XyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkN18gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkN18gfD0gdG9fYml0RmllbGQ3XzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDgoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkOF8gPSBiaXRGaWVsZDhfOwogICAgICAgIGludCB0b19iaXRGaWVsZDhfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1N187CiAgICAgICAgICB0b19iaXRGaWVsZDhfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ4XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkOF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDhfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTlfOwogICAgICAgICAgdG9fYml0RmllbGQ4XyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MF87CiAgICAgICAgICB0b19iaXRGaWVsZDhfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ4XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkOF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDhfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjJfOwogICAgICAgICAgdG9fYml0RmllbGQ4XyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2M187CiAgICAgICAgICB0b19iaXRGaWVsZDhfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ4XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkOF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDhfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjVfOwogICAgICAgICAgdG9fYml0RmllbGQ4XyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDhfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ4XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkOF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDhfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjhfOwogICAgICAgICAgdG9fYml0RmllbGQ4XyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OV87CiAgICAgICAgICB0b19iaXRGaWVsZDhfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ4XyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkOF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDhfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzFfOwogICAgICAgICAgdG9fYml0RmllbGQ4XyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDhfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ4XyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczXzsKICAgICAgICAgIHRvX2JpdEZpZWxkOF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDhfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzRfOwogICAgICAgICAgdG9fYml0RmllbGQ4XyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NV87CiAgICAgICAgICB0b19iaXRGaWVsZDhfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ4XyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkOF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDhfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzdfOwogICAgICAgICAgdG9fYml0RmllbGQ4XyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OF87CiAgICAgICAgICB0b19iaXRGaWVsZDhfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ4XyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkOF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDhfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODBfOwogICAgICAgICAgdG9fYml0RmllbGQ4XyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MV87CiAgICAgICAgICB0b19iaXRGaWVsZDhfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ4XyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkOF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDhfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODNfOwogICAgICAgICAgdG9fYml0RmllbGQ4XyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NF87CiAgICAgICAgICB0b19iaXRGaWVsZDhfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ4XyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkOF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDhfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODZfOwogICAgICAgICAgdG9fYml0RmllbGQ4XyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4N187CiAgICAgICAgICB0b19iaXRGaWVsZDhfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ4XyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkOF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkOF8gfD0gdG9fYml0RmllbGQ4XzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDkoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkOV8gPSBiaXRGaWVsZDlfOwogICAgICAgIGludCB0b19iaXRGaWVsZDlfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOV8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OV87CiAgICAgICAgICB0b19iaXRGaWVsZDlfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ5XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkOV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDlfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTFfOwogICAgICAgICAgdG9fYml0RmllbGQ5XyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOV8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDlfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ5XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkOV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDlfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTRfOwogICAgICAgICAgdG9fYml0RmllbGQ5XyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOV8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NV87CiAgICAgICAgICB0b19iaXRGaWVsZDlfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ5XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkOV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDlfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTdfOwogICAgICAgICAgdG9fYml0RmllbGQ5XyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOV8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOThfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OF87CiAgICAgICAgICB0b19iaXRGaWVsZDlfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ5XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkOV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDlfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDBfOwogICAgICAgICAgdG9fYml0RmllbGQ5XyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMV87CiAgICAgICAgICB0b19iaXRGaWVsZDlfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ5XyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkOV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDlfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDNfOwogICAgICAgICAgdG9fYml0RmllbGQ5XyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOV8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNF87CiAgICAgICAgICB0b19iaXRGaWVsZDlfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ5XyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkOV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDlfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDZfOwogICAgICAgICAgdG9fYml0RmllbGQ5XyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOV8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwN187CiAgICAgICAgICB0b19iaXRGaWVsZDlfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ5XyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkOV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDlfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDlfOwogICAgICAgICAgdG9fYml0RmllbGQ5XyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOV8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMF87CiAgICAgICAgICB0b19iaXRGaWVsZDlfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ5XyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzExXzsKICAgICAgICAgIHRvX2JpdEZpZWxkOV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDlfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTJfOwogICAgICAgICAgdG9fYml0RmllbGQ5XyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOV8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxM187CiAgICAgICAgICB0b19iaXRGaWVsZDlfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ5XyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkOV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDlfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTVfOwogICAgICAgICAgdG9fYml0RmllbGQ5XyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOV8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNl87CiAgICAgICAgICB0b19iaXRGaWVsZDlfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ5XyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxN18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkOV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDlfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMThfOwogICAgICAgICAgdG9fYml0RmllbGQ5XyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkOV8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOV87CiAgICAgICAgICB0b19iaXRGaWVsZDlfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQ5XyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkOV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkOV8gfD0gdG9fYml0RmllbGQ5XzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDEwKGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDEwXyA9IGJpdEZpZWxkMTBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDEwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMl87CiAgICAgICAgICB0b19iaXRGaWVsZDEwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjNfOwogICAgICAgICAgdG9fYml0RmllbGQxMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNV87CiAgICAgICAgICB0b19iaXRGaWVsZDEwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjZfOwogICAgICAgICAgdG9fYml0RmllbGQxMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyN18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOF87CiAgICAgICAgICB0b19iaXRGaWVsZDEwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjlfOwogICAgICAgICAgdG9fYml0RmllbGQxMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMV87CiAgICAgICAgICB0b19iaXRGaWVsZDEwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzJfOwogICAgICAgICAgdG9fYml0RmllbGQxMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNF87CiAgICAgICAgICB0b19iaXRGaWVsZDEwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzVfOwogICAgICAgICAgdG9fYml0RmllbGQxMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzN187CiAgICAgICAgICB0b19iaXRGaWVsZDEwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzhfOwogICAgICAgICAgdG9fYml0RmllbGQxMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEwXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MF87CiAgICAgICAgICB0b19iaXRGaWVsZDEwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTBfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDFfOwogICAgICAgICAgdG9fYml0RmllbGQxMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEwXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0M187CiAgICAgICAgICB0b19iaXRGaWVsZDEwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTBfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDRfOwogICAgICAgICAgdG9fYml0RmllbGQxMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEwXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDEwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTBfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDdfOwogICAgICAgICAgdG9fYml0RmllbGQxMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMF8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OV87CiAgICAgICAgICB0b19iaXRGaWVsZDEwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTBfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTBfOwogICAgICAgICAgdG9fYml0RmllbGQxMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEwXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDEwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQxMF8gfD0gdG9fYml0RmllbGQxMF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwxMShjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQxMV8gPSBiaXRGaWVsZDExXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQxMV8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMV8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1M187CiAgICAgICAgICB0b19iaXRGaWVsZDExXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTFfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTRfOwogICAgICAgICAgdG9fYml0RmllbGQxMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDExXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMV8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDExXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTFfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTdfOwogICAgICAgICAgdG9fYml0RmllbGQxMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDExXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMV8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OV87CiAgICAgICAgICB0b19iaXRGaWVsZDExXyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTFfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjBfOwogICAgICAgICAgdG9fYml0RmllbGQxMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDExXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTFfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMV8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDExXyB8PSAweDAwMDAwMjAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTFfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjNfOwogICAgICAgICAgdG9fYml0RmllbGQxMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDExXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NV87CiAgICAgICAgICB0b19iaXRGaWVsZDExXyB8PSAweDAwMDAxMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTFfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjZfOwogICAgICAgICAgdG9fYml0RmllbGQxMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDExXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMV8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OF87CiAgICAgICAgICB0b19iaXRGaWVsZDExXyB8PSAweDAwMDA4MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTFfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjlfOwogICAgICAgICAgdG9fYml0RmllbGQxMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDExXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMV8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MV87CiAgICAgICAgICB0b19iaXRGaWVsZDExXyB8PSAweDAwMDQwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTFfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzJfOwogICAgICAgICAgdG9fYml0RmllbGQxMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDExXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzczXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTFfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMV8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NF87CiAgICAgICAgICB0b19iaXRGaWVsZDExXyB8PSAweDAwMjAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTFfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzVfOwogICAgICAgICAgdG9fYml0RmllbGQxMV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDExXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTFfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMV8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3N187CiAgICAgICAgICB0b19iaXRGaWVsZDExXyB8PSAweDAxMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTFfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzhfOwogICAgICAgICAgdG9fYml0RmllbGQxMV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDExXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTFfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMV8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MF87CiAgICAgICAgICB0b19iaXRGaWVsZDExXyB8PSAweDA4MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTFfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODFfOwogICAgICAgICAgdG9fYml0RmllbGQxMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDExXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTFfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMV8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4M187CiAgICAgICAgICB0b19iaXRGaWVsZDExXyB8PSAweDQwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTFfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODRfOwogICAgICAgICAgdG9fYml0RmllbGQxMV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMTFfIHw9IHRvX2JpdEZpZWxkMTFfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMTIoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMTJfID0gYml0RmllbGQxMl87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMTJfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTJfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODVfOwogICAgICAgICAgdG9fYml0RmllbGQxMl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEyXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMl8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4N187CiAgICAgICAgICB0b19iaXRGaWVsZDEyXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTJfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODhfOwogICAgICAgICAgdG9fYml0RmllbGQxMl8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEyXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTJfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMl8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MF87CiAgICAgICAgICB0b19iaXRGaWVsZDEyXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTJfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTFfOwogICAgICAgICAgdG9fYml0RmllbGQxMl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEyXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMl8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5M187CiAgICAgICAgICB0b19iaXRGaWVsZDEyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTJfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTRfOwogICAgICAgICAgdG9fYml0RmllbGQxMl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEyXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTJfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMl8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDEyXyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTJfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTdfOwogICAgICAgICAgdG9fYml0RmllbGQxMl8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEyXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMl8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OV87CiAgICAgICAgICB0b19iaXRGaWVsZDEyXyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTJfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDBfOwogICAgICAgICAgdG9fYml0RmllbGQxMl8gfD0gMHgwMDAwODAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEyXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTJfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMl8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMl87CiAgICAgICAgICB0b19iaXRGaWVsZDEyXyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTJfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDNfOwogICAgICAgICAgdG9fYml0RmllbGQxMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEyXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTJfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMl8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNV87CiAgICAgICAgICB0b19iaXRGaWVsZDEyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTJfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDZfOwogICAgICAgICAgdG9fYml0RmllbGQxMl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEyXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwN18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTJfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMl8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOF87CiAgICAgICAgICB0b19iaXRGaWVsZDEyXyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTJfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDlfOwogICAgICAgICAgdG9fYml0RmllbGQxMl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEyXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTJfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMl8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMV87CiAgICAgICAgICB0b19iaXRGaWVsZDEyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTJfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTJfOwogICAgICAgICAgdG9fYml0RmllbGQxMl8gfD0gMHgwODAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEyXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTJfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxMl8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNF87CiAgICAgICAgICB0b19iaXRGaWVsZDEyXyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTJfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTVfOwogICAgICAgICAgdG9fYml0RmllbGQxMl8gfD0gMHg0MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEyXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTJfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDEyXyB8PSB0b19iaXRGaWVsZDEyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDEzKGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDEzXyA9IGJpdEZpZWxkMTNfOwogICAgICAgIGludCB0b19iaXRGaWVsZDEzXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEzXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxN18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTNfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxM18gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MThfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOF87CiAgICAgICAgICB0b19iaXRGaWVsZDEzXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTNfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTlfOwogICAgICAgICAgdG9fYml0RmllbGQxM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEzXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTNfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxM18gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMV87CiAgICAgICAgICB0b19iaXRGaWVsZDEzXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTNfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjJfOwogICAgICAgICAgdG9fYml0RmllbGQxM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEzXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTNfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxM18gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNF87CiAgICAgICAgICB0b19iaXRGaWVsZDEzXyB8PSAweDAwMDAwMDgwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTNfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjVfOwogICAgICAgICAgdG9fYml0RmllbGQxM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEzXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxM18gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyN187CiAgICAgICAgICB0b19iaXRGaWVsZDEzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTNfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjhfOwogICAgICAgICAgdG9fYml0RmllbGQxM18gfD0gMHgwMDAwMDgwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEzXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTNfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxM18gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMF87CiAgICAgICAgICB0b19iaXRGaWVsZDEzXyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTNfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzFfOwogICAgICAgICAgdG9fYml0RmllbGQxM18gfD0gMHgwMDAwNDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEzXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxM18gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzM187CiAgICAgICAgICB0b19iaXRGaWVsZDEzXyB8PSAweDAwMDEwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTNfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzRfOwogICAgICAgICAgdG9fYml0RmllbGQxM18gfD0gMHgwMDAyMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEzXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTNfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxM18gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNl87CiAgICAgICAgICB0b19iaXRGaWVsZDEzXyB8PSAweDAwMDgwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTNfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzdfOwogICAgICAgICAgdG9fYml0RmllbGQxM18gfD0gMHgwMDEwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEzXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxM18gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOV87CiAgICAgICAgICB0b19iaXRGaWVsZDEzXyB8PSAweDAwNDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTNfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDBfOwogICAgICAgICAgdG9fYml0RmllbGQxM18gfD0gMHgwMDgwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEzXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTNfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxM18gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDEzXyB8PSAweDAyMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTNfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDNfOwogICAgICAgICAgdG9fYml0RmllbGQxM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEzXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTNfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxM18gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NV87CiAgICAgICAgICB0b19iaXRGaWVsZDEzXyB8PSAweDEwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTNfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDZfOwogICAgICAgICAgdG9fYml0RmllbGQxM18gfD0gMHgyMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDEzXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTNfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxM18gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OF87CiAgICAgICAgICB0b19iaXRGaWVsZDEzXyB8PSAweDgwMDAwMDAwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQxM18gfD0gdG9fYml0RmllbGQxM187CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwxNChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQxNF8gPSBiaXRGaWVsZDE0XzsKICAgICAgICBpbnQgdG9fYml0RmllbGQxNF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OV87CiAgICAgICAgICB0b19iaXRGaWVsZDE0XyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTRfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTBfOwogICAgICAgICAgdG9fYml0RmllbGQxNF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE0XyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTRfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDE0XyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTRfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTNfOwogICAgICAgICAgdG9fYml0RmllbGQxNF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE0XyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTRfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NV87CiAgICAgICAgICB0b19iaXRGaWVsZDE0XyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTRfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTZfOwogICAgICAgICAgdG9fYml0RmllbGQxNF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE0XyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTRfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NThfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OF87CiAgICAgICAgICB0b19iaXRGaWVsZDE0XyB8PSAweDAwMDAwMjAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTRfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTlfOwogICAgICAgICAgdG9fYml0RmllbGQxNF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE0XyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTRfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MV87CiAgICAgICAgICB0b19iaXRGaWVsZDE0XyB8PSAweDAwMDAxMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTRfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjJfOwogICAgICAgICAgdG9fYml0RmllbGQxNF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE0XyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTRfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDE0XyB8PSAweDAwMDA4MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTRfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjVfOwogICAgICAgICAgdG9fYml0RmllbGQxNF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE0XyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTRfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2N187CiAgICAgICAgICB0b19iaXRGaWVsZDE0XyB8PSAweDAwMDQwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTRfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjhfOwogICAgICAgICAgdG9fYml0RmllbGQxNF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE0XyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTRfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MF87CiAgICAgICAgICB0b19iaXRGaWVsZDE0XyB8PSAweDAwMjAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTRfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzFfOwogICAgICAgICAgdG9fYml0RmllbGQxNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE0XyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTRfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3M187CiAgICAgICAgICB0b19iaXRGaWVsZDE0XyB8PSAweDAxMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTRfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzRfOwogICAgICAgICAgdG9fYml0RmllbGQxNF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE0XyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTRfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDE0XyB8PSAweDA4MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTRfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzdfOwogICAgICAgICAgdG9fYml0RmllbGQxNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE0XyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTRfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OV87CiAgICAgICAgICB0b19iaXRGaWVsZDE0XyB8PSAweDQwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTRfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODBfOwogICAgICAgICAgdG9fYml0RmllbGQxNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMTRfIHw9IHRvX2JpdEZpZWxkMTRfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMTUoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMTVfID0gYml0RmllbGQxNV87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMTVfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTVfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODFfOwogICAgICAgICAgdG9fYml0RmllbGQxNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE1XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTVfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNV8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4M187CiAgICAgICAgICB0b19iaXRGaWVsZDE1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTVfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODRfOwogICAgICAgICAgdG9fYml0RmllbGQxNV8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE1XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTVfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNV8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDE1XyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTVfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODdfOwogICAgICAgICAgdG9fYml0RmllbGQxNV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE1XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTVfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNV8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OV87CiAgICAgICAgICB0b19iaXRGaWVsZDE1XyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTVfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTBfOwogICAgICAgICAgdG9fYml0RmllbGQxNV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE1XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTVfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNV8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDE1XyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTVfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTNfOwogICAgICAgICAgdG9fYml0RmllbGQxNV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE1XyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTVfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNV8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NV87CiAgICAgICAgICB0b19iaXRGaWVsZDE1XyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTVfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTZfOwogICAgICAgICAgdG9fYml0RmllbGQxNV8gfD0gMHgwMDAwODAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE1XyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNV8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OThfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OF87CiAgICAgICAgICB0b19iaXRGaWVsZDE1XyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTVfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTlfOwogICAgICAgICAgdG9fYml0RmllbGQxNV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE1XyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNV8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMV87CiAgICAgICAgICB0b19iaXRGaWVsZDE1XyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTVfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDJfOwogICAgICAgICAgdG9fYml0RmllbGQxNV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE1XyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNV8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNF87CiAgICAgICAgICB0b19iaXRGaWVsZDE1XyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTVfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDVfOwogICAgICAgICAgdG9fYml0RmllbGQxNV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE1XyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTVfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNV8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwN187CiAgICAgICAgICB0b19iaXRGaWVsZDE1XyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTVfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDhfOwogICAgICAgICAgdG9fYml0RmllbGQxNV8gfD0gMHgwODAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE1XyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTVfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNV8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMF87CiAgICAgICAgICB0b19iaXRGaWVsZDE1XyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTVfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTExXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTFfOwogICAgICAgICAgdG9fYml0RmllbGQxNV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE1XyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTVfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDE1XyB8PSB0b19iaXRGaWVsZDE1XzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDE2KGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDE2XyA9IGJpdEZpZWxkMTZfOwogICAgICAgIGludCB0b19iaXRGaWVsZDE2XyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE2XyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTZfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNl8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNF87CiAgICAgICAgICB0b19iaXRGaWVsZDE2XyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTZfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTVfOwogICAgICAgICAgdG9fYml0RmllbGQxNl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE2XyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTZfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNl8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxN187CiAgICAgICAgICB0b19iaXRGaWVsZDE2XyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTZfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MThfOwogICAgICAgICAgdG9fYml0RmllbGQxNl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE2XyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTZfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNl8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMF87CiAgICAgICAgICB0b19iaXRGaWVsZDE2XyB8PSAweDAwMDAwMDgwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTZfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjFfOwogICAgICAgICAgdG9fYml0RmllbGQxNl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE2XyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTZfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNl8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyM187CiAgICAgICAgICB0b19iaXRGaWVsZDE2XyB8PSAweDAwMDAwNDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTZfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjRfOwogICAgICAgICAgdG9fYml0RmllbGQxNl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE2XyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTZfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNl8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNl87CiAgICAgICAgICB0b19iaXRGaWVsZDE2XyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTZfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjdfOwogICAgICAgICAgdG9fYml0RmllbGQxNl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE2XyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTZfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNl8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOV87CiAgICAgICAgICB0b19iaXRGaWVsZDE2XyB8PSAweDAwMDEwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTZfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzBfOwogICAgICAgICAgdG9fYml0RmllbGQxNl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE2XyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTZfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNl8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMl87CiAgICAgICAgICB0b19iaXRGaWVsZDE2XyB8PSAweDAwMDgwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTZfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzNfOwogICAgICAgICAgdG9fYml0RmllbGQxNl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE2XyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTZfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNl8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNV87CiAgICAgICAgICB0b19iaXRGaWVsZDE2XyB8PSAweDAwNDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTZfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzZfOwogICAgICAgICAgdG9fYml0RmllbGQxNl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE2XyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzN18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTZfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNl8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOF87CiAgICAgICAgICB0b19iaXRGaWVsZDE2XyB8PSAweDAyMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTZfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzlfOwogICAgICAgICAgdG9fYml0RmllbGQxNl8gfD0gMHgwNDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE2XyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTZfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNl8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MV87CiAgICAgICAgICB0b19iaXRGaWVsZDE2XyB8PSAweDEwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTZfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDJfOwogICAgICAgICAgdG9fYml0RmllbGQxNl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE2XyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTZfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxNl8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NF87CiAgICAgICAgICB0b19iaXRGaWVsZDE2XyB8PSAweDgwMDAwMDAwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQxNl8gfD0gdG9fYml0RmllbGQxNl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwxNyhjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQxN18gPSBiaXRGaWVsZDE3XzsKICAgICAgICBpbnQgdG9fYml0RmllbGQxN18gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxN18gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NV87CiAgICAgICAgICB0b19iaXRGaWVsZDE3XyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTdfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDZfOwogICAgICAgICAgdG9fYml0RmllbGQxN18gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE3XyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTdfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxN18gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OF87CiAgICAgICAgICB0b19iaXRGaWVsZDE3XyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTdfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDlfOwogICAgICAgICAgdG9fYml0RmllbGQxN18gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE3XyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTdfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxN18gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MV87CiAgICAgICAgICB0b19iaXRGaWVsZDE3XyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTdfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTJfOwogICAgICAgICAgdG9fYml0RmllbGQxN18gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE3XyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTdfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxN18gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NF87CiAgICAgICAgICB0b19iaXRGaWVsZDE3XyB8PSAweDAwMDAwMjAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTdfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTVfOwogICAgICAgICAgdG9fYml0RmllbGQxN18gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE3XyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTdfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxN18gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1N187CiAgICAgICAgICB0b19iaXRGaWVsZDE3XyB8PSAweDAwMDAxMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTdfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NThfOwogICAgICAgICAgdG9fYml0RmllbGQxN18gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE3XyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTdfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxN18gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MF87CiAgICAgICAgICB0b19iaXRGaWVsZDE3XyB8PSAweDAwMDA4MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTdfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjFfOwogICAgICAgICAgdG9fYml0RmllbGQxN18gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE3XyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTdfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxN18gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2M187CiAgICAgICAgICB0b19iaXRGaWVsZDE3XyB8PSAweDAwMDQwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTdfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjRfOwogICAgICAgICAgdG9fYml0RmllbGQxN18gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE3XyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTdfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxN18gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDE3XyB8PSAweDAwMjAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTdfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjdfOwogICAgICAgICAgdG9fYml0RmllbGQxN18gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE3XyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTdfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxN18gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OV87CiAgICAgICAgICB0b19iaXRGaWVsZDE3XyB8PSAweDAxMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTdfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzBfOwogICAgICAgICAgdG9fYml0RmllbGQxN18gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE3XyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTdfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxN18gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDE3XyB8PSAweDA4MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTdfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTczXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzNfOwogICAgICAgICAgdG9fYml0RmllbGQxN18gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE3XyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTdfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxN18gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NV87CiAgICAgICAgICB0b19iaXRGaWVsZDE3XyB8PSAweDQwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTdfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzZfOwogICAgICAgICAgdG9fYml0RmllbGQxN18gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMTdfIHw9IHRvX2JpdEZpZWxkMTdfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMTgoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMThfID0gYml0RmllbGQxOF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMThfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMThfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzdfOwogICAgICAgICAgdG9fYml0RmllbGQxOF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE4XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMThfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OV87CiAgICAgICAgICB0b19iaXRGaWVsZDE4XyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMThfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODBfOwogICAgICAgICAgdG9fYml0RmllbGQxOF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE4XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMThfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDE4XyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMThfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODNfOwogICAgICAgICAgdG9fYml0RmllbGQxOF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE4XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMThfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NV87CiAgICAgICAgICB0b19iaXRGaWVsZDE4XyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMThfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODZfOwogICAgICAgICAgdG9fYml0RmllbGQxOF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE4XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMThfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OF87CiAgICAgICAgICB0b19iaXRGaWVsZDE4XyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMThfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODlfOwogICAgICAgICAgdG9fYml0RmllbGQxOF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE4XyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMThfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MV87CiAgICAgICAgICB0b19iaXRGaWVsZDE4XyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMThfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTJfOwogICAgICAgICAgdG9fYml0RmllbGQxOF8gfD0gMHgwMDAwODAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE4XyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMThfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NF87CiAgICAgICAgICB0b19iaXRGaWVsZDE4XyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMThfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTVfOwogICAgICAgICAgdG9fYml0RmllbGQxOF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE4XyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMThfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5N187CiAgICAgICAgICB0b19iaXRGaWVsZDE4XyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMThfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OThfOwogICAgICAgICAgdG9fYml0RmllbGQxOF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE4XyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMThfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMF87CiAgICAgICAgICB0b19iaXRGaWVsZDE4XyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMThfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDFfOwogICAgICAgICAgdG9fYml0RmllbGQxOF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE4XyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMThfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwM187CiAgICAgICAgICB0b19iaXRGaWVsZDE4XyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMThfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDRfOwogICAgICAgICAgdG9fYml0RmllbGQxOF8gfD0gMHgwODAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE4XyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMThfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNl87CiAgICAgICAgICB0b19iaXRGaWVsZDE4XyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMThfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDdfOwogICAgICAgICAgdG9fYml0RmllbGQxOF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE4XyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMThfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDE4XyB8PSB0b19iaXRGaWVsZDE4XzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDE5KGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDE5XyA9IGJpdEZpZWxkMTlfOwogICAgICAgIGludCB0b19iaXRGaWVsZDE5XyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE5XyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTlfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMF87CiAgICAgICAgICB0b19iaXRGaWVsZDE5XyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTlfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjExXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTFfOwogICAgICAgICAgdG9fYml0RmllbGQxOV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE5XyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTlfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOV8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxM187CiAgICAgICAgICB0b19iaXRGaWVsZDE5XyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTlfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTRfOwogICAgICAgICAgdG9fYml0RmllbGQxOV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE5XyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTlfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOV8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNl87CiAgICAgICAgICB0b19iaXRGaWVsZDE5XyB8PSAweDAwMDAwMDgwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTlfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTdfOwogICAgICAgICAgdG9fYml0RmllbGQxOV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE5XyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTlfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOV8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOV87CiAgICAgICAgICB0b19iaXRGaWVsZDE5XyB8PSAweDAwMDAwNDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTlfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjBfOwogICAgICAgICAgdG9fYml0RmllbGQxOV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE5XyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTlfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOV8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMl87CiAgICAgICAgICB0b19iaXRGaWVsZDE5XyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTlfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjNfOwogICAgICAgICAgdG9fYml0RmllbGQxOV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE5XyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTlfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOV8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNV87CiAgICAgICAgICB0b19iaXRGaWVsZDE5XyB8PSAweDAwMDEwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTlfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjZfOwogICAgICAgICAgdG9fYml0RmllbGQxOV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE5XyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyN18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTlfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOV8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOF87CiAgICAgICAgICB0b19iaXRGaWVsZDE5XyB8PSAweDAwMDgwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTlfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjlfOwogICAgICAgICAgdG9fYml0RmllbGQxOV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE5XyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTlfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOV8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMV87CiAgICAgICAgICB0b19iaXRGaWVsZDE5XyB8PSAweDAwNDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTlfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzJfOwogICAgICAgICAgdG9fYml0RmllbGQxOV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE5XyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTlfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOV8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNF87CiAgICAgICAgICB0b19iaXRGaWVsZDE5XyB8PSAweDAyMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTlfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzVfOwogICAgICAgICAgdG9fYml0RmllbGQxOV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE5XyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTlfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOV8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzN187CiAgICAgICAgICB0b19iaXRGaWVsZDE5XyB8PSAweDEwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMTlfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzhfOwogICAgICAgICAgdG9fYml0RmllbGQxOV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDE5XyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMTlfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxOV8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MF87CiAgICAgICAgICB0b19iaXRGaWVsZDE5XyB8PSAweDgwMDAwMDAwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQxOV8gfD0gdG9fYml0RmllbGQxOV87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwyMChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQyMF8gPSBiaXRGaWVsZDIwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQyMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MV87CiAgICAgICAgICB0b19iaXRGaWVsZDIwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDJfOwogICAgICAgICAgdG9fYml0RmllbGQyMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NF87CiAgICAgICAgICB0b19iaXRGaWVsZDIwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDVfOwogICAgICAgICAgdG9fYml0RmllbGQyMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0N187CiAgICAgICAgICB0b19iaXRGaWVsZDIwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDhfOwogICAgICAgICAgdG9fYml0RmllbGQyMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MF87CiAgICAgICAgICB0b19iaXRGaWVsZDIwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTFfOwogICAgICAgICAgdG9fYml0RmllbGQyMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1M187CiAgICAgICAgICB0b19iaXRGaWVsZDIwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTRfOwogICAgICAgICAgdG9fYml0RmllbGQyMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDIwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTdfOwogICAgICAgICAgdG9fYml0RmllbGQyMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OV87CiAgICAgICAgICB0b19iaXRGaWVsZDIwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjBfOwogICAgICAgICAgdG9fYml0RmllbGQyMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDIwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjBfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjNfOwogICAgICAgICAgdG9fYml0RmllbGQyMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NV87CiAgICAgICAgICB0b19iaXRGaWVsZDIwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjZfOwogICAgICAgICAgdG9fYml0RmllbGQyMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OF87CiAgICAgICAgICB0b19iaXRGaWVsZDIwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjlfOwogICAgICAgICAgdG9fYml0RmllbGQyMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MV87CiAgICAgICAgICB0b19iaXRGaWVsZDIwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjBfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzJfOwogICAgICAgICAgdG9fYml0RmllbGQyMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMjBfIHw9IHRvX2JpdEZpZWxkMjBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMjEoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMjFfID0gYml0RmllbGQyMV87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMjFfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjFfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjczXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzNfOwogICAgICAgICAgdG9fYml0RmllbGQyMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIxXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMV8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NV87CiAgICAgICAgICB0b19iaXRGaWVsZDIxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjFfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzZfOwogICAgICAgICAgdG9fYml0RmllbGQyMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIxXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMV8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OF87CiAgICAgICAgICB0b19iaXRGaWVsZDIxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjFfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzlfOwogICAgICAgICAgdG9fYml0RmllbGQyMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIxXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMV8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MV87CiAgICAgICAgICB0b19iaXRGaWVsZDIxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjFfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODJfOwogICAgICAgICAgdG9fYml0RmllbGQyMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIxXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMV8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NF87CiAgICAgICAgICB0b19iaXRGaWVsZDIxXyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjFfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODVfOwogICAgICAgICAgdG9fYml0RmllbGQyMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIxXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMV8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4N187CiAgICAgICAgICB0b19iaXRGaWVsZDIxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjFfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODhfOwogICAgICAgICAgdG9fYml0RmllbGQyMV8gfD0gMHgwMDAwODAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIxXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMV8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MF87CiAgICAgICAgICB0b19iaXRGaWVsZDIxXyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjFfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTFfOwogICAgICAgICAgdG9fYml0RmllbGQyMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIxXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjFfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMV8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5M187CiAgICAgICAgICB0b19iaXRGaWVsZDIxXyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjFfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTRfOwogICAgICAgICAgdG9fYml0RmllbGQyMV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIxXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMV8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDIxXyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjFfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTdfOwogICAgICAgICAgdG9fYml0RmllbGQyMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIxXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMV8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OV87CiAgICAgICAgICB0b19iaXRGaWVsZDIxXyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjFfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDBfOwogICAgICAgICAgdG9fYml0RmllbGQyMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIxXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjFfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMV8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMl87CiAgICAgICAgICB0b19iaXRGaWVsZDIxXyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjFfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDNfOwogICAgICAgICAgdG9fYml0RmllbGQyMV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIxXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDIxXyB8PSB0b19iaXRGaWVsZDIxXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDIyKGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDIyXyA9IGJpdEZpZWxkMjJfOwogICAgICAgIGludCB0b19iaXRGaWVsZDIyXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIyXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjJfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMl8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNl87CiAgICAgICAgICB0b19iaXRGaWVsZDIyXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjJfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDdfOwogICAgICAgICAgdG9fYml0RmllbGQyMl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIyXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMl8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOV87CiAgICAgICAgICB0b19iaXRGaWVsZDIyXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjJfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTBfOwogICAgICAgICAgdG9fYml0RmllbGQyMl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIyXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzExXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMl8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMl87CiAgICAgICAgICB0b19iaXRGaWVsZDIyXyB8PSAweDAwMDAwMDgwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjJfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTNfOwogICAgICAgICAgdG9fYml0RmllbGQyMl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIyXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMl8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNV87CiAgICAgICAgICB0b19iaXRGaWVsZDIyXyB8PSAweDAwMDAwNDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjJfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTZfOwogICAgICAgICAgdG9fYml0RmllbGQyMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIyXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxN18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMl8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MThfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOF87CiAgICAgICAgICB0b19iaXRGaWVsZDIyXyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjJfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTlfOwogICAgICAgICAgdG9fYml0RmllbGQyMl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIyXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMl8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMV87CiAgICAgICAgICB0b19iaXRGaWVsZDIyXyB8PSAweDAwMDEwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjJfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjJfOwogICAgICAgICAgdG9fYml0RmllbGQyMl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIyXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjJfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMl8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNF87CiAgICAgICAgICB0b19iaXRGaWVsZDIyXyB8PSAweDAwMDgwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjJfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjVfOwogICAgICAgICAgdG9fYml0RmllbGQyMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIyXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjJfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMl8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyN187CiAgICAgICAgICB0b19iaXRGaWVsZDIyXyB8PSAweDAwNDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjJfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjhfOwogICAgICAgICAgdG9fYml0RmllbGQyMl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIyXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMl8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMF87CiAgICAgICAgICB0b19iaXRGaWVsZDIyXyB8PSAweDAyMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjJfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzFfOwogICAgICAgICAgdG9fYml0RmllbGQyMl8gfD0gMHgwNDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIyXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjJfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMl8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczM187CiAgICAgICAgICB0b19iaXRGaWVsZDIyXyB8PSAweDEwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjJfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzRfOwogICAgICAgICAgdG9fYml0RmllbGQyMl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIyXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyMl8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNl87CiAgICAgICAgICB0b19iaXRGaWVsZDIyXyB8PSAweDgwMDAwMDAwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQyMl8gfD0gdG9fYml0RmllbGQyMl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwyMyhjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQyM18gPSBiaXRGaWVsZDIzXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQyM18gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyM18gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczN187CiAgICAgICAgICB0b19iaXRGaWVsZDIzXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjNfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzhfOwogICAgICAgICAgdG9fYml0RmllbGQyM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIzXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjNfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyM18gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MF87CiAgICAgICAgICB0b19iaXRGaWVsZDIzXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjNfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDFfOwogICAgICAgICAgdG9fYml0RmllbGQyM18gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIzXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjNfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyM18gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0M187CiAgICAgICAgICB0b19iaXRGaWVsZDIzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjNfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDRfOwogICAgICAgICAgdG9fYml0RmllbGQyM18gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIzXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjNfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyM18gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDIzXyB8PSAweDAwMDAwMjAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjNfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDdfOwogICAgICAgICAgdG9fYml0RmllbGQyM18gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIzXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjNfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyM18gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OV87CiAgICAgICAgICB0b19iaXRGaWVsZDIzXyB8PSAweDAwMDAxMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjNfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTBfOwogICAgICAgICAgdG9fYml0RmllbGQyM18gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIzXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjNfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyM18gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDIzXyB8PSAweDAwMDA4MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjNfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTNfOwogICAgICAgICAgdG9fYml0RmllbGQyM18gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIzXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjNfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyM18gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NV87CiAgICAgICAgICB0b19iaXRGaWVsZDIzXyB8PSAweDAwMDQwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjNfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTZfOwogICAgICAgICAgdG9fYml0RmllbGQyM18gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIzXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjNfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyM18gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NThfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OF87CiAgICAgICAgICB0b19iaXRGaWVsZDIzXyB8PSAweDAwMjAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjNfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTlfOwogICAgICAgICAgdG9fYml0RmllbGQyM18gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIzXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjNfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyM18gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MV87CiAgICAgICAgICB0b19iaXRGaWVsZDIzXyB8PSAweDAxMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjNfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjJfOwogICAgICAgICAgdG9fYml0RmllbGQyM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIzXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjNfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyM18gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDIzXyB8PSAweDA4MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjNfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjVfOwogICAgICAgICAgdG9fYml0RmllbGQyM18gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDIzXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjNfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyM18gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2N187CiAgICAgICAgICB0b19iaXRGaWVsZDIzXyB8PSAweDQwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjNfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjhfOwogICAgICAgICAgdG9fYml0RmllbGQyM18gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMjNfIHw9IHRvX2JpdEZpZWxkMjNfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMjQoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMjRfID0gYml0RmllbGQyNF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMjRfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjRfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjlfOwogICAgICAgICAgdG9fYml0RmllbGQyNF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI0XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjRfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MV87CiAgICAgICAgICB0b19iaXRGaWVsZDI0XyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjRfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzJfOwogICAgICAgICAgdG9fYml0RmllbGQyNF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI0XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzczXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjRfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NF87CiAgICAgICAgICB0b19iaXRGaWVsZDI0XyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjRfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzVfOwogICAgICAgICAgdG9fYml0RmllbGQyNF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI0XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjRfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3N187CiAgICAgICAgICB0b19iaXRGaWVsZDI0XyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjRfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzhfOwogICAgICAgICAgdG9fYml0RmllbGQyNF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI0XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjRfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MF87CiAgICAgICAgICB0b19iaXRGaWVsZDI0XyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjRfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODFfOwogICAgICAgICAgdG9fYml0RmllbGQyNF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI0XyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjRfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4M187CiAgICAgICAgICB0b19iaXRGaWVsZDI0XyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjRfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODRfOwogICAgICAgICAgdG9fYml0RmllbGQyNF8gfD0gMHgwMDAwODAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI0XyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjRfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDI0XyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjRfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODdfOwogICAgICAgICAgdG9fYml0RmllbGQyNF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI0XyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjRfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OV87CiAgICAgICAgICB0b19iaXRGaWVsZDI0XyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjRfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTBfOwogICAgICAgICAgdG9fYml0RmllbGQyNF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI0XyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjRfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDI0XyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjRfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTNfOwogICAgICAgICAgdG9fYml0RmllbGQyNF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI0XyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjRfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NV87CiAgICAgICAgICB0b19iaXRGaWVsZDI0XyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjRfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTZfOwogICAgICAgICAgdG9fYml0RmllbGQyNF8gfD0gMHgwODAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI0XyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjRfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OThfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OF87CiAgICAgICAgICB0b19iaXRGaWVsZDI0XyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjRfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTlfOwogICAgICAgICAgdG9fYml0RmllbGQyNF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI0XyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjRfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDI0XyB8PSB0b19iaXRGaWVsZDI0XzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDI1KGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDI1XyA9IGJpdEZpZWxkMjVfOwogICAgICAgIGludCB0b19iaXRGaWVsZDI1XyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI1XyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjVfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMl87CiAgICAgICAgICB0b19iaXRGaWVsZDI1XyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjVfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDNfOwogICAgICAgICAgdG9fYml0RmllbGQyNV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI1XyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNV8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNV87CiAgICAgICAgICB0b19iaXRGaWVsZDI1XyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjVfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDZfOwogICAgICAgICAgdG9fYml0RmllbGQyNV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI1XyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwN18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjVfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNV8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOF87CiAgICAgICAgICB0b19iaXRGaWVsZDI1XyB8PSAweDAwMDAwMDgwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjVfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDlfOwogICAgICAgICAgdG9fYml0RmllbGQyNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI1XyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjVfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNV8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMV87CiAgICAgICAgICB0b19iaXRGaWVsZDI1XyB8PSAweDAwMDAwNDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjVfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTJfOwogICAgICAgICAgdG9fYml0RmllbGQyNV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI1XyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjVfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNV8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNF87CiAgICAgICAgICB0b19iaXRGaWVsZDI1XyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjVfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTVfOwogICAgICAgICAgdG9fYml0RmllbGQyNV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI1XyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjVfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNV8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxN187CiAgICAgICAgICB0b19iaXRGaWVsZDI1XyB8PSAweDAwMDEwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjVfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MThfOwogICAgICAgICAgdG9fYml0RmllbGQyNV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI1XyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjVfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNV8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMF87CiAgICAgICAgICB0b19iaXRGaWVsZDI1XyB8PSAweDAwMDgwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjVfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjFfOwogICAgICAgICAgdG9fYml0RmllbGQyNV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI1XyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjVfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNV8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyM187CiAgICAgICAgICB0b19iaXRGaWVsZDI1XyB8PSAweDAwNDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjVfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjRfOwogICAgICAgICAgdG9fYml0RmllbGQyNV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI1XyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjVfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNV8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNl87CiAgICAgICAgICB0b19iaXRGaWVsZDI1XyB8PSAweDAyMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjVfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjdfOwogICAgICAgICAgdG9fYml0RmllbGQyNV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI1XyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjVfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNV8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOV87CiAgICAgICAgICB0b19iaXRGaWVsZDI1XyB8PSAweDEwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjVfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzBfOwogICAgICAgICAgdG9fYml0RmllbGQyNV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI1XyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjVfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNV8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMl87CiAgICAgICAgICB0b19iaXRGaWVsZDI1XyB8PSAweDgwMDAwMDAwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQyNV8gfD0gdG9fYml0RmllbGQyNV87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwyNihjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQyNl8gPSBiaXRGaWVsZDI2XzsKICAgICAgICBpbnQgdG9fYml0RmllbGQyNl8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNl8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzM187CiAgICAgICAgICB0b19iaXRGaWVsZDI2XyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjZfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzRfOwogICAgICAgICAgdG9fYml0RmllbGQyNl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI2XyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNl8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNl87CiAgICAgICAgICB0b19iaXRGaWVsZDI2XyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjZfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzdfOwogICAgICAgICAgdG9fYml0RmllbGQyNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI2XyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjZfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNl8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOV87CiAgICAgICAgICB0b19iaXRGaWVsZDI2XyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjZfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDBfOwogICAgICAgICAgdG9fYml0RmllbGQyNl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI2XyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjZfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNl8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDI2XyB8PSAweDAwMDAwMjAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjZfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDNfOwogICAgICAgICAgdG9fYml0RmllbGQyNl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI2XyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjZfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNl8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NV87CiAgICAgICAgICB0b19iaXRGaWVsZDI2XyB8PSAweDAwMDAxMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjZfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDZfOwogICAgICAgICAgdG9fYml0RmllbGQyNl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI2XyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjZfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNl8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OF87CiAgICAgICAgICB0b19iaXRGaWVsZDI2XyB8PSAweDAwMDA4MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjZfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDlfOwogICAgICAgICAgdG9fYml0RmllbGQyNl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI2XyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjZfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNl8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MV87CiAgICAgICAgICB0b19iaXRGaWVsZDI2XyB8PSAweDAwMDQwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjZfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTJfOwogICAgICAgICAgdG9fYml0RmllbGQyNl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI2XyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjZfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNl8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NF87CiAgICAgICAgICB0b19iaXRGaWVsZDI2XyB8PSAweDAwMjAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjZfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTVfOwogICAgICAgICAgdG9fYml0RmllbGQyNl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI2XyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjZfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNl8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1N187CiAgICAgICAgICB0b19iaXRGaWVsZDI2XyB8PSAweDAxMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjZfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NThfOwogICAgICAgICAgdG9fYml0RmllbGQyNl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI2XyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjZfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNl8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MF87CiAgICAgICAgICB0b19iaXRGaWVsZDI2XyB8PSAweDA4MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjZfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjFfOwogICAgICAgICAgdG9fYml0RmllbGQyNl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI2XyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjZfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyNl8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2M187CiAgICAgICAgICB0b19iaXRGaWVsZDI2XyB8PSAweDQwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjZfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjRfOwogICAgICAgICAgdG9fYml0RmllbGQyNl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMjZfIHw9IHRvX2JpdEZpZWxkMjZfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMjcoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMjdfID0gYml0RmllbGQyN187CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMjdfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjdfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjVfOwogICAgICAgICAgdG9fYml0RmllbGQyN18gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI3XyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjdfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyN18gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2N187CiAgICAgICAgICB0b19iaXRGaWVsZDI3XyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjdfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjhfOwogICAgICAgICAgdG9fYml0RmllbGQyN18gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI3XyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjdfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyN18gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MF87CiAgICAgICAgICB0b19iaXRGaWVsZDI3XyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjdfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzFfOwogICAgICAgICAgdG9fYml0RmllbGQyN18gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI3XyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjdfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyN18gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3M187CiAgICAgICAgICB0b19iaXRGaWVsZDI3XyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjdfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzRfOwogICAgICAgICAgdG9fYml0RmllbGQyN18gfD0gMHgwMDAwMDIwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI3XyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjdfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyN18gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDI3XyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjdfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzdfOwogICAgICAgICAgdG9fYml0RmllbGQyN18gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI3XyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjdfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyN18gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OV87CiAgICAgICAgICB0b19iaXRGaWVsZDI3XyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjdfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODBfOwogICAgICAgICAgdG9fYml0RmllbGQyN18gfD0gMHgwMDAwODAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI3XyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjdfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyN18gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDI3XyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjdfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODNfOwogICAgICAgICAgdG9fYml0RmllbGQyN18gfD0gMHgwMDA0MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI3XyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjdfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyN18gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NV87CiAgICAgICAgICB0b19iaXRGaWVsZDI3XyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjdfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODZfOwogICAgICAgICAgdG9fYml0RmllbGQyN18gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI3XyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjdfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyN18gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OF87CiAgICAgICAgICB0b19iaXRGaWVsZDI3XyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjdfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODlfOwogICAgICAgICAgdG9fYml0RmllbGQyN18gfD0gMHgwMTAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI3XyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjdfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyN18gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MV87CiAgICAgICAgICB0b19iaXRGaWVsZDI3XyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjdfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTJfOwogICAgICAgICAgdG9fYml0RmllbGQyN18gfD0gMHgwODAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI3XyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjdfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyN18gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NF87CiAgICAgICAgICB0b19iaXRGaWVsZDI3XyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjdfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTVfOwogICAgICAgICAgdG9fYml0RmllbGQyN18gfD0gMHg0MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI3XyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjdfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDI3XyB8PSB0b19iaXRGaWVsZDI3XzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDI4KGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDI4XyA9IGJpdEZpZWxkMjhfOwogICAgICAgIGludCB0b19iaXRGaWVsZDI4XyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI4XyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjhfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OThfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OF87CiAgICAgICAgICB0b19iaXRGaWVsZDI4XyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjhfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTlfOwogICAgICAgICAgdG9fYml0RmllbGQyOF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI4XyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjhfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMV87CiAgICAgICAgICB0b19iaXRGaWVsZDI4XyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjhfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDJfOwogICAgICAgICAgdG9fYml0RmllbGQyOF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI4XyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwM18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjhfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNF87CiAgICAgICAgICB0b19iaXRGaWVsZDI4XyB8PSAweDAwMDAwMDgwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjhfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDVfOwogICAgICAgICAgdG9fYml0RmllbGQyOF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI4XyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjhfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwN187CiAgICAgICAgICB0b19iaXRGaWVsZDI4XyB8PSAweDAwMDAwNDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjhfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDhfOwogICAgICAgICAgdG9fYml0RmllbGQyOF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI4XyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjhfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMF87CiAgICAgICAgICB0b19iaXRGaWVsZDI4XyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjhfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTExXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTFfOwogICAgICAgICAgdG9fYml0RmllbGQyOF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI4XyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjhfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxM187CiAgICAgICAgICB0b19iaXRGaWVsZDI4XyB8PSAweDAwMDEwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjhfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTRfOwogICAgICAgICAgdG9fYml0RmllbGQyOF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI4XyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjhfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNl87CiAgICAgICAgICB0b19iaXRGaWVsZDI4XyB8PSAweDAwMDgwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjhfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTdfOwogICAgICAgICAgdG9fYml0RmllbGQyOF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI4XyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjhfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOV87CiAgICAgICAgICB0b19iaXRGaWVsZDI4XyB8PSAweDAwNDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjhfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjBfOwogICAgICAgICAgdG9fYml0RmllbGQyOF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI4XyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjhfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMl87CiAgICAgICAgICB0b19iaXRGaWVsZDI4XyB8PSAweDAyMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjhfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjNfOwogICAgICAgICAgdG9fYml0RmllbGQyOF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI4XyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjhfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOF8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNV87CiAgICAgICAgICB0b19iaXRGaWVsZDI4XyB8PSAweDEwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjhfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjZfOwogICAgICAgICAgdG9fYml0RmllbGQyOF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI4XyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyN18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjhfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOF87CiAgICAgICAgICB0b19iaXRGaWVsZDI4XyB8PSAweDgwMDAwMDAwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQyOF8gfD0gdG9fYml0RmllbGQyOF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwyOShjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQyOV8gPSBiaXRGaWVsZDI5XzsKICAgICAgICBpbnQgdG9fYml0RmllbGQyOV8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOV8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOV87CiAgICAgICAgICB0b19iaXRGaWVsZDI5XyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjlfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzBfOwogICAgICAgICAgdG9fYml0RmllbGQyOV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI5XyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjlfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOV8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMl87CiAgICAgICAgICB0b19iaXRGaWVsZDI5XyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjlfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMzXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzNfOwogICAgICAgICAgdG9fYml0RmllbGQyOV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI5XyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjlfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOV8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNV87CiAgICAgICAgICB0b19iaXRGaWVsZDI5XyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjlfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzZfOwogICAgICAgICAgdG9fYml0RmllbGQyOV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI5XyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzN18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjlfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOV8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOF87CiAgICAgICAgICB0b19iaXRGaWVsZDI5XyB8PSAweDAwMDAwMjAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjlfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzlfOwogICAgICAgICAgdG9fYml0RmllbGQyOV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI5XyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjlfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MV87CiAgICAgICAgICB0b19iaXRGaWVsZDI5XyB8PSAweDAwMDAxMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjlfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDJfOwogICAgICAgICAgdG9fYml0RmllbGQyOV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI5XyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjlfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOV8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NF87CiAgICAgICAgICB0b19iaXRGaWVsZDI5XyB8PSAweDAwMDA4MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjlfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDVfOwogICAgICAgICAgdG9fYml0RmllbGQyOV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI5XyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjlfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOV8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0N187CiAgICAgICAgICB0b19iaXRGaWVsZDI5XyB8PSAweDAwMDQwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjlfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDhfOwogICAgICAgICAgdG9fYml0RmllbGQyOV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI5XyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjlfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOV8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MF87CiAgICAgICAgICB0b19iaXRGaWVsZDI5XyB8PSAweDAwMjAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjlfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTFfOwogICAgICAgICAgdG9fYml0RmllbGQyOV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI5XyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjlfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOV8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1M187CiAgICAgICAgICB0b19iaXRGaWVsZDI5XyB8PSAweDAxMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjlfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTRfOwogICAgICAgICAgdG9fYml0RmllbGQyOV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI5XyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjlfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOV8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDI5XyB8PSAweDA4MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjlfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTdfOwogICAgICAgICAgdG9fYml0RmllbGQyOV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDI5XyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMjlfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyOV8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OV87CiAgICAgICAgICB0b19iaXRGaWVsZDI5XyB8PSAweDQwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMjlfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjBfOwogICAgICAgICAgdG9fYml0RmllbGQyOV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMjlfIHw9IHRvX2JpdEZpZWxkMjlfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMzAoY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMzBfID0gYml0RmllbGQzMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMzBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMzBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjFfOwogICAgICAgICAgdG9fYml0RmllbGQzMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjNfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2M187CiAgICAgICAgICB0b19iaXRGaWVsZDMwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMzBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY0XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjRfOwogICAgICAgICAgdG9fYml0RmllbGQzMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjZfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDMwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMzBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY3XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjdfOwogICAgICAgICAgdG9fYml0RmllbGQzMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjlfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OV87CiAgICAgICAgICB0b19iaXRGaWVsZDMwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMzBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzBfOwogICAgICAgICAgdG9fYml0RmllbGQzMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzJfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDMwXyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMzBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTczXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzNfOwogICAgICAgICAgdG9fYml0RmllbGQzMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzVfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NV87CiAgICAgICAgICB0b19iaXRGaWVsZDMwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMzBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc2XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzZfOwogICAgICAgICAgdG9fYml0RmllbGQzMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMwXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3N18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc3XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzhfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OF87CiAgICAgICAgICB0b19iaXRGaWVsZDMwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMzBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc5XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzlfOwogICAgICAgICAgdG9fYml0RmllbGQzMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMwXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MF8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODFfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MV87CiAgICAgICAgICB0b19iaXRGaWVsZDMwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMzBfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgyXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODJfOwogICAgICAgICAgdG9fYml0RmllbGQzMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMwXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzMF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NF87CiAgICAgICAgICB0b19iaXRGaWVsZDMwXyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMzBfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODVfOwogICAgICAgICAgdG9fYml0RmllbGQzMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMwXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4N187CiAgICAgICAgICB0b19iaXRGaWVsZDMwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMzBfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODhfOwogICAgICAgICAgdG9fYml0RmllbGQzMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMwXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzMF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTBfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MF87CiAgICAgICAgICB0b19iaXRGaWVsZDMwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMzBfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkxXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTFfOwogICAgICAgICAgdG9fYml0RmllbGQzMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMwXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Ml8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDMwXyB8PSB0b19iaXRGaWVsZDMwXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDMxKGNvbS5nb29nbGUucHJvdG9idWYuVW5pdHRlc3RFbm9ybW91c0Rlc2NyaXB0b3IuVGVzdEVub3Jtb3VzRGVzY3JpcHRvciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDMxXyA9IGJpdEZpZWxkMzFfOwogICAgICAgIGludCB0b19iaXRGaWVsZDMxXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMxXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5M18gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzMV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTRfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NF87CiAgICAgICAgICB0b19iaXRGaWVsZDMxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMzFfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk1XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTVfOwogICAgICAgICAgdG9fYml0RmllbGQzMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMxXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Nl8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzMV8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTdfID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5N187CiAgICAgICAgICB0b19iaXRGaWVsZDMxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMzFfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk4XyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OThfOwogICAgICAgICAgdG9fYml0RmllbGQzMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDMxXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OV8gPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQzMV8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwXyA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMzFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDMxXyB8PSB0b19iaXRGaWVsZDMxXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMV87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMl87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkM187CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkNF87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkNV87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkNl87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkN187CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkOF87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkOV87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMTBfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDExXzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQxMl87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMTNfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDE0XzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQxNV87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMTZfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDE3XzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQxOF87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMTlfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDIwXzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQyMV87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMjJfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDIzXzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQyNF87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMjVfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDI2XzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQyN187CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMjhfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDI5XzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQzMF87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMzFfOwoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xID0gMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEgPSAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEgPSAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xID0gMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xID0gMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMSA9IDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMiA9IDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yID0gMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yID0gMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMiA9IDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMiA9IDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIgPSAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMgPSAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMyA9IDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMyA9IDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMgPSAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMgPSAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zID0gMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ID0gNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQgPSA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQgPSA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ID0gNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ID0gNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNCA9IDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNSA9IDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ID0gNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ID0gNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNSA9IDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNSA9IDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNSgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUgPSA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYgPSA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNiA9IDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNiA9IDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYgPSA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYgPSA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ID0gNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ID0gNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcgPSA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcgPSA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nN187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ID0gNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ID0gNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNyA9IDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nN0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOCA9IDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ID0gOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ID0gOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOCA9IDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOCA9IDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzggPSA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkgPSA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOSA9IDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOSA9IDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkgPSA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkgPSA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ID0gOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAgPSAxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAgPSAxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAgPSAxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwID0gMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAgPSAxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAgPSAxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEgPSAxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEgPSAxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEgPSAxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExID0gMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEgPSAxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEgPSAxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIgPSAxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIgPSAxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIgPSAxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyID0gMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIgPSAxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIgPSAxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMgPSAxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMgPSAxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMgPSAxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzID0gMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMgPSAxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMgPSAxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQgPSAxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQgPSAxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQgPSAxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0ID0gMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQgPSAxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQgPSAxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUgPSAxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUgPSAxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUgPSAxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1ID0gMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUgPSAxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUgPSAxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYgPSAxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYgPSAxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYgPSAxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2ID0gMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYgPSAxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYgPSAxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcgPSAxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcgPSAxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcgPSAxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3ID0gMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcgPSAxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcgPSAxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTggPSAxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTggPSAxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMThfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTggPSAxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMThfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMThfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4ID0gMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTggPSAxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMThfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTggPSAxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMThCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkgPSAxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkgPSAxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkgPSAxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5ID0gMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkgPSAxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkgPSAxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAgPSAyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAgPSAyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAgPSAyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwID0gMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAgPSAyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAgPSAyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEgPSAyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEgPSAyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEgPSAyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxID0gMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEgPSAyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEgPSAyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIgPSAyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIgPSAyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIgPSAyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyID0gMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIgPSAyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIgPSAyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMgPSAyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMgPSAyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMgPSAyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzID0gMjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMgPSAyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMgPSAyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQgPSAyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQgPSAyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQgPSAyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0ID0gMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQgPSAyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQgPSAyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUgPSAyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUgPSAyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUgPSAyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1ID0gMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUgPSAyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUgPSAyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYgPSAyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYgPSAyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYgPSAyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2ID0gMjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYgPSAyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYgPSAyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcgPSAyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcgPSAyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcgPSAyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3ID0gMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcgPSAyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcgPSAyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjggPSAyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjggPSAyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjggPSAyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4ID0gMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjggPSAyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjggPSAyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkgPSAyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkgPSAyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkgPSAyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5ID0gMjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkgPSAyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkgPSAyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAgPSAzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAgPSAzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAgPSAzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwID0gMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAgPSAzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAgPSAzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEgPSAzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEgPSAzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEgPSAzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxID0gMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEgPSAzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEgPSAzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIgPSAzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIgPSAzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIgPSAzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyID0gMzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIgPSAzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIgPSAzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMgPSAzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMgPSAzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMgPSAzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzID0gMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMgPSAzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMgPSAzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQgPSAzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQgPSAzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQgPSAzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0ID0gMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQgPSAzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQgPSAzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUgPSAzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUgPSAzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUgPSAzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1ID0gMzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUgPSAzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUgPSAzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYgPSAzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYgPSAzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYgPSAzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2ID0gMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYgPSAzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYgPSAzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcgPSAzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcgPSAzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcgPSAzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3ID0gMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcgPSAzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcgPSAzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzggPSAzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzggPSAzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzggPSAzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4ID0gMzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzggPSAzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzggPSAzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkgPSAzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkgPSAzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkgPSAzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5ID0gMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkgPSAzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkgPSAzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAgPSA0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAgPSA0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAgPSA0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwID0gNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAgPSA0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAgPSA0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEgPSA0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEgPSA0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEgPSA0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxID0gNDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEgPSA0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEgPSA0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIgPSA0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIgPSA0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIgPSA0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyID0gNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIgPSA0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIgPSA0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMgPSA0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMgPSA0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMgPSA0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzID0gNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMgPSA0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMgPSA0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQgPSA0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQgPSA0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQgPSA0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0ID0gNDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQgPSA0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQgPSA0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUgPSA0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUgPSA0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUgPSA0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1ID0gNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUgPSA0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUgPSA0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYgPSA0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYgPSA0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYgPSA0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2ID0gNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYgPSA0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYgPSA0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcgPSA0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcgPSA0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcgPSA0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3ID0gNDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcgPSA0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcgPSA0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDggPSA0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDggPSA0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDggPSA0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4ID0gNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDggPSA0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDggPSA0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkgPSA0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkgPSA0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkgPSA0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5ID0gNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkgPSA0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkgPSA0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAgPSA1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAgPSA1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAgPSA1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwID0gNTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAgPSA1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAgPSA1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEgPSA1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEgPSA1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEgPSA1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxID0gNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEgPSA1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEgPSA1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIgPSA1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIgPSA1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIgPSA1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyID0gNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIgPSA1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIgPSA1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMgPSA1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMgPSA1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMgPSA1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzID0gNTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMgPSA1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMgPSA1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQgPSA1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQgPSA1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQgPSA1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0ID0gNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQgPSA1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQgPSA1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUgPSA1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUgPSA1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUgPSA1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1ID0gNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUgPSA1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUgPSA1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYgPSA1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYgPSA1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYgPSA1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2ID0gNTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYgPSA1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYgPSA1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcgPSA1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcgPSA1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcgPSA1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3ID0gNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcgPSA1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcgPSA1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTggPSA1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTggPSA1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNThfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTggPSA1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNThfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNThfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4ID0gNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTggPSA1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNThfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTggPSA1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNThCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkgPSA1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkgPSA1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkgPSA1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5ID0gNTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkgPSA1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkgPSA1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAgPSA2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAgPSA2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAgPSA2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwID0gNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAgPSA2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAgPSA2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEgPSA2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEgPSA2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEgPSA2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxID0gNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEgPSA2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEgPSA2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIgPSA2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIgPSA2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIgPSA2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyID0gNjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIgPSA2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIgPSA2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMgPSA2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMgPSA2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMgPSA2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzID0gNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMgPSA2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMgPSA2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQgPSA2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQgPSA2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQgPSA2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0ID0gNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQgPSA2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQgPSA2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUgPSA2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUgPSA2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUgPSA2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1ID0gNjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUgPSA2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUgPSA2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYgPSA2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYgPSA2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYgPSA2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2ID0gNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYgPSA2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYgPSA2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcgPSA2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcgPSA2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcgPSA2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3ID0gNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcgPSA2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcgPSA2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjggPSA2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjggPSA2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjggPSA2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4ID0gNjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjggPSA2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjggPSA2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkgPSA2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkgPSA2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkgPSA2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5ID0gNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkgPSA2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkgPSA2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAgPSA3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAgPSA3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAgPSA3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwID0gNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAgPSA3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwKCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAgPSA3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEgPSA3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEgPSA3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEgPSA3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxID0gNzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEgPSA3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxKCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEgPSA3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIgPSA3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIgPSA3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIgPSA3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyID0gNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIgPSA3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyKCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIgPSA3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMgPSA3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMgPSA3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMgPSA3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczID0gNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMgPSA3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczKCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMgPSA3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQgPSA3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQgPSA3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQgPSA3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0ID0gNzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQgPSA3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQgPSA3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUgPSA3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUgPSA3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUgPSA3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1ID0gNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUgPSA3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUgPSA3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYgPSA3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYgPSA3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYgPSA3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2ID0gNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYgPSA3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYgPSA3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcgPSA3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcgPSA3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcgPSA3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3ID0gNzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcgPSA3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcgPSA3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzggPSA3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzggPSA3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzggPSA3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4ID0gNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzggPSA3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzggPSA3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkgPSA3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkgPSA3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkgPSA3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5ID0gNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkgPSA3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkgPSA3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAgPSA4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAgPSA4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAgPSA4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwID0gODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAgPSA4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwKCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAgPSA4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEgPSA4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEgPSA4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEgPSA4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxID0gODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEgPSA4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxKCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEgPSA4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIgPSA4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIgPSA4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIgPSA4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyID0gODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIgPSA4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyKCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIgPSA4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMgPSA4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMgPSA4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMgPSA4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzID0gODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMgPSA4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzKCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMgPSA4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQgPSA4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQgPSA4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQgPSA4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0ID0gODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQgPSA4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQgPSA4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUgPSA4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUgPSA4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUgPSA4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1ID0gODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUgPSA4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUgPSA4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYgPSA4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYgPSA4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYgPSA4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2ID0gODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYgPSA4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYgPSA4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcgPSA4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcgPSA4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcgPSA4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3ID0gODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcgPSA4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcgPSA4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODggPSA4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODggPSA4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODggPSA4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4ID0gODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODggPSA4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODggPSA4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkgPSA4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkgPSA4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkgPSA4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5ID0gODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkgPSA4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkgPSA4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAgPSA5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAgPSA5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAgPSA5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwID0gOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAgPSA5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwKCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAgPSA5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEgPSA5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEgPSA5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEgPSA5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxID0gOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEgPSA5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxKCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEgPSA5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIgPSA5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIgPSA5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIgPSA5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyID0gOTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIgPSA5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyKCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIgPSA5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMgPSA5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMgPSA5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMgPSA5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzID0gOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMgPSA5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzKCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMgPSA5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQgPSA5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQgPSA5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQgPSA5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0ID0gOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQgPSA5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQgPSA5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUgPSA5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUgPSA5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUgPSA5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1ID0gOTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUgPSA5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUgPSA5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYgPSA5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYgPSA5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYgPSA5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2ID0gOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYgPSA5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2KCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYgPSA5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcgPSA5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcgPSA5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcgPSA5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3ID0gOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcgPSA5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3KCk7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcgPSA5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTggPSA5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTggPSA5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOThfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTggPSA5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOThfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOThfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4ID0gOTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTggPSA5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOThfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4KCk7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTggPSA5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOThCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkgPSA5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkgPSA5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkgPSA5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5ID0gOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkgPSA5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5KCk7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkgPSA5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMCA9IDEwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDAgPSAxMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDAgPSAxMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAwID0gMTAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMCA9IDEwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwKCk7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAwID0gMTAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAxID0gMTAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMSA9IDEwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMSA9IDEwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDEgPSAxMDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAxID0gMTAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDEoKTsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDEgPSAxMDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDIgPSAxMDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAyID0gMTAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAyID0gMTAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMiA9IDEwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDIgPSAxMDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMigpOwogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMiA9IDEwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMyA9IDEwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDMgPSAxMDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDMgPSAxMDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAzID0gMTAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMyA9IDEwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAzKCk7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAzID0gMTAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA0ID0gMTA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNCA9IDEwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNCA9IDEwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDQgPSAxMDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA0ID0gMTA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDQoKTsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDQgPSAxMDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDUgPSAxMDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA1ID0gMTA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA1ID0gMTA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNSA9IDEwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDUgPSAxMDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNSgpOwogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNSA9IDEwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNiA9IDEwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDYgPSAxMDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDYgPSAxMDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA2ID0gMTA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNiA9IDEwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA2KCk7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA2ID0gMTA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA3ID0gMTA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNyA9IDEwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwNyA9IDEwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDcgPSAxMDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA3ID0gMTA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDcoKTsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDcgPSAxMDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDggPSAxMDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA4ID0gMTA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA4ID0gMTA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwOCA9IDEwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDggPSAxMDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOCgpOwogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwOCA9IDEwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwOSA9IDEwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDkgPSAxMDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDkgPSAxMDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA5ID0gMTA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwOSA9IDEwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA5KCk7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA5ID0gMTA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEwID0gMTEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMCA9IDExMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMCA9IDExMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTAgPSAxMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEwID0gMTEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTAoKTsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTAgPSAxMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTEgPSAxMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTExID0gMTExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTExID0gMTExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMSA9IDExMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTEgPSAxMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMSgpOwogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMSA9IDExMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMiA9IDExMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTIgPSAxMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTIgPSAxMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEyID0gMTEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMiA9IDExMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEyKCk7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEyID0gMTEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEzID0gMTEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMyA9IDExMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMyA9IDExMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTMgPSAxMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTEzID0gMTEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTMoKTsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTMgPSAxMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTQgPSAxMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE0ID0gMTE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE0ID0gMTE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNCA9IDExNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTQgPSAxMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNCgpOwogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNCA9IDExNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNSA9IDExNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTUgPSAxMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTUgPSAxMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE1ID0gMTE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNSA9IDExNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE1KCk7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE1ID0gMTE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE2ID0gMTE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNiA9IDExNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNiA9IDExNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTYgPSAxMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE2ID0gMTE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTYoKTsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTYgPSAxMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTcgPSAxMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE3ID0gMTE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE3ID0gMTE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExN187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNyA9IDExNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTcgPSAxMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNygpOwogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExNyA9IDExNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExN0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExOCA9IDExOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTggPSAxMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMThfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTggPSAxMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE4ID0gMTE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExOCA9IDExOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE4KCk7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE4ID0gMTE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE5ID0gMTE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExOSA9IDExOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExOSA9IDExOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTkgPSAxMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTE5ID0gMTE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTkoKTsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTkgPSAxMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjAgPSAxMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIwID0gMTIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIwID0gMTIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMCA9IDEyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjAgPSAxMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMCgpOwogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMCA9IDEyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMSA9IDEyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjEgPSAxMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjEgPSAxMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIxID0gMTIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMSA9IDEyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIxKCk7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIxID0gMTIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIyID0gMTIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMiA9IDEyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMiA9IDEyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjIgPSAxMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIyID0gMTIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjIoKTsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjIgPSAxMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjMgPSAxMjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIzID0gMTIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIzID0gMTIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyM187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMyA9IDEyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjMgPSAxMjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMygpOwogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyMyA9IDEyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyM0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNCA9IDEyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjQgPSAxMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjQgPSAxMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI0ID0gMTI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNCA9IDEyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI0KCk7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI0ID0gMTI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI1ID0gMTI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNSA9IDEyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNSA9IDEyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjUgPSAxMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI1ID0gMTI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjUoKTsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjUgPSAxMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjYgPSAxMjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzXyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI2ID0gMTI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI2ID0gMTI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNiA9IDEyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjYgPSAxMjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNigpOwogICAgICAgIGJpdEZpZWxkM18gPSAoYml0RmllbGQzXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNiA9IDEyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNyA9IDEyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDNfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjcgPSAxMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjcgPSAxMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI3ID0gMTI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkM18gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNyA9IDEyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyN18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI3KCk7CiAgICAgICAgYml0RmllbGQzXyA9IChiaXRGaWVsZDNfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI3ID0gMTI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI4ID0gMTI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkM18gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyOCA9IDEyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyOCA9IDEyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjggPSAxMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI4ID0gMTI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjgoKTsKICAgICAgICBiaXRGaWVsZDNfID0gKGJpdEZpZWxkM18gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjggPSAxMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDNfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjkgPSAxMjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI5ID0gMTI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTI5ID0gMTI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyOSA9IDEyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMjkgPSAxMjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOSgpOwogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyOSA9IDEyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMCA9IDEzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzAgPSAxMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzAgPSAxMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMwID0gMTMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMCA9IDEzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwKCk7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMwID0gMTMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMxID0gMTMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMSA9IDEzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMSA9IDEzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzEgPSAxMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMxID0gMTMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzEoKTsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzEgPSAxMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzIgPSAxMzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMyID0gMTMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMyID0gMTMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMiA9IDEzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzIgPSAxMzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMigpOwogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMiA9IDEzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMyA9IDEzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzMgPSAxMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzMgPSAxMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMzID0gMTMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMyA9IDEzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzKCk7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTMzID0gMTMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM0ID0gMTM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNCA9IDEzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNCA9IDEzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzQgPSAxMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM0ID0gMTM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzQoKTsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzQgPSAxMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzUgPSAxMzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM1ID0gMTM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM1ID0gMTM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNSA9IDEzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzUgPSAxMzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNSgpOwogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNSA9IDEzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNiA9IDEzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzYgPSAxMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzYgPSAxMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM2ID0gMTM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNiA9IDEzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2KCk7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM2ID0gMTM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM3ID0gMTM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNyA9IDEzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNyA9IDEzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzcgPSAxMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM3ID0gMTM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzcoKTsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzcgPSAxMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzggPSAxMzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM4ID0gMTM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM4ID0gMTM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzOCA9IDEzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzggPSAxMzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOCgpOwogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzOCA9IDEzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzOSA9IDEzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzkgPSAxMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzkgPSAxMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM5ID0gMTM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzOSA9IDEzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5KCk7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTM5ID0gMTM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQwID0gMTQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MCA9IDE0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MCA9IDE0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDAgPSAxNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQwID0gMTQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDAoKTsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDAgPSAxNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDEgPSAxNDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQxID0gMTQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQxID0gMTQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MSA9IDE0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDEgPSAxNDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MSgpOwogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MSA9IDE0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MiA9IDE0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDIgPSAxNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDIgPSAxNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQyID0gMTQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MiA9IDE0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyKCk7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQyID0gMTQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQzID0gMTQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MyA9IDE0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0MyA9IDE0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDMgPSAxNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQzID0gMTQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDMoKTsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDMgPSAxNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDQgPSAxNDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ0ID0gMTQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ0ID0gMTQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NCA9IDE0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDQgPSAxNDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NCgpOwogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NCA9IDE0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NSA9IDE0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDUgPSAxNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDUgPSAxNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ1ID0gMTQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NSA9IDE0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1KCk7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ1ID0gMTQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ2ID0gMTQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NiA9IDE0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NiA9IDE0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDYgPSAxNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ2ID0gMTQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDYoKTsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDYgPSAxNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDcgPSAxNDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ3ID0gMTQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ3ID0gMTQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NyA9IDE0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDcgPSAxNDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NygpOwogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0NyA9IDE0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0OCA9IDE0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDggPSAxNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDggPSAxNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ4ID0gMTQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0OCA9IDE0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4KCk7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ4ID0gMTQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ5ID0gMTQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0OSA9IDE0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE0OSA9IDE0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDkgPSAxNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTQ5ID0gMTQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDkoKTsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDkgPSAxNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTAgPSAxNTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUwID0gMTUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUwID0gMTUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MCA9IDE1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTAgPSAxNTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MCgpOwogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MCA9IDE1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MSA9IDE1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTEgPSAxNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTEgPSAxNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUxID0gMTUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MSA9IDE1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxKCk7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUxID0gMTUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUyID0gMTUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MiA9IDE1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MiA9IDE1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTIgPSAxNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUyID0gMTUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTIoKTsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTIgPSAxNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTMgPSAxNTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUzID0gMTUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTUzID0gMTUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MyA9IDE1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTMgPSAxNTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MygpOwogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1MyA9IDE1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NCA9IDE1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTQgPSAxNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTQgPSAxNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU0ID0gMTU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NCA9IDE1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0KCk7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU0ID0gMTU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU1ID0gMTU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NSA9IDE1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NSA9IDE1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTUgPSAxNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU1ID0gMTU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTUoKTsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTUgPSAxNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTYgPSAxNTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU2ID0gMTU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU2ID0gMTU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NiA9IDE1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTYgPSAxNTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NigpOwogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NiA9IDE1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NyA9IDE1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTcgPSAxNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTcgPSAxNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU3ID0gMTU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1NyA9IDE1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3KCk7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU3ID0gMTU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU4ID0gMTU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNF8gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1OCA9IDE1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNThfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1OCA9IDE1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNThCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNThfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTggPSAxNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU4ID0gMTU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTgoKTsKICAgICAgICBiaXRGaWVsZDRfID0gKGJpdEZpZWxkNF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTggPSAxNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNThCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTkgPSAxNTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ0XyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU5ID0gMTU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU5ID0gMTU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1OSA9IDE1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDRfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTkgPSAxNTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OSgpOwogICAgICAgIGJpdEZpZWxkNF8gPSAoYml0RmllbGQ0XyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE1OSA9IDE1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MCA9IDE2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDRfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjAgPSAxNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjAgPSAxNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYwID0gMTYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MCA9IDE2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwKCk7CiAgICAgICAgYml0RmllbGQ0XyA9IChiaXRGaWVsZDRfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYwID0gMTYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ0XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYxID0gMTYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MSA9IDE2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MSA9IDE2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjEgPSAxNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYxID0gMTYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjEoKTsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjEgPSAxNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjIgPSAxNjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYyID0gMTYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYyID0gMTYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MiA9IDE2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjIgPSAxNjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MigpOwogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MiA9IDE2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MyA9IDE2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjMgPSAxNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjMgPSAxNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYzID0gMTYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MyA9IDE2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzKCk7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTYzID0gMTYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY0ID0gMTY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NCA9IDE2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NCA9IDE2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjQgPSAxNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY0ID0gMTY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjQoKTsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjQgPSAxNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjUgPSAxNjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY1ID0gMTY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY1ID0gMTY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NSA9IDE2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjUgPSAxNjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NSgpOwogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NSA9IDE2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NiA9IDE2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjYgPSAxNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjYgPSAxNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY2ID0gMTY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NiA9IDE2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2KCk7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY2ID0gMTY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY3ID0gMTY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NyA9IDE2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2NyA9IDE2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjcgPSAxNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY3ID0gMTY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjcoKTsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjcgPSAxNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjggPSAxNjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY4ID0gMTY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY4ID0gMTY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2OCA9IDE2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjggPSAxNjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OCgpOwogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2OCA9IDE2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2OSA9IDE2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjkgPSAxNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNjkgPSAxNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY5ID0gMTY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2OSA9IDE2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5KCk7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTY5ID0gMTY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcwID0gMTcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MCA9IDE3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MCA9IDE3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzAgPSAxNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcwID0gMTcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzAoKTsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzAgPSAxNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzEgPSAxNzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcxID0gMTcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcxID0gMTcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MSA9IDE3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzEgPSAxNzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MSgpOwogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MSA9IDE3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MiA9IDE3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzIgPSAxNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzIgPSAxNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcyID0gMTcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MiA9IDE3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyKCk7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTcyID0gMTcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTczID0gMTczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTczKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MyA9IDE3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTczLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3MyA9IDE3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTczXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzMgPSAxNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTczIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTczID0gMTczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTczXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzMoKTsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzMgPSAxNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzQgPSAxNzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc0ID0gMTc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc0ID0gMTc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NCA9IDE3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzQgPSAxNzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NCgpOwogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NCA9IDE3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NSA9IDE3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzUgPSAxNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzUgPSAxNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc1ID0gMTc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NSA9IDE3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1KCk7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc1ID0gMTc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc2ID0gMTc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NiA9IDE3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NiA9IDE3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzYgPSAxNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc2ID0gMTc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzYoKTsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzYgPSAxNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzcgPSAxNzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc3ID0gMTc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc3ID0gMTc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NyA9IDE3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzcgPSAxNzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NygpOwogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3NyA9IDE3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3OCA9IDE3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzggPSAxNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzggPSAxNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc4ID0gMTc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3OCA9IDE3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4KCk7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc4ID0gMTc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc5ID0gMTc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMDQwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3OSA9IDE3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE3OSA9IDE3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzkgPSAxNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc5ID0gMTc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzkoKTsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzkgPSAxNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODAgPSAxODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgwID0gMTgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgwID0gMTgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MCA9IDE4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODAgPSAxODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MCgpOwogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MCA9IDE4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MSA9IDE4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODEgPSAxODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODEgPSAxODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgxID0gMTgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MSA9IDE4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxKCk7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgxID0gMTgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgyID0gMTgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MiA9IDE4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MiA9IDE4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODIgPSAxODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgyID0gMTgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODIoKTsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODIgPSAxODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODMgPSAxODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgzID0gMTgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgzID0gMTgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MyA9IDE4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODMgPSAxODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MygpOwogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4MyA9IDE4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NCA9IDE4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODQgPSAxODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODQgPSAxODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg0ID0gMTg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NCA9IDE4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0KCk7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg0ID0gMTg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg1ID0gMTg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NSA9IDE4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NSA9IDE4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODUgPSAxODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg1ID0gMTg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODUoKTsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODUgPSAxODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODYgPSAxODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg2ID0gMTg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg2ID0gMTg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NiA9IDE4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODYgPSAxODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NigpOwogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NiA9IDE4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NyA9IDE4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODcgPSAxODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODcgPSAxODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg3ID0gMTg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NyA9IDE4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3KCk7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg3ID0gMTg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg4ID0gMTg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDA4MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4OCA9IDE4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4OCA9IDE4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODggPSAxODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg4ID0gMTg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODgoKTsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODggPSAxODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODkgPSAxODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg5ID0gMTg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTg5ID0gMTg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4OSA9IDE4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xODkgPSAxODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OSgpOwogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4OSA9IDE4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MCA9IDE5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDVfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTAgPSAxOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTAgPSAxOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkwID0gMTkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MCA9IDE5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwKCk7CiAgICAgICAgYml0RmllbGQ1XyA9IChiaXRGaWVsZDVfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkwID0gMTkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkxID0gMTkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNV8gJiAweDQwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MSA9IDE5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MSA9IDE5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTEgPSAxOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkxID0gMTkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTEoKTsKICAgICAgICBiaXRGaWVsZDVfID0gKGJpdEZpZWxkNV8gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTEgPSAxOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTIgPSAxOTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ1XyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkyID0gMTkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkyID0gMTkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MiA9IDE5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDVfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTIgPSAxOTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MigpOwogICAgICAgIGJpdEZpZWxkNV8gPSAoYml0RmllbGQ1XyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MiA9IDE5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MyA9IDE5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTMgPSAxOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTMgPSAxOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkzID0gMTkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MyA9IDE5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkzKCk7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTkzID0gMTkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk0ID0gMTk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NCA9IDE5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NCA9IDE5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTQgPSAxOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk0ID0gMTk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTQoKTsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTQgPSAxOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTUgPSAxOTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk1ID0gMTk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk1ID0gMTk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NSA9IDE5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTUgPSAxOTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NSgpOwogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NSA9IDE5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NiA9IDE5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTYgPSAxOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTYgPSAxOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk2ID0gMTk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NiA9IDE5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk2KCk7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk2ID0gMTk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk3ID0gMTk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NyA9IDE5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5NyA9IDE5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTcgPSAxOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk3ID0gMTk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTcoKTsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTcgPSAxOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTggPSAxOTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk4ID0gMTk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk4ID0gMTk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOThfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5OCA9IDE5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTggPSAxOTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOThfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OCgpOwogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5OCA9IDE5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5OSA9IDE5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTkgPSAxOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTkgPSAxOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk5ID0gMTk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5OSA9IDE5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk5KCk7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTk5ID0gMTk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAwID0gMjAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMCA9IDIwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMCA9IDIwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDAgPSAyMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAwID0gMjAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDAoKTsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDAgPSAyMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDEgPSAyMDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAxID0gMjAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAxID0gMjAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMSA9IDIwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDEgPSAyMDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMSgpOwogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMSA9IDIwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMiA9IDIwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDIgPSAyMDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDIgPSAyMDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAyID0gMjAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMiA9IDIwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAyKCk7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAyID0gMjAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAzID0gMjAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMyA9IDIwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwMyA9IDIwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDMgPSAyMDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAzID0gMjAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDMoKTsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDMgPSAyMDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDQgPSAyMDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA0ID0gMjA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA0ID0gMjA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNCA9IDIwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDQgPSAyMDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNCgpOwogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNCA9IDIwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNSA9IDIwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDUgPSAyMDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDUgPSAyMDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA1ID0gMjA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNSA9IDIwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA1KCk7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA1ID0gMjA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA2ID0gMjA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNiA9IDIwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNiA9IDIwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDYgPSAyMDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA2ID0gMjA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDYoKTsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDYgPSAyMDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDcgPSAyMDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA3ID0gMjA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA3ID0gMjA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwN187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNyA9IDIwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDcgPSAyMDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNygpOwogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwNyA9IDIwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwN0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwOCA9IDIwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDggPSAyMDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDggPSAyMDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA4ID0gMjA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwOCA9IDIwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA4KCk7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA4ID0gMjA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA5ID0gMjA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwOSA9IDIwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIwOSA9IDIwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDkgPSAyMDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA5ID0gMjA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDkoKTsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMDkgPSAyMDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTAgPSAyMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEwID0gMjEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEwID0gMjEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMCA9IDIxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTAgPSAyMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMCgpOwogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMCA9IDIxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMSA9IDIxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTEgPSAyMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjExXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTEgPSAyMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjExQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjExXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjExID0gMjExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjExXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMSA9IDIxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjExKCk7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjExID0gMjExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjExQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEyID0gMjEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMiA9IDIxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMiA9IDIxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTIgPSAyMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEyID0gMjEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTIoKTsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTIgPSAyMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTMgPSAyMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEzID0gMjEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjEzID0gMjEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxM187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMyA9IDIxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTMgPSAyMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMygpOwogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMyA9IDIxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxM0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNCA9IDIxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTQgPSAyMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTQgPSAyMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE0ID0gMjE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNCA9IDIxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE0KCk7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE0ID0gMjE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE1ID0gMjE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNSA9IDIxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNSA9IDIxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTUgPSAyMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE1ID0gMjE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTUoKTsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTUgPSAyMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTYgPSAyMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE2ID0gMjE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE2ID0gMjE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNiA9IDIxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTYgPSAyMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNigpOwogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDAwODAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNiA9IDIxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNyA9IDIxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTcgPSAyMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTcgPSAyMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE3ID0gMjE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxNyA9IDIxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxN18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE3KCk7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE3ID0gMjE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE4ID0gMjE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxOCA9IDIxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMThfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxOCA9IDIxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMThCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMThfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTggPSAyMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE4ID0gMjE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTgoKTsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTggPSAyMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMThCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTkgPSAyMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE5ID0gMjE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE5ID0gMjE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxOSA9IDIxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMTkgPSAyMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOSgpOwogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxOSA9IDIxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMCA9IDIyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjAgPSAyMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjAgPSAyMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIwID0gMjIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMCA9IDIyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIwKCk7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIwID0gMjIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIxID0gMjIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMSA9IDIyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMSA9IDIyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjEgPSAyMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIxID0gMjIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjEoKTsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjEgPSAyMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjIgPSAyMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ2XyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIyID0gMjIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIyID0gMjIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMiA9IDIyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjIgPSAyMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMigpOwogICAgICAgIGJpdEZpZWxkNl8gPSAoYml0RmllbGQ2XyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMiA9IDIyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMyA9IDIyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDZfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjMgPSAyMjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjMgPSAyMjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIzID0gMjIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkNl8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyMyA9IDIyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIzKCk7CiAgICAgICAgYml0RmllbGQ2XyA9IChiaXRGaWVsZDZfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjIzID0gMjIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI0ID0gMjI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkNl8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNCA9IDIyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNCA9IDIyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjQgPSAyMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ2XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI0ID0gMjI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjQoKTsKICAgICAgICBiaXRGaWVsZDZfID0gKGJpdEZpZWxkNl8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjQgPSAyMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDZfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjUgPSAyMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI1ID0gMjI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI1ID0gMjI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNSA9IDIyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjUgPSAyMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNSgpOwogICAgICAgIGJpdEZpZWxkN18gPSAoYml0RmllbGQ3XyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNSA9IDIyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNiA9IDIyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjYgPSAyMjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjYgPSAyMjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI2ID0gMjI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNiA9IDIyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2KCk7CiAgICAgICAgYml0RmllbGQ3XyA9IChiaXRGaWVsZDdfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI2ID0gMjI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI3ID0gMjI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNyA9IDIyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyNyA9IDIyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjcgPSAyMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI3ID0gMjI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjcoKTsKICAgICAgICBiaXRGaWVsZDdfID0gKGJpdEZpZWxkN18gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjcgPSAyMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjggPSAyMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI4ID0gMjI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI4ID0gMjI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyOCA9IDIyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjggPSAyMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOCgpOwogICAgICAgIGJpdEZpZWxkN18gPSAoYml0RmllbGQ3XyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyOCA9IDIyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyOSA9IDIyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjkgPSAyMjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjkgPSAyMjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI5ID0gMjI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyOSA9IDIyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5KCk7CiAgICAgICAgYml0RmllbGQ3XyA9IChiaXRGaWVsZDdfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjI5ID0gMjI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMwID0gMjMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMCA9IDIzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMCA9IDIzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzAgPSAyMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMwID0gMjMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzAoKTsKICAgICAgICBiaXRGaWVsZDdfID0gKGJpdEZpZWxkN18gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzAgPSAyMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzEgPSAyMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMxID0gMjMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMxID0gMjMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMSA9IDIzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzEgPSAyMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMSgpOwogICAgICAgIGJpdEZpZWxkN18gPSAoYml0RmllbGQ3XyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMSA9IDIzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMiA9IDIzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzIgPSAyMzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzIgPSAyMzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMyID0gMjMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMiA9IDIzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyKCk7CiAgICAgICAgYml0RmllbGQ3XyA9IChiaXRGaWVsZDdfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMyID0gMjMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMzID0gMjMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMyA9IDIzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzMyA9IDIzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzMgPSAyMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjMzID0gMjMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzMoKTsKICAgICAgICBiaXRGaWVsZDdfID0gKGJpdEZpZWxkN18gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzMgPSAyMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzQgPSAyMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM0ID0gMjM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM0ID0gMjM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNCA9IDIzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzQgPSAyMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNCgpOwogICAgICAgIGJpdEZpZWxkN18gPSAoYml0RmllbGQ3XyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNCA9IDIzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNSA9IDIzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzUgPSAyMzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzUgPSAyMzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM1ID0gMjM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNSA9IDIzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1KCk7CiAgICAgICAgYml0RmllbGQ3XyA9IChiaXRGaWVsZDdfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM1ID0gMjM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM2ID0gMjM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNiA9IDIzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNiA9IDIzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzYgPSAyMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM2ID0gMjM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzYoKTsKICAgICAgICBiaXRGaWVsZDdfID0gKGJpdEZpZWxkN18gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzYgPSAyMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzcgPSAyMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM3ID0gMjM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM3ID0gMjM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzN187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNyA9IDIzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzcgPSAyMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNygpOwogICAgICAgIGJpdEZpZWxkN18gPSAoYml0RmllbGQ3XyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzNyA9IDIzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzN0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzOCA9IDIzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzggPSAyMzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzggPSAyMzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM4ID0gMjM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzOCA9IDIzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4KCk7CiAgICAgICAgYml0RmllbGQ3XyA9IChiaXRGaWVsZDdfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM4ID0gMjM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM5ID0gMjM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzOSA9IDIzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIzOSA9IDIzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzkgPSAyMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM5ID0gMjM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzkoKTsKICAgICAgICBiaXRGaWVsZDdfID0gKGJpdEZpZWxkN18gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzkgPSAyMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDAgPSAyNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQwID0gMjQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQwID0gMjQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MCA9IDI0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDAgPSAyNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MCgpOwogICAgICAgIGJpdEZpZWxkN18gPSAoYml0RmllbGQ3XyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MCA9IDI0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MSA9IDI0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDEgPSAyNDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDEgPSAyNDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQxID0gMjQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MSA9IDI0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxKCk7CiAgICAgICAgYml0RmllbGQ3XyA9IChiaXRGaWVsZDdfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQxID0gMjQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQyID0gMjQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MiA9IDI0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MiA9IDI0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDIgPSAyNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQyID0gMjQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDIoKTsKICAgICAgICBiaXRGaWVsZDdfID0gKGJpdEZpZWxkN18gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDIgPSAyNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDMgPSAyNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQzID0gMjQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQzID0gMjQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MyA9IDI0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDMgPSAyNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MygpOwogICAgICAgIGJpdEZpZWxkN18gPSAoYml0RmllbGQ3XyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MyA9IDI0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NCA9IDI0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDQgPSAyNDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDQgPSAyNDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ0ID0gMjQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NCA9IDI0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0KCk7CiAgICAgICAgYml0RmllbGQ3XyA9IChiaXRGaWVsZDdfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ0ID0gMjQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ1ID0gMjQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NSA9IDI0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NSA9IDI0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDUgPSAyNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ1ID0gMjQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDUoKTsKICAgICAgICBiaXRGaWVsZDdfID0gKGJpdEZpZWxkN18gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDUgPSAyNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDYgPSAyNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ2ID0gMjQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ2ID0gMjQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NiA9IDI0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDYgPSAyNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NigpOwogICAgICAgIGJpdEZpZWxkN18gPSAoYml0RmllbGQ3XyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NiA9IDI0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NyA9IDI0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDcgPSAyNDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDcgPSAyNDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ3ID0gMjQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0NyA9IDI0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3KCk7CiAgICAgICAgYml0RmllbGQ3XyA9IChiaXRGaWVsZDdfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ3ID0gMjQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ4ID0gMjQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0OCA9IDI0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0OCA9IDI0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDggPSAyNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ4ID0gMjQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDgoKTsKICAgICAgICBiaXRGaWVsZDdfID0gKGJpdEZpZWxkN18gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDggPSAyNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDkgPSAyNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ5ID0gMjQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjQ5ID0gMjQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0OSA9IDI0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNDkgPSAyNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OSgpOwogICAgICAgIGJpdEZpZWxkN18gPSAoYml0RmllbGQ3XyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0OSA9IDI0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MCA9IDI1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTAgPSAyNTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTAgPSAyNTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUwID0gMjUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MCA9IDI1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwKCk7CiAgICAgICAgYml0RmllbGQ3XyA9IChiaXRGaWVsZDdfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUwID0gMjUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUxID0gMjUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MSA9IDI1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MSA9IDI1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTEgPSAyNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUxID0gMjUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTEoKTsKICAgICAgICBiaXRGaWVsZDdfID0gKGJpdEZpZWxkN18gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTEgPSAyNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTIgPSAyNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUyID0gMjUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUyID0gMjUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MiA9IDI1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTIgPSAyNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MigpOwogICAgICAgIGJpdEZpZWxkN18gPSAoYml0RmllbGQ3XyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MiA9IDI1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MyA9IDI1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTMgPSAyNTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTMgPSAyNTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUzID0gMjUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1MyA9IDI1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzKCk7CiAgICAgICAgYml0RmllbGQ3XyA9IChiaXRGaWVsZDdfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjUzID0gMjUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU0ID0gMjU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkN18gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NCA9IDI1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NCA9IDI1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTQgPSAyNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU0ID0gMjU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTQoKTsKICAgICAgICBiaXRGaWVsZDdfID0gKGJpdEZpZWxkN18gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTQgPSAyNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTUgPSAyNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ3XyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU1ID0gMjU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU1ID0gMjU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NSA9IDI1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDdfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTUgPSAyNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NSgpOwogICAgICAgIGJpdEZpZWxkN18gPSAoYml0RmllbGQ3XyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NSA9IDI1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NiA9IDI1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDdfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTYgPSAyNTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTYgPSAyNTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU2ID0gMjU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkN18gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NiA9IDI1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2KCk7CiAgICAgICAgYml0RmllbGQ3XyA9IChiaXRGaWVsZDdfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU2ID0gMjU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ3XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU3ID0gMjU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NyA9IDI1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1NyA9IDI1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTcgPSAyNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU3ID0gMjU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTcoKTsKICAgICAgICBiaXRGaWVsZDhfID0gKGJpdEZpZWxkOF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTcgPSAyNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTggPSAyNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU4ID0gMjU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU4ID0gMjU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNThfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1OCA9IDI1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTggPSAyNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNThfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OCgpOwogICAgICAgIGJpdEZpZWxkOF8gPSAoYml0RmllbGQ4XyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1OCA9IDI1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1OSA9IDI1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTkgPSAyNTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTkgPSAyNTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU5ID0gMjU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI1OSA9IDI1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5KCk7CiAgICAgICAgYml0RmllbGQ4XyA9IChiaXRGaWVsZDhfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU5ID0gMjU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYwID0gMjYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MCA9IDI2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MCA9IDI2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjAgPSAyNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYwID0gMjYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjAoKTsKICAgICAgICBiaXRGaWVsZDhfID0gKGJpdEZpZWxkOF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjAgPSAyNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjEgPSAyNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYxID0gMjYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYxID0gMjYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MSA9IDI2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjEgPSAyNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MSgpOwogICAgICAgIGJpdEZpZWxkOF8gPSAoYml0RmllbGQ4XyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MSA9IDI2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MiA9IDI2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjIgPSAyNjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjIgPSAyNjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYyID0gMjYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MiA9IDI2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyKCk7CiAgICAgICAgYml0RmllbGQ4XyA9IChiaXRGaWVsZDhfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYyID0gMjYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYzID0gMjYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MyA9IDI2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2MyA9IDI2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjMgPSAyNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYzID0gMjYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjMoKTsKICAgICAgICBiaXRGaWVsZDhfID0gKGJpdEZpZWxkOF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjMgPSAyNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjQgPSAyNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY0ID0gMjY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY0ID0gMjY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NCA9IDI2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjQgPSAyNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NCgpOwogICAgICAgIGJpdEZpZWxkOF8gPSAoYml0RmllbGQ4XyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NCA9IDI2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NSA9IDI2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjUgPSAyNjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjUgPSAyNjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY1ID0gMjY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NSA9IDI2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1KCk7CiAgICAgICAgYml0RmllbGQ4XyA9IChiaXRGaWVsZDhfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY1ID0gMjY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY2ID0gMjY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NiA9IDI2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NiA9IDI2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjYgPSAyNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY2ID0gMjY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjYoKTsKICAgICAgICBiaXRGaWVsZDhfID0gKGJpdEZpZWxkOF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjYgPSAyNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjcgPSAyNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY3ID0gMjY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY3ID0gMjY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NyA9IDI2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjcgPSAyNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NygpOwogICAgICAgIGJpdEZpZWxkOF8gPSAoYml0RmllbGQ4XyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NyA9IDI2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2OCA9IDI2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjggPSAyNjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjggPSAyNjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY4ID0gMjY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2OCA9IDI2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4KCk7CiAgICAgICAgYml0RmllbGQ4XyA9IChiaXRGaWVsZDhfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY4ID0gMjY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY5ID0gMjY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2OSA9IDI2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2OSA9IDI2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjkgPSAyNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjY5ID0gMjY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjkoKTsKICAgICAgICBiaXRGaWVsZDhfID0gKGJpdEZpZWxkOF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNjkgPSAyNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzAgPSAyNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcwID0gMjcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcwID0gMjcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MCA9IDI3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzAgPSAyNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MCgpOwogICAgICAgIGJpdEZpZWxkOF8gPSAoYml0RmllbGQ4XyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MCA9IDI3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MSA9IDI3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzEgPSAyNzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzEgPSAyNzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcxID0gMjcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MSA9IDI3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxKCk7CiAgICAgICAgYml0RmllbGQ4XyA9IChiaXRGaWVsZDhfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcxID0gMjcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcyID0gMjcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MiA9IDI3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MiA9IDI3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzIgPSAyNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjcyID0gMjcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzIoKTsKICAgICAgICBiaXRGaWVsZDhfID0gKGJpdEZpZWxkOF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzIgPSAyNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzMgPSAyNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjczID0gMjczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjczID0gMjczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MyA9IDI3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzMgPSAyNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MygpOwogICAgICAgIGJpdEZpZWxkOF8gPSAoYml0RmllbGQ4XyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MyA9IDI3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NCA9IDI3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzQgPSAyNzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzQgPSAyNzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc0ID0gMjc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NCA9IDI3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0KCk7CiAgICAgICAgYml0RmllbGQ4XyA9IChiaXRGaWVsZDhfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc0ID0gMjc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc1ID0gMjc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMDQwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NSA9IDI3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NSA9IDI3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzUgPSAyNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc1ID0gMjc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzUoKTsKICAgICAgICBiaXRGaWVsZDhfID0gKGJpdEZpZWxkOF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzUgPSAyNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzYgPSAyNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc2ID0gMjc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc2ID0gMjc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NiA9IDI3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzYgPSAyNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NigpOwogICAgICAgIGJpdEZpZWxkOF8gPSAoYml0RmllbGQ4XyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NiA9IDI3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NyA9IDI3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzcgPSAyNzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzcgPSAyNzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc3ID0gMjc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3NyA9IDI3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3KCk7CiAgICAgICAgYml0RmllbGQ4XyA9IChiaXRGaWVsZDhfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc3ID0gMjc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc4ID0gMjc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3OCA9IDI3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3OCA9IDI3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzggPSAyNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc4ID0gMjc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzgoKTsKICAgICAgICBiaXRGaWVsZDhfID0gKGJpdEZpZWxkOF8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzggPSAyNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzkgPSAyNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc5ID0gMjc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjc5ID0gMjc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3OSA9IDI3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzkgPSAyNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OSgpOwogICAgICAgIGJpdEZpZWxkOF8gPSAoYml0RmllbGQ4XyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3OSA9IDI3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MCA9IDI4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODAgPSAyODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODAgPSAyODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgwID0gMjgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MCA9IDI4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwKCk7CiAgICAgICAgYml0RmllbGQ4XyA9IChiaXRGaWVsZDhfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgwID0gMjgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgxID0gMjgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MSA9IDI4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MSA9IDI4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODEgPSAyODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgxID0gMjgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODEoKTsKICAgICAgICBiaXRGaWVsZDhfID0gKGJpdEZpZWxkOF8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODEgPSAyODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODIgPSAyODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgyID0gMjgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgyID0gMjgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MiA9IDI4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODIgPSAyODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MigpOwogICAgICAgIGJpdEZpZWxkOF8gPSAoYml0RmllbGQ4XyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MiA9IDI4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MyA9IDI4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODMgPSAyODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODMgPSAyODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgzID0gMjgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4MyA9IDI4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzKCk7CiAgICAgICAgYml0RmllbGQ4XyA9IChiaXRGaWVsZDhfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgzID0gMjgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg0ID0gMjg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDA4MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NCA9IDI4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NCA9IDI4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODQgPSAyODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg0ID0gMjg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODQoKTsKICAgICAgICBiaXRGaWVsZDhfID0gKGJpdEZpZWxkOF8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODQgPSAyODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODUgPSAyODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg1ID0gMjg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg1ID0gMjg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NSA9IDI4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODUgPSAyODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NSgpOwogICAgICAgIGJpdEZpZWxkOF8gPSAoYml0RmllbGQ4XyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NSA9IDI4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NiA9IDI4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDhfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODYgPSAyODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODYgPSAyODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg2ID0gMjg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NiA9IDI4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2KCk7CiAgICAgICAgYml0RmllbGQ4XyA9IChiaXRGaWVsZDhfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg2ID0gMjg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg3ID0gMjg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOF8gJiAweDQwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NyA9IDI4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4NyA9IDI4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODcgPSAyODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ4XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg3ID0gMjg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODcoKTsKICAgICAgICBiaXRGaWVsZDhfID0gKGJpdEZpZWxkOF8gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODcgPSAyODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODggPSAyODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ4XyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg4ID0gMjg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg4ID0gMjg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4OCA9IDI4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDhfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODggPSAyODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OCgpOwogICAgICAgIGJpdEZpZWxkOF8gPSAoYml0RmllbGQ4XyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4OCA9IDI4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4OSA9IDI4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODkgPSAyODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODkgPSAyODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg5ID0gMjg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI4OSA9IDI4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg5KCk7CiAgICAgICAgYml0RmllbGQ5XyA9IChiaXRGaWVsZDlfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjg5ID0gMjg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkwID0gMjkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MCA9IDI5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MCA9IDI5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTAgPSAyOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkwID0gMjkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTAoKTsKICAgICAgICBiaXRGaWVsZDlfID0gKGJpdEZpZWxkOV8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTAgPSAyOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTEgPSAyOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkxID0gMjkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkxID0gMjkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MSA9IDI5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTEgPSAyOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MSgpOwogICAgICAgIGJpdEZpZWxkOV8gPSAoYml0RmllbGQ5XyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MSA9IDI5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MiA9IDI5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTIgPSAyOTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTIgPSAyOTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkyID0gMjkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MiA9IDI5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkyKCk7CiAgICAgICAgYml0RmllbGQ5XyA9IChiaXRGaWVsZDlfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkyID0gMjkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkzID0gMjkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MyA9IDI5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5MyA9IDI5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTMgPSAyOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkzID0gMjkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTMoKTsKICAgICAgICBiaXRGaWVsZDlfID0gKGJpdEZpZWxkOV8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTMgPSAyOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTQgPSAyOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk0ID0gMjk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk0ID0gMjk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NCA9IDI5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTQgPSAyOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NCgpOwogICAgICAgIGJpdEZpZWxkOV8gPSAoYml0RmllbGQ5XyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NCA9IDI5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NSA9IDI5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTUgPSAyOTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTUgPSAyOTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk1ID0gMjk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NSA9IDI5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk1KCk7CiAgICAgICAgYml0RmllbGQ5XyA9IChiaXRGaWVsZDlfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk1ID0gMjk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk2ID0gMjk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NiA9IDI5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NiA9IDI5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTYgPSAyOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk2ID0gMjk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTYoKTsKICAgICAgICBiaXRGaWVsZDlfID0gKGJpdEZpZWxkOV8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTYgPSAyOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTcgPSAyOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk3ID0gMjk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk3ID0gMjk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NyA9IDI5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTcgPSAyOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NygpOwogICAgICAgIGJpdEZpZWxkOV8gPSAoYml0RmllbGQ5XyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5NyA9IDI5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5OCA9IDI5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTggPSAyOTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOThfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTggPSAyOTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk4ID0gMjk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5OCA9IDI5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk4KCk7CiAgICAgICAgYml0RmllbGQ5XyA9IChiaXRGaWVsZDlfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk4ID0gMjk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk5ID0gMjk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5OSA9IDI5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5OSA9IDI5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTkgPSAyOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk5ID0gMjk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTkoKTsKICAgICAgICBiaXRGaWVsZDlfID0gKGJpdEZpZWxkOV8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yOTkgPSAyOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDAgPSAzMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAwID0gMzAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAwID0gMzAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMCA9IDMwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDAgPSAzMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMCgpOwogICAgICAgIGJpdEZpZWxkOV8gPSAoYml0RmllbGQ5XyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMCA9IDMwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMSA9IDMwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDEgPSAzMDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDEgPSAzMDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAxID0gMzAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMSA9IDMwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAxKCk7CiAgICAgICAgYml0RmllbGQ5XyA9IChiaXRGaWVsZDlfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAxID0gMzAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAyID0gMzAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMiA9IDMwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMiA9IDMwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDIgPSAzMDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAyID0gMzAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDIoKTsKICAgICAgICBiaXRGaWVsZDlfID0gKGJpdEZpZWxkOV8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDIgPSAzMDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDMgPSAzMDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAzID0gMzAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzAzID0gMzAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwM187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMyA9IDMwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDMgPSAzMDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMygpOwogICAgICAgIGJpdEZpZWxkOV8gPSAoYml0RmllbGQ5XyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwMyA9IDMwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwM0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNCA9IDMwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDQgPSAzMDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDQgPSAzMDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA0ID0gMzA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNCA9IDMwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA0KCk7CiAgICAgICAgYml0RmllbGQ5XyA9IChiaXRGaWVsZDlfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA0ID0gMzA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA1ID0gMzA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNSA9IDMwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNSA9IDMwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDUgPSAzMDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA1ID0gMzA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDUoKTsKICAgICAgICBiaXRGaWVsZDlfID0gKGJpdEZpZWxkOV8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDUgPSAzMDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDYgPSAzMDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA2ID0gMzA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA2ID0gMzA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNiA9IDMwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDYgPSAzMDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNigpOwogICAgICAgIGJpdEZpZWxkOV8gPSAoYml0RmllbGQ5XyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNiA9IDMwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNyA9IDMwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDcgPSAzMDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDcgPSAzMDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA3ID0gMzA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwNyA9IDMwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwN18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA3KCk7CiAgICAgICAgYml0RmllbGQ5XyA9IChiaXRGaWVsZDlfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA3ID0gMzA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA4ID0gMzA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwOCA9IDMwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwOCA9IDMwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDggPSAzMDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA4ID0gMzA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDgoKTsKICAgICAgICBiaXRGaWVsZDlfID0gKGJpdEZpZWxkOV8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDggPSAzMDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDkgPSAzMDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA5ID0gMzA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzA5ID0gMzA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwOSA9IDMwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDkgPSAzMDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOSgpOwogICAgICAgIGJpdEZpZWxkOV8gPSAoYml0RmllbGQ5XyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwOSA9IDMwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMCA9IDMxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTAgPSAzMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTAgPSAzMTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEwID0gMzEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMCA9IDMxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEwKCk7CiAgICAgICAgYml0RmllbGQ5XyA9IChiaXRGaWVsZDlfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEwID0gMzEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzExID0gMzExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzExKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMSA9IDMxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzExLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMSA9IDMxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzExXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTEgPSAzMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzExIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzExID0gMzExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzExXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTEoKTsKICAgICAgICBiaXRGaWVsZDlfID0gKGJpdEZpZWxkOV8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTEgPSAzMTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTIgPSAzMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEyID0gMzEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEyID0gMzEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMiA9IDMxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTIgPSAzMTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMigpOwogICAgICAgIGJpdEZpZWxkOV8gPSAoYml0RmllbGQ5XyAmIH4weDAwODAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMiA9IDMxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMyA9IDMxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTMgPSAzMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTMgPSAzMTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEzID0gMzEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxMyA9IDMxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEzKCk7CiAgICAgICAgYml0RmllbGQ5XyA9IChiaXRGaWVsZDlfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzEzID0gMzEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE0ID0gMzE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNCA9IDMxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNCA9IDMxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTQgPSAzMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE0ID0gMzE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTQoKTsKICAgICAgICBiaXRGaWVsZDlfID0gKGJpdEZpZWxkOV8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTQgPSAzMTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTUgPSAzMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE1ID0gMzE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE1ID0gMzE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNSA9IDMxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTUgPSAzMTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNSgpOwogICAgICAgIGJpdEZpZWxkOV8gPSAoYml0RmllbGQ5XyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNSA9IDMxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNiA9IDMxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTYgPSAzMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTYgPSAzMTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE2ID0gMzE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNiA9IDMxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE2KCk7CiAgICAgICAgYml0RmllbGQ5XyA9IChiaXRGaWVsZDlfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE2ID0gMzE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE3ID0gMzE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNyA9IDMxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxNyA9IDMxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTcgPSAzMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE3ID0gMzE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTcoKTsKICAgICAgICBiaXRGaWVsZDlfID0gKGJpdEZpZWxkOV8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTcgPSAzMTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTggPSAzMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQ5XyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE4ID0gMzE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE4ID0gMzE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMThfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxOCA9IDMxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTggPSAzMTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMThfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOCgpOwogICAgICAgIGJpdEZpZWxkOV8gPSAoYml0RmllbGQ5XyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxOCA9IDMxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxOSA9IDMxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDlfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTkgPSAzMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTkgPSAzMTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE5ID0gMzE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkOV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMxOSA9IDMxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE5KCk7CiAgICAgICAgYml0RmllbGQ5XyA9IChiaXRGaWVsZDlfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE5ID0gMzE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIwID0gMzIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkOV8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMCA9IDMyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMCA9IDMyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjAgPSAzMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQ5XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIwID0gMzIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjAoKTsKICAgICAgICBiaXRGaWVsZDlfID0gKGJpdEZpZWxkOV8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjAgPSAzMjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDlfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjEgPSAzMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMSA9IDMyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMSA9IDMyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjEgPSAzMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMSA9IDMyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIxKCk7CiAgICAgICAgYml0RmllbGQxMF8gPSAoYml0RmllbGQxMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjEgPSAzMjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIyID0gMzIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjIgPSAzMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjIgPSAzMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIyID0gMzIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjIgPSAzMjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMigpOwogICAgICAgIGJpdEZpZWxkMTBfID0gKGJpdEZpZWxkMTBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIyID0gMzIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMyA9IDMyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIzID0gMzIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIzID0gMzIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyM187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMyA9IDMyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzIzID0gMzIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjMoKTsKICAgICAgICBiaXRGaWVsZDEwXyA9IChiaXRGaWVsZDEwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMyA9IDMyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyM0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjQgPSAzMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNCA9IDMyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNCA9IDMyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjQgPSAzMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNCA9IDMyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI0KCk7CiAgICAgICAgYml0RmllbGQxMF8gPSAoYml0RmllbGQxMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjQgPSAzMjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI1ID0gMzI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjUgPSAzMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjUgPSAzMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI1ID0gMzI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjUgPSAzMjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNSgpOwogICAgICAgIGJpdEZpZWxkMTBfID0gKGJpdEZpZWxkMTBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI1ID0gMzI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNiA9IDMyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI2ID0gMzI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI2ID0gMzI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNiA9IDMyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI2ID0gMzI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjYoKTsKICAgICAgICBiaXRGaWVsZDEwXyA9IChiaXRGaWVsZDEwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNiA9IDMyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjcgPSAzMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNyA9IDMyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNyA9IDMyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjcgPSAzMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyNyA9IDMyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyN18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI3KCk7CiAgICAgICAgYml0RmllbGQxMF8gPSAoYml0RmllbGQxMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjcgPSAzMjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI4ID0gMzI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjggPSAzMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjggPSAzMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI4ID0gMzI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMjggPSAzMjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOCgpOwogICAgICAgIGJpdEZpZWxkMTBfID0gKGJpdEZpZWxkMTBfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI4ID0gMzI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyOSA9IDMyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEwXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI5ID0gMzI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI5ID0gMzI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyOSA9IDMyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzI5ID0gMzI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjkoKTsKICAgICAgICBiaXRGaWVsZDEwXyA9IChiaXRGaWVsZDEwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyOSA9IDMyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzAgPSAzMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMF8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMCA9IDMzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMCA9IDMzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzAgPSAzMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMCA9IDMzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMwKCk7CiAgICAgICAgYml0RmllbGQxMF8gPSAoYml0RmllbGQxMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzAgPSAzMzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMxID0gMzMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzEgPSAzMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzEgPSAzMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMxID0gMzMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzEgPSAzMzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMSgpOwogICAgICAgIGJpdEZpZWxkMTBfID0gKGJpdEZpZWxkMTBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMxID0gMzMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMiA9IDMzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEwXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMyID0gMzMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMyID0gMzMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMiA9IDMzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzMyID0gMzMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzIoKTsKICAgICAgICBiaXRGaWVsZDEwXyA9IChiaXRGaWVsZDEwXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMiA9IDMzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzMgPSAzMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMF8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMyA9IDMzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMyA9IDMzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzMgPSAzMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzMyA9IDMzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMzKCk7CiAgICAgICAgYml0RmllbGQxMF8gPSAoYml0RmllbGQxMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzMgPSAzMzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM0ID0gMzM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzQgPSAzMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzQgPSAzMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM0ID0gMzM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzQgPSAzMzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNCgpOwogICAgICAgIGJpdEZpZWxkMTBfID0gKGJpdEZpZWxkMTBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM0ID0gMzM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzNSA9IDMzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEwXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM1ID0gMzM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM1ID0gMzM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzNSA9IDMzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM1ID0gMzM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzUoKTsKICAgICAgICBiaXRGaWVsZDEwXyA9IChiaXRGaWVsZDEwXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzNSA9IDMzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzYgPSAzMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMF8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzNiA9IDMzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzNiA9IDMzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzYgPSAzMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzNiA9IDMzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM2KCk7CiAgICAgICAgYml0RmllbGQxMF8gPSAoYml0RmllbGQxMF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzYgPSAzMzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM3ID0gMzM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzcgPSAzMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzcgPSAzMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM3ID0gMzM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzcgPSAzMzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNygpOwogICAgICAgIGJpdEZpZWxkMTBfID0gKGJpdEZpZWxkMTBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM3ID0gMzM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzOCA9IDMzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEwXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM4ID0gMzM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM4ID0gMzM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzOCA9IDMzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM4ID0gMzM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzgoKTsKICAgICAgICBiaXRGaWVsZDEwXyA9IChiaXRGaWVsZDEwXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzOCA9IDMzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzkgPSAzMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMF8gJiAweDAwMDQwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzOSA9IDMzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzOSA9IDMzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzkgPSAzMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMzOSA9IDMzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM5KCk7CiAgICAgICAgYml0RmllbGQxMF8gPSAoYml0RmllbGQxMF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzkgPSAzMzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQwID0gMzQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDAgPSAzNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDAgPSAzNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQwID0gMzQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDAgPSAzNDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MCgpOwogICAgICAgIGJpdEZpZWxkMTBfID0gKGJpdEZpZWxkMTBfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQwID0gMzQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0MSA9IDM0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEwXyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQxID0gMzQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQxID0gMzQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0MSA9IDM0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQxID0gMzQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDEoKTsKICAgICAgICBiaXRGaWVsZDEwXyA9IChiaXRGaWVsZDEwXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0MSA9IDM0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDIgPSAzNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMF8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0MiA9IDM0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0MiA9IDM0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDIgPSAzNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0MiA9IDM0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQyKCk7CiAgICAgICAgYml0RmllbGQxMF8gPSAoYml0RmllbGQxMF8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDIgPSAzNDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQzID0gMzQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDMgPSAzNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDMgPSAzNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQzID0gMzQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDMgPSAzNDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MygpOwogICAgICAgIGJpdEZpZWxkMTBfID0gKGJpdEZpZWxkMTBfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQzID0gMzQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NCA9IDM0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEwXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ0ID0gMzQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ0ID0gMzQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NCA9IDM0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ0ID0gMzQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDQoKTsKICAgICAgICBiaXRGaWVsZDEwXyA9IChiaXRGaWVsZDEwXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NCA9IDM0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDUgPSAzNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMF8gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NSA9IDM0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NSA9IDM0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDUgPSAzNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NSA9IDM0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ1KCk7CiAgICAgICAgYml0RmllbGQxMF8gPSAoYml0RmllbGQxMF8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDUgPSAzNDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ2ID0gMzQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDYgPSAzNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDYgPSAzNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ2ID0gMzQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDYgPSAzNDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NigpOwogICAgICAgIGJpdEZpZWxkMTBfID0gKGJpdEZpZWxkMTBfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ2ID0gMzQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NyA9IDM0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEwXyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ3ID0gMzQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ3ID0gMzQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NyA9IDM0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ3ID0gMzQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDcoKTsKICAgICAgICBiaXRGaWVsZDEwXyA9IChiaXRGaWVsZDEwXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NyA9IDM0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDggPSAzNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMF8gJiAweDA4MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0OCA9IDM0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0OCA9IDM0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDggPSAzNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0OCA9IDM0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ4KCk7CiAgICAgICAgYml0RmllbGQxMF8gPSAoYml0RmllbGQxMF8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDggPSAzNDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ5ID0gMzQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDkgPSAzNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDkgPSAzNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ5ID0gMzQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNDkgPSAzNDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0OSgpOwogICAgICAgIGJpdEZpZWxkMTBfID0gKGJpdEZpZWxkMTBfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQ5ID0gMzQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MCA9IDM1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEwXyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUwID0gMzUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUwID0gMzUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MCA9IDM1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUwID0gMzUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTAoKTsKICAgICAgICBiaXRGaWVsZDEwXyA9IChiaXRGaWVsZDEwXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MCA9IDM1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTEgPSAzNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMF8gJiAweDQwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MSA9IDM1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MSA9IDM1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTEgPSAzNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MSA9IDM1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUxKCk7CiAgICAgICAgYml0RmllbGQxMF8gPSAoYml0RmllbGQxMF8gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTEgPSAzNTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUyID0gMzUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTBfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTIgPSAzNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTIgPSAzNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUyID0gMzUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTIgPSAzNTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MigpOwogICAgICAgIGJpdEZpZWxkMTBfID0gKGJpdEZpZWxkMTBfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUyID0gMzUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MyA9IDM1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDExXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUzID0gMzUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUzID0gMzUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MyA9IDM1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzUzID0gMzUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTMoKTsKICAgICAgICBiaXRGaWVsZDExXyA9IChiaXRGaWVsZDExXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MyA9IDM1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTQgPSAzNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMV8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NCA9IDM1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NCA9IDM1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTQgPSAzNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NCA9IDM1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU0KCk7CiAgICAgICAgYml0RmllbGQxMV8gPSAoYml0RmllbGQxMV8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTQgPSAzNTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU1ID0gMzU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTUgPSAzNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTUgPSAzNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU1ID0gMzU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTUgPSAzNTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NSgpOwogICAgICAgIGJpdEZpZWxkMTFfID0gKGJpdEZpZWxkMTFfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU1ID0gMzU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NiA9IDM1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDExXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU2ID0gMzU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU2ID0gMzU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NiA9IDM1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU2ID0gMzU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTYoKTsKICAgICAgICBiaXRGaWVsZDExXyA9IChiaXRGaWVsZDExXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NiA9IDM1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTcgPSAzNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMV8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NyA9IDM1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NyA9IDM1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTcgPSAzNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1NyA9IDM1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU3KCk7CiAgICAgICAgYml0RmllbGQxMV8gPSAoYml0RmllbGQxMV8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTcgPSAzNTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU4ID0gMzU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTggPSAzNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNThfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTggPSAzNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU4ID0gMzU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTggPSAzNTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNThfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OCgpOwogICAgICAgIGJpdEZpZWxkMTFfID0gKGJpdEZpZWxkMTFfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU4ID0gMzU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1OSA9IDM1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDExXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU5ID0gMzU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU5ID0gMzU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1OSA9IDM1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzU5ID0gMzU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTkoKTsKICAgICAgICBiaXRGaWVsZDExXyA9IChiaXRGaWVsZDExXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1OSA9IDM1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjAgPSAzNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMV8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MCA9IDM2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MCA9IDM2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjAgPSAzNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MCA9IDM2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYwKCk7CiAgICAgICAgYml0RmllbGQxMV8gPSAoYml0RmllbGQxMV8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjAgPSAzNjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYxID0gMzYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjEgPSAzNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjEgPSAzNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYxID0gMzYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjEgPSAzNjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MSgpOwogICAgICAgIGJpdEZpZWxkMTFfID0gKGJpdEZpZWxkMTFfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYxID0gMzYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MiA9IDM2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDExXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYyID0gMzYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYyID0gMzYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MiA9IDM2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzYyID0gMzYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjIoKTsKICAgICAgICBiaXRGaWVsZDExXyA9IChiaXRGaWVsZDExXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MiA9IDM2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjMgPSAzNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMV8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MyA9IDM2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MyA9IDM2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjMgPSAzNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2MyA9IDM2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYzKCk7CiAgICAgICAgYml0RmllbGQxMV8gPSAoYml0RmllbGQxMV8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjMgPSAzNjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY0ID0gMzY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjQgPSAzNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjQgPSAzNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY0ID0gMzY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjQgPSAzNjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NCgpOwogICAgICAgIGJpdEZpZWxkMTFfID0gKGJpdEZpZWxkMTFfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY0ID0gMzY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2NSA9IDM2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDExXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY1ID0gMzY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY1ID0gMzY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2NSA9IDM2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY1ID0gMzY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjUoKTsKICAgICAgICBiaXRGaWVsZDExXyA9IChiaXRGaWVsZDExXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2NSA9IDM2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjYgPSAzNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMV8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2NiA9IDM2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2NiA9IDM2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjYgPSAzNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2NiA9IDM2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY2KCk7CiAgICAgICAgYml0RmllbGQxMV8gPSAoYml0RmllbGQxMV8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjYgPSAzNjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY3ID0gMzY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjcgPSAzNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjcgPSAzNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY3ID0gMzY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjcgPSAzNjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NygpOwogICAgICAgIGJpdEZpZWxkMTFfID0gKGJpdEZpZWxkMTFfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY3ID0gMzY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2OCA9IDM2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDExXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY4ID0gMzY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY4ID0gMzY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2OCA9IDM2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzY4ID0gMzY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjgoKTsKICAgICAgICBiaXRGaWVsZDExXyA9IChiaXRGaWVsZDExXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2OCA9IDM2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjkgPSAzNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMV8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2OSA9IDM2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2OSA9IDM2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjkgPSAzNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2OSA9IDM2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY5KCk7CiAgICAgICAgYml0RmllbGQxMV8gPSAoYml0RmllbGQxMV8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjkgPSAzNjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcwID0gMzcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzAgPSAzNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzAgPSAzNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcwID0gMzcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzAgPSAzNzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MCgpOwogICAgICAgIGJpdEZpZWxkMTFfID0gKGJpdEZpZWxkMTFfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcwID0gMzcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3MSA9IDM3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDExXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcxID0gMzcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcxID0gMzcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3MSA9IDM3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcxID0gMzcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzEoKTsKICAgICAgICBiaXRGaWVsZDExXyA9IChiaXRGaWVsZDExXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3MSA9IDM3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzIgPSAzNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMV8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3MiA9IDM3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3MiA9IDM3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzIgPSAzNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3MiA9IDM3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcyKCk7CiAgICAgICAgYml0RmllbGQxMV8gPSAoYml0RmllbGQxMV8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzIgPSAzNzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzczID0gMzczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzczKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzMgPSAzNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzczXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzMgPSAzNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzczQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzczXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzczID0gMzczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzczXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzMgPSAzNzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzczKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MygpOwogICAgICAgIGJpdEZpZWxkMTFfID0gKGJpdEZpZWxkMTFfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzczID0gMzczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzczQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NCA9IDM3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDExXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc0ID0gMzc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc0ID0gMzc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NCA9IDM3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc0ID0gMzc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzQoKTsKICAgICAgICBiaXRGaWVsZDExXyA9IChiaXRGaWVsZDExXyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NCA9IDM3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzUgPSAzNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMV8gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NSA9IDM3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NSA9IDM3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzUgPSAzNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NSA9IDM3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc1KCk7CiAgICAgICAgYml0RmllbGQxMV8gPSAoYml0RmllbGQxMV8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzUgPSAzNzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc2ID0gMzc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzYgPSAzNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzYgPSAzNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc2ID0gMzc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzYgPSAzNzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NigpOwogICAgICAgIGJpdEZpZWxkMTFfID0gKGJpdEZpZWxkMTFfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc2ID0gMzc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NyA9IDM3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDExXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc3ID0gMzc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc3ID0gMzc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NyA9IDM3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc3ID0gMzc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzcoKTsKICAgICAgICBiaXRGaWVsZDExXyA9IChiaXRGaWVsZDExXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3NyA9IDM3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzggPSAzNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMV8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3OCA9IDM3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3OCA9IDM3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzggPSAzNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3OCA9IDM3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc4KCk7CiAgICAgICAgYml0RmllbGQxMV8gPSAoYml0RmllbGQxMV8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzggPSAzNzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc5ID0gMzc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzkgPSAzNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzkgPSAzNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc5ID0gMzc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNzkgPSAzNzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3OSgpOwogICAgICAgIGJpdEZpZWxkMTFfID0gKGJpdEZpZWxkMTFfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc5ID0gMzc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MCA9IDM4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDExXyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgwID0gMzgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgwID0gMzgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MCA9IDM4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgwID0gMzgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODAoKTsKICAgICAgICBiaXRGaWVsZDExXyA9IChiaXRGaWVsZDExXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MCA9IDM4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODEgPSAzODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMV8gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MSA9IDM4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MSA9IDM4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODEgPSAzODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MSA9IDM4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgxKCk7CiAgICAgICAgYml0RmllbGQxMV8gPSAoYml0RmllbGQxMV8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODEgPSAzODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgyID0gMzgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTFfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODIgPSAzODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODIgPSAzODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgyID0gMzgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODIgPSAzODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MigpOwogICAgICAgIGJpdEZpZWxkMTFfID0gKGJpdEZpZWxkMTFfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgyID0gMzgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MyA9IDM4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDExXyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgzID0gMzgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgzID0gMzgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MyA9IDM4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzgzID0gMzgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODMoKTsKICAgICAgICBiaXRGaWVsZDExXyA9IChiaXRGaWVsZDExXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4MyA9IDM4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODQgPSAzODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMV8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NCA9IDM4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NCA9IDM4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODQgPSAzODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NCA9IDM4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg0KCk7CiAgICAgICAgYml0RmllbGQxMV8gPSAoYml0RmllbGQxMV8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODQgPSAzODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDExXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg1ID0gMzg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODUgPSAzODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODUgPSAzODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg1ID0gMzg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODUgPSAzODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NSgpOwogICAgICAgIGJpdEZpZWxkMTJfID0gKGJpdEZpZWxkMTJfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg1ID0gMzg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NiA9IDM4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEyXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg2ID0gMzg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg2ID0gMzg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NiA9IDM4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg2ID0gMzg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODYoKTsKICAgICAgICBiaXRGaWVsZDEyXyA9IChiaXRGaWVsZDEyXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NiA9IDM4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODcgPSAzODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMl8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NyA9IDM4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NyA9IDM4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODcgPSAzODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4NyA9IDM4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg3KCk7CiAgICAgICAgYml0RmllbGQxMl8gPSAoYml0RmllbGQxMl8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODcgPSAzODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg4ID0gMzg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODggPSAzODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODggPSAzODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg4ID0gMzg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODggPSAzODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OCgpOwogICAgICAgIGJpdEZpZWxkMTJfID0gKGJpdEZpZWxkMTJfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg4ID0gMzg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4OSA9IDM4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEyXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg5ID0gMzg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg5ID0gMzg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4OSA9IDM4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzg5ID0gMzg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODkoKTsKICAgICAgICBiaXRGaWVsZDEyXyA9IChiaXRGaWVsZDEyXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4OSA9IDM4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTAgPSAzOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMl8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MCA9IDM5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MCA9IDM5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTAgPSAzOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MCA9IDM5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkwKCk7CiAgICAgICAgYml0RmllbGQxMl8gPSAoYml0RmllbGQxMl8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTAgPSAzOTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkxID0gMzkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTEgPSAzOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTEgPSAzOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkxID0gMzkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTEgPSAzOTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MSgpOwogICAgICAgIGJpdEZpZWxkMTJfID0gKGJpdEZpZWxkMTJfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkxID0gMzkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MiA9IDM5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEyXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkyID0gMzkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkyID0gMzkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MiA9IDM5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzkyID0gMzkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTIoKTsKICAgICAgICBiaXRGaWVsZDEyXyA9IChiaXRGaWVsZDEyXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MiA9IDM5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTMgPSAzOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMl8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MyA9IDM5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MyA9IDM5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTMgPSAzOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5MyA9IDM5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkzKCk7CiAgICAgICAgYml0RmllbGQxMl8gPSAoYml0RmllbGQxMl8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTMgPSAzOTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk0ID0gMzk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTQgPSAzOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTQgPSAzOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk0ID0gMzk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTQgPSAzOTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NCgpOwogICAgICAgIGJpdEZpZWxkMTJfID0gKGJpdEZpZWxkMTJfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk0ID0gMzk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5NSA9IDM5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEyXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk1ID0gMzk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk1ID0gMzk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5NSA9IDM5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk1ID0gMzk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTUoKTsKICAgICAgICBiaXRGaWVsZDEyXyA9IChiaXRGaWVsZDEyXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5NSA9IDM5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTYgPSAzOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMl8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5NiA9IDM5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5NiA9IDM5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTYgPSAzOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5NiA9IDM5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk2KCk7CiAgICAgICAgYml0RmllbGQxMl8gPSAoYml0RmllbGQxMl8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTYgPSAzOTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk3ID0gMzk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTcgPSAzOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTcgPSAzOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk3ID0gMzk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTcgPSAzOTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NygpOwogICAgICAgIGJpdEZpZWxkMTJfID0gKGJpdEZpZWxkMTJfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk3ID0gMzk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5OCA9IDM5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEyXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk4ID0gMzk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk4ID0gMzk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOThfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5OCA9IDM5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk4ID0gMzk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTgoKTsKICAgICAgICBiaXRGaWVsZDEyXyA9IChiaXRGaWVsZDEyXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5OCA9IDM5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTkgPSAzOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMl8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5OSA9IDM5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5OSA9IDM5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTkgPSAzOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM5OSA9IDM5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk5KCk7CiAgICAgICAgYml0RmllbGQxMl8gPSAoYml0RmllbGQxMl8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTkgPSAzOTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAwID0gNDAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDAgPSA0MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDAgPSA0MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAwID0gNDAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDAgPSA0MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMCgpOwogICAgICAgIGJpdEZpZWxkMTJfID0gKGJpdEZpZWxkMTJfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAwID0gNDAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMSA9IDQwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEyXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAxID0gNDAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAxID0gNDAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMSA9IDQwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAxID0gNDAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDEoKTsKICAgICAgICBiaXRGaWVsZDEyXyA9IChiaXRGaWVsZDEyXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMSA9IDQwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDIgPSA0MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMl8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMiA9IDQwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMiA9IDQwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDIgPSA0MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMiA9IDQwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAyKCk7CiAgICAgICAgYml0RmllbGQxMl8gPSAoYml0RmllbGQxMl8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDIgPSA0MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAzID0gNDAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDMgPSA0MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDMgPSA0MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAzID0gNDAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDMgPSA0MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMygpOwogICAgICAgIGJpdEZpZWxkMTJfID0gKGJpdEZpZWxkMTJfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDAzID0gNDAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNCA9IDQwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEyXyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA0ID0gNDA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA0ID0gNDA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNCA9IDQwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA0ID0gNDA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDQoKTsKICAgICAgICBiaXRGaWVsZDEyXyA9IChiaXRGaWVsZDEyXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNCA9IDQwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDUgPSA0MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMl8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNSA9IDQwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNSA9IDQwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDUgPSA0MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNSA9IDQwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA1KCk7CiAgICAgICAgYml0RmllbGQxMl8gPSAoYml0RmllbGQxMl8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDUgPSA0MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA2ID0gNDA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDYgPSA0MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDYgPSA0MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA2ID0gNDA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDYgPSA0MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNigpOwogICAgICAgIGJpdEZpZWxkMTJfID0gKGJpdEZpZWxkMTJfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA2ID0gNDA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNyA9IDQwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEyXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA3ID0gNDA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA3ID0gNDA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwN187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNyA9IDQwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA3ID0gNDA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDcoKTsKICAgICAgICBiaXRGaWVsZDEyXyA9IChiaXRGaWVsZDEyXyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwNyA9IDQwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwN0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDggPSA0MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMl8gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwOCA9IDQwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwOCA9IDQwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDggPSA0MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwOCA9IDQwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA4KCk7CiAgICAgICAgYml0RmllbGQxMl8gPSAoYml0RmllbGQxMl8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDggPSA0MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA5ID0gNDA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDkgPSA0MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDkgPSA0MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA5ID0gNDA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MDkgPSA0MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwOSgpOwogICAgICAgIGJpdEZpZWxkMTJfID0gKGJpdEZpZWxkMTJfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDA5ID0gNDA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMCA9IDQxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEyXyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEwID0gNDEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEwID0gNDEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMCA9IDQxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEwID0gNDEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTAoKTsKICAgICAgICBiaXRGaWVsZDEyXyA9IChiaXRGaWVsZDEyXyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMCA9IDQxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDExXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTEgPSA0MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDExIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMl8gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMSA9IDQxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDExLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMSA9IDQxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDExXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTEgPSA0MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDExIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMSA9IDQxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDExKCk7CiAgICAgICAgYml0RmllbGQxMl8gPSAoYml0RmllbGQxMl8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTEgPSA0MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEyID0gNDEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTIgPSA0MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTIgPSA0MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEyID0gNDEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTIgPSA0MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMigpOwogICAgICAgIGJpdEZpZWxkMTJfID0gKGJpdEZpZWxkMTJfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEyID0gNDEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMyA9IDQxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEyXyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEzID0gNDEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEzID0gNDEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxM187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMyA9IDQxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDEzID0gNDEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTMoKTsKICAgICAgICBiaXRGaWVsZDEyXyA9IChiaXRGaWVsZDEyXyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxMyA9IDQxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxM0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTQgPSA0MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxMl8gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNCA9IDQxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNCA9IDQxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTQgPSA0MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNCA9IDQxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE0KCk7CiAgICAgICAgYml0RmllbGQxMl8gPSAoYml0RmllbGQxMl8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTQgPSA0MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE1ID0gNDE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTJfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTUgPSA0MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTUgPSA0MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE1ID0gNDE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTUgPSA0MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNSgpOwogICAgICAgIGJpdEZpZWxkMTJfID0gKGJpdEZpZWxkMTJfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE1ID0gNDE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxMl8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNiA9IDQxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEyXyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE2ID0gNDE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE2ID0gNDE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNiA9IDQxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEyXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE2ID0gNDE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTYoKTsKICAgICAgICBiaXRGaWVsZDEyXyA9IChiaXRGaWVsZDEyXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNiA9IDQxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTJfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTcgPSA0MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxM18gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNyA9IDQxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNyA9IDQxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTcgPSA0MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxNyA9IDQxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxN18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE3KCk7CiAgICAgICAgYml0RmllbGQxM18gPSAoYml0RmllbGQxM18gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTcgPSA0MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE4ID0gNDE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTggPSA0MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MThfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTggPSA0MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE4ID0gNDE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTggPSA0MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MThfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOCgpOwogICAgICAgIGJpdEZpZWxkMTNfID0gKGJpdEZpZWxkMTNfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE4ID0gNDE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxOSA9IDQxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEzXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE5ID0gNDE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE5ID0gNDE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxOSA9IDQxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE5ID0gNDE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTkoKTsKICAgICAgICBiaXRGaWVsZDEzXyA9IChiaXRGaWVsZDEzXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxOSA9IDQxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjAgPSA0MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxM18gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMCA9IDQyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMCA9IDQyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjAgPSA0MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMCA9IDQyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIwKCk7CiAgICAgICAgYml0RmllbGQxM18gPSAoYml0RmllbGQxM18gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjAgPSA0MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIxID0gNDIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjEgPSA0MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjEgPSA0MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIxID0gNDIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjEgPSA0MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMSgpOwogICAgICAgIGJpdEZpZWxkMTNfID0gKGJpdEZpZWxkMTNfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIxID0gNDIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMiA9IDQyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEzXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIyID0gNDIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIyID0gNDIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMiA9IDQyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIyID0gNDIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjIoKTsKICAgICAgICBiaXRGaWVsZDEzXyA9IChiaXRGaWVsZDEzXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMiA9IDQyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjMgPSA0MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxM18gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMyA9IDQyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMyA9IDQyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjMgPSA0MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyMyA9IDQyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIzKCk7CiAgICAgICAgYml0RmllbGQxM18gPSAoYml0RmllbGQxM18gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjMgPSA0MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI0ID0gNDI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjQgPSA0MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjQgPSA0MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI0ID0gNDI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjQgPSA0MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNCgpOwogICAgICAgIGJpdEZpZWxkMTNfID0gKGJpdEZpZWxkMTNfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI0ID0gNDI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNSA9IDQyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEzXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI1ID0gNDI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI1ID0gNDI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNSA9IDQyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI1ID0gNDI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjUoKTsKICAgICAgICBiaXRGaWVsZDEzXyA9IChiaXRGaWVsZDEzXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNSA9IDQyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjYgPSA0MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxM18gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNiA9IDQyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNiA9IDQyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjYgPSA0MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNiA9IDQyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI2KCk7CiAgICAgICAgYml0RmllbGQxM18gPSAoYml0RmllbGQxM18gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjYgPSA0MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI3ID0gNDI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjcgPSA0MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjcgPSA0MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI3ID0gNDI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjcgPSA0MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNygpOwogICAgICAgIGJpdEZpZWxkMTNfID0gKGJpdEZpZWxkMTNfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI3ID0gNDI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyOCA9IDQyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEzXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI4ID0gNDI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI4ID0gNDI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyOCA9IDQyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDI4ID0gNDI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjgoKTsKICAgICAgICBiaXRGaWVsZDEzXyA9IChiaXRGaWVsZDEzXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyOCA9IDQyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjkgPSA0MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxM18gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyOSA9IDQyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyOSA9IDQyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjkgPSA0MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyOSA9IDQyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI5KCk7CiAgICAgICAgYml0RmllbGQxM18gPSAoYml0RmllbGQxM18gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MjkgPSA0MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMwID0gNDMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzAgPSA0MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzAgPSA0MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMwID0gNDMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzAgPSA0MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMCgpOwogICAgICAgIGJpdEZpZWxkMTNfID0gKGJpdEZpZWxkMTNfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMwID0gNDMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzMSA9IDQzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEzXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMxID0gNDMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMxID0gNDMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzMSA9IDQzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMxID0gNDMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzEoKTsKICAgICAgICBiaXRGaWVsZDEzXyA9IChiaXRGaWVsZDEzXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzMSA9IDQzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzIgPSA0MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxM18gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzMiA9IDQzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzMiA9IDQzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzIgPSA0MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzMiA9IDQzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMyKCk7CiAgICAgICAgYml0RmllbGQxM18gPSAoYml0RmllbGQxM18gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzIgPSA0MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMzID0gNDMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzMgPSA0MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzMgPSA0MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMzID0gNDMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzMgPSA0MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMygpOwogICAgICAgIGJpdEZpZWxkMTNfID0gKGJpdEZpZWxkMTNfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMzID0gNDMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNCA9IDQzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEzXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM0ID0gNDM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM0ID0gNDM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNCA9IDQzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM0ID0gNDM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzQoKTsKICAgICAgICBiaXRGaWVsZDEzXyA9IChiaXRGaWVsZDEzXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNCA9IDQzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzUgPSA0MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxM18gJiAweDAwMDQwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNSA9IDQzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNSA9IDQzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzUgPSA0MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNSA9IDQzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM1KCk7CiAgICAgICAgYml0RmllbGQxM18gPSAoYml0RmllbGQxM18gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzUgPSA0MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM2ID0gNDM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzYgPSA0MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzYgPSA0MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM2ID0gNDM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzYgPSA0MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNigpOwogICAgICAgIGJpdEZpZWxkMTNfID0gKGJpdEZpZWxkMTNfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM2ID0gNDM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNyA9IDQzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEzXyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM3ID0gNDM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM3ID0gNDM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzN187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNyA9IDQzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM3ID0gNDM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzcoKTsKICAgICAgICBiaXRGaWVsZDEzXyA9IChiaXRGaWVsZDEzXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNyA9IDQzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzN0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzggPSA0MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxM18gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzOCA9IDQzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzOCA9IDQzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzggPSA0MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzOCA9IDQzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM4KCk7CiAgICAgICAgYml0RmllbGQxM18gPSAoYml0RmllbGQxM18gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzggPSA0MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM5ID0gNDM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzkgPSA0MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzkgPSA0MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM5ID0gNDM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MzkgPSA0MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzOSgpOwogICAgICAgIGJpdEZpZWxkMTNfID0gKGJpdEZpZWxkMTNfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDM5ID0gNDM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MCA9IDQ0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEzXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQwID0gNDQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQwID0gNDQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MCA9IDQ0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQwID0gNDQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDAoKTsKICAgICAgICBiaXRGaWVsZDEzXyA9IChiaXRGaWVsZDEzXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MCA9IDQ0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDEgPSA0NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxM18gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MSA9IDQ0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MSA9IDQ0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDEgPSA0NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MSA9IDQ0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQxKCk7CiAgICAgICAgYml0RmllbGQxM18gPSAoYml0RmllbGQxM18gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDEgPSA0NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQyID0gNDQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDIgPSA0NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDIgPSA0NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQyID0gNDQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDIgPSA0NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MigpOwogICAgICAgIGJpdEZpZWxkMTNfID0gKGJpdEZpZWxkMTNfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQyID0gNDQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MyA9IDQ0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEzXyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQzID0gNDQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQzID0gNDQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MyA9IDQ0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQzID0gNDQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDMoKTsKICAgICAgICBiaXRGaWVsZDEzXyA9IChiaXRGaWVsZDEzXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0MyA9IDQ0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDQgPSA0NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxM18gJiAweDA4MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NCA9IDQ0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NCA9IDQ0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDQgPSA0NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NCA9IDQ0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ0KCk7CiAgICAgICAgYml0RmllbGQxM18gPSAoYml0RmllbGQxM18gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDQgPSA0NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ1ID0gNDQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDUgPSA0NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDUgPSA0NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ1ID0gNDQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDUgPSA0NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NSgpOwogICAgICAgIGJpdEZpZWxkMTNfID0gKGJpdEZpZWxkMTNfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ1ID0gNDQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NiA9IDQ0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDEzXyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ2ID0gNDQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ2ID0gNDQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NiA9IDQ0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ2ID0gNDQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDYoKTsKICAgICAgICBiaXRGaWVsZDEzXyA9IChiaXRGaWVsZDEzXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NiA9IDQ0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDcgPSA0NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxM18gJiAweDQwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NyA9IDQ0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NyA9IDQ0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDcgPSA0NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0NyA9IDQ0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ3KCk7CiAgICAgICAgYml0RmllbGQxM18gPSAoYml0RmllbGQxM18gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDcgPSA0NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDEzXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ4ID0gNDQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTNfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDggPSA0NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDggPSA0NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ4ID0gNDQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTNfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDggPSA0NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OCgpOwogICAgICAgIGJpdEZpZWxkMTNfID0gKGJpdEZpZWxkMTNfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ4ID0gNDQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxM18gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0OSA9IDQ0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE0XyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ5ID0gNDQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ5ID0gNDQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0OSA9IDQ0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDQ5ID0gNDQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDkoKTsKICAgICAgICBiaXRGaWVsZDE0XyA9IChiaXRGaWVsZDE0XyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ0OSA9IDQ0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTAgPSA0NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MCA9IDQ1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MCA9IDQ1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTAgPSA0NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MCA9IDQ1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUwKCk7CiAgICAgICAgYml0RmllbGQxNF8gPSAoYml0RmllbGQxNF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTAgPSA0NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUxID0gNDUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTEgPSA0NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTEgPSA0NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUxID0gNDUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTEgPSA0NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MSgpOwogICAgICAgIGJpdEZpZWxkMTRfID0gKGJpdEZpZWxkMTRfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUxID0gNDUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MiA9IDQ1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE0XyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUyID0gNDUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUyID0gNDUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MiA9IDQ1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUyID0gNDUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTIoKTsKICAgICAgICBiaXRGaWVsZDE0XyA9IChiaXRGaWVsZDE0XyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MiA9IDQ1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTMgPSA0NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MyA9IDQ1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MyA9IDQ1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTMgPSA0NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1MyA9IDQ1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUzKCk7CiAgICAgICAgYml0RmllbGQxNF8gPSAoYml0RmllbGQxNF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTMgPSA0NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU0ID0gNDU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTQgPSA0NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTQgPSA0NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU0ID0gNDU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTQgPSA0NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NCgpOwogICAgICAgIGJpdEZpZWxkMTRfID0gKGJpdEZpZWxkMTRfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU0ID0gNDU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1NSA9IDQ1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE0XyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU1ID0gNDU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU1ID0gNDU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1NSA9IDQ1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU1ID0gNDU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTUoKTsKICAgICAgICBiaXRGaWVsZDE0XyA9IChiaXRGaWVsZDE0XyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1NSA9IDQ1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTYgPSA0NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1NiA9IDQ1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1NiA9IDQ1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTYgPSA0NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1NiA9IDQ1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU2KCk7CiAgICAgICAgYml0RmllbGQxNF8gPSAoYml0RmllbGQxNF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTYgPSA0NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU3ID0gNDU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTcgPSA0NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTcgPSA0NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU3ID0gNDU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTcgPSA0NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NygpOwogICAgICAgIGJpdEZpZWxkMTRfID0gKGJpdEZpZWxkMTRfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU3ID0gNDU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1OCA9IDQ1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE0XyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU4ID0gNDU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU4ID0gNDU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NThfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1OCA9IDQ1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU4ID0gNDU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTgoKTsKICAgICAgICBiaXRGaWVsZDE0XyA9IChiaXRGaWVsZDE0XyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1OCA9IDQ1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTkgPSA0NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNF8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1OSA9IDQ1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1OSA9IDQ1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTkgPSA0NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1OSA9IDQ1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU5KCk7CiAgICAgICAgYml0RmllbGQxNF8gPSAoYml0RmllbGQxNF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NTkgPSA0NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYwID0gNDYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjAgPSA0NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjAgPSA0NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYwID0gNDYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjAgPSA0NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MCgpOwogICAgICAgIGJpdEZpZWxkMTRfID0gKGJpdEZpZWxkMTRfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYwID0gNDYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2MSA9IDQ2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE0XyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYxID0gNDYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYxID0gNDYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2MSA9IDQ2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYxID0gNDYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjEoKTsKICAgICAgICBiaXRGaWVsZDE0XyA9IChiaXRGaWVsZDE0XyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2MSA9IDQ2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjIgPSA0NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNF8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2MiA9IDQ2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2MiA9IDQ2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjIgPSA0NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2MiA9IDQ2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYyKCk7CiAgICAgICAgYml0RmllbGQxNF8gPSAoYml0RmllbGQxNF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjIgPSA0NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYzID0gNDYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjMgPSA0NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjMgPSA0NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYzID0gNDYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjMgPSA0NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MygpOwogICAgICAgIGJpdEZpZWxkMTRfID0gKGJpdEZpZWxkMTRfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDYzID0gNDYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NCA9IDQ2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE0XyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY0ID0gNDY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY0ID0gNDY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NCA9IDQ2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY0ID0gNDY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjQoKTsKICAgICAgICBiaXRGaWVsZDE0XyA9IChiaXRGaWVsZDE0XyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NCA9IDQ2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjUgPSA0NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNF8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NSA9IDQ2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NSA9IDQ2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjUgPSA0NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NSA9IDQ2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY1KCk7CiAgICAgICAgYml0RmllbGQxNF8gPSAoYml0RmllbGQxNF8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjUgPSA0NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY2ID0gNDY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjYgPSA0NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjYgPSA0NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY2ID0gNDY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjYgPSA0NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NigpOwogICAgICAgIGJpdEZpZWxkMTRfID0gKGJpdEZpZWxkMTRfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY2ID0gNDY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NyA9IDQ2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE0XyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY3ID0gNDY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY3ID0gNDY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NyA9IDQ2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY3ID0gNDY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjcoKTsKICAgICAgICBiaXRGaWVsZDE0XyA9IChiaXRGaWVsZDE0XyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2NyA9IDQ2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjggPSA0NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNF8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2OCA9IDQ2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2OCA9IDQ2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjggPSA0NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2OCA9IDQ2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY4KCk7CiAgICAgICAgYml0RmllbGQxNF8gPSAoYml0RmllbGQxNF8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjggPSA0NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY5ID0gNDY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjkgPSA0NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjkgPSA0NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY5ID0gNDY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjkgPSA0NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2OSgpOwogICAgICAgIGJpdEZpZWxkMTRfID0gKGJpdEZpZWxkMTRfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDY5ID0gNDY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MCA9IDQ3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE0XyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcwID0gNDcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcwID0gNDcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MCA9IDQ3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcwID0gNDcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzAoKTsKICAgICAgICBiaXRGaWVsZDE0XyA9IChiaXRGaWVsZDE0XyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MCA9IDQ3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzEgPSA0NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNF8gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MSA9IDQ3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MSA9IDQ3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzEgPSA0NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MSA9IDQ3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcxKCk7CiAgICAgICAgYml0RmllbGQxNF8gPSAoYml0RmllbGQxNF8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzEgPSA0NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcyID0gNDcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzIgPSA0NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzIgPSA0NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcyID0gNDcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzIgPSA0NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MigpOwogICAgICAgIGJpdEZpZWxkMTRfID0gKGJpdEZpZWxkMTRfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDcyID0gNDcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MyA9IDQ3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE0XyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDczID0gNDczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDczKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDczXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDczID0gNDczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDczLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MyA9IDQ3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDczKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDczID0gNDczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDczXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzMoKTsKICAgICAgICBiaXRGaWVsZDE0XyA9IChiaXRGaWVsZDE0XyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3MyA9IDQ3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDczIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDczXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzQgPSA0NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNF8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NCA9IDQ3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NCA9IDQ3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzQgPSA0NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NCA9IDQ3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc0KCk7CiAgICAgICAgYml0RmllbGQxNF8gPSAoYml0RmllbGQxNF8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzQgPSA0NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc1ID0gNDc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzUgPSA0NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzUgPSA0NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc1ID0gNDc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzUgPSA0NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NSgpOwogICAgICAgIGJpdEZpZWxkMTRfID0gKGJpdEZpZWxkMTRfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc1ID0gNDc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NiA9IDQ3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE0XyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc2ID0gNDc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc2ID0gNDc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NiA9IDQ3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc2ID0gNDc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzYoKTsKICAgICAgICBiaXRGaWVsZDE0XyA9IChiaXRGaWVsZDE0XyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NiA9IDQ3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzcgPSA0NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNF8gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NyA9IDQ3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NyA9IDQ3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzcgPSA0NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3NyA9IDQ3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc3KCk7CiAgICAgICAgYml0RmllbGQxNF8gPSAoYml0RmllbGQxNF8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzcgPSA0NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc4ID0gNDc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTRfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzggPSA0NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzggPSA0NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc4ID0gNDc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzggPSA0NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OCgpOwogICAgICAgIGJpdEZpZWxkMTRfID0gKGJpdEZpZWxkMTRfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc4ID0gNDc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3OSA9IDQ3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE0XyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc5ID0gNDc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc5ID0gNDc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3OSA9IDQ3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc5ID0gNDc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzkoKTsKICAgICAgICBiaXRGaWVsZDE0XyA9IChiaXRGaWVsZDE0XyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ3OSA9IDQ3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTRfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODAgPSA0ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNF8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MCA9IDQ4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MCA9IDQ4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODAgPSA0ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MCA9IDQ4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgwKCk7CiAgICAgICAgYml0RmllbGQxNF8gPSAoYml0RmllbGQxNF8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODAgPSA0ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE0XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgxID0gNDgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODEgPSA0ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODEgPSA0ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgxID0gNDgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODEgPSA0ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MSgpOwogICAgICAgIGJpdEZpZWxkMTVfID0gKGJpdEZpZWxkMTVfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgxID0gNDgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MiA9IDQ4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE1XyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgyID0gNDgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgyID0gNDgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MiA9IDQ4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDgyID0gNDgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODIoKTsKICAgICAgICBiaXRGaWVsZDE1XyA9IChiaXRGaWVsZDE1XyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MiA9IDQ4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODMgPSA0ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNV8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MyA9IDQ4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MyA9IDQ4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODMgPSA0ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MyA9IDQ4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgzKCk7CiAgICAgICAgYml0RmllbGQxNV8gPSAoYml0RmllbGQxNV8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODMgPSA0ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg0ID0gNDg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODQgPSA0ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODQgPSA0ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg0ID0gNDg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODQgPSA0ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NCgpOwogICAgICAgIGJpdEZpZWxkMTVfID0gKGJpdEZpZWxkMTVfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg0ID0gNDg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4NSA9IDQ4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE1XyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg1ID0gNDg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg1ID0gNDg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4NSA9IDQ4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg1ID0gNDg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODUoKTsKICAgICAgICBiaXRGaWVsZDE1XyA9IChiaXRGaWVsZDE1XyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4NSA9IDQ4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODYgPSA0ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNV8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4NiA9IDQ4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4NiA9IDQ4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODYgPSA0ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4NiA9IDQ4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg2KCk7CiAgICAgICAgYml0RmllbGQxNV8gPSAoYml0RmllbGQxNV8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODYgPSA0ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg3ID0gNDg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODcgPSA0ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODcgPSA0ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg3ID0gNDg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODcgPSA0ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NygpOwogICAgICAgIGJpdEZpZWxkMTVfID0gKGJpdEZpZWxkMTVfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg3ID0gNDg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4OCA9IDQ4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE1XyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg4ID0gNDg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg4ID0gNDg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4OCA9IDQ4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDg4ID0gNDg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODgoKTsKICAgICAgICBiaXRGaWVsZDE1XyA9IChiaXRGaWVsZDE1XyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4OCA9IDQ4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODkgPSA0ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNV8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4OSA9IDQ4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4OSA9IDQ4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODkgPSA0ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4OSA9IDQ4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg5KCk7CiAgICAgICAgYml0RmllbGQxNV8gPSAoYml0RmllbGQxNV8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180ODkgPSA0ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkwID0gNDkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTAgPSA0OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTAgPSA0OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkwID0gNDkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTAgPSA0OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MCgpOwogICAgICAgIGJpdEZpZWxkMTVfID0gKGJpdEZpZWxkMTVfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkwID0gNDkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5MSA9IDQ5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE1XyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkxID0gNDkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkxID0gNDkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5MSA9IDQ5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkxID0gNDkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTEoKTsKICAgICAgICBiaXRGaWVsZDE1XyA9IChiaXRGaWVsZDE1XyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5MSA9IDQ5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTIgPSA0OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNV8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5MiA9IDQ5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5MiA9IDQ5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTIgPSA0OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5MiA9IDQ5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkyKCk7CiAgICAgICAgYml0RmllbGQxNV8gPSAoYml0RmllbGQxNV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTIgPSA0OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkzID0gNDkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTMgPSA0OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTMgPSA0OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkzID0gNDkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTMgPSA0OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MygpOwogICAgICAgIGJpdEZpZWxkMTVfID0gKGJpdEZpZWxkMTVfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDkzID0gNDkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NCA9IDQ5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE1XyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk0ID0gNDk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk0ID0gNDk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NCA9IDQ5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk0ID0gNDk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTQoKTsKICAgICAgICBiaXRGaWVsZDE1XyA9IChiaXRGaWVsZDE1XyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NCA9IDQ5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTUgPSA0OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNV8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NSA9IDQ5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NSA9IDQ5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTUgPSA0OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NSA9IDQ5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk1KCk7CiAgICAgICAgYml0RmllbGQxNV8gPSAoYml0RmllbGQxNV8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTUgPSA0OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk2ID0gNDk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTYgPSA0OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTYgPSA0OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk2ID0gNDk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTYgPSA0OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NigpOwogICAgICAgIGJpdEZpZWxkMTVfID0gKGJpdEZpZWxkMTVfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk2ID0gNDk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NyA9IDQ5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE1XyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk3ID0gNDk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk3ID0gNDk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NyA9IDQ5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk3ID0gNDk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTcoKTsKICAgICAgICBiaXRGaWVsZDE1XyA9IChiaXRGaWVsZDE1XyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5NyA9IDQ5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTggPSA0OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNV8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5OCA9IDQ5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OThfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5OCA9IDQ5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OThCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OThfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTggPSA0OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ5OCA9IDQ5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk4KCk7CiAgICAgICAgYml0RmllbGQxNV8gPSAoYml0RmllbGQxNV8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTggPSA0OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OThCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk5ID0gNDk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTkgPSA0OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTkgPSA0OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk5ID0gNDk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTkgPSA0OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5OSgpOwogICAgICAgIGJpdEZpZWxkMTVfID0gKGJpdEZpZWxkMTVfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk5ID0gNDk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMCA9IDUwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE1XyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAwID0gNTAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAwID0gNTAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMCA9IDUwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAwID0gNTAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDAoKTsKICAgICAgICBiaXRGaWVsZDE1XyA9IChiaXRGaWVsZDE1XyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMCA9IDUwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDEgPSA1MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNV8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMSA9IDUwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMSA9IDUwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDEgPSA1MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMSA9IDUwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAxKCk7CiAgICAgICAgYml0RmllbGQxNV8gPSAoYml0RmllbGQxNV8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDEgPSA1MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAyID0gNTAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDIgPSA1MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDIgPSA1MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAyID0gNTAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDIgPSA1MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMigpOwogICAgICAgIGJpdEZpZWxkMTVfID0gKGJpdEZpZWxkMTVfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAyID0gNTAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMyA9IDUwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE1XyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAzID0gNTAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAzID0gNTAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwM187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMyA9IDUwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTAzID0gNTAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDMoKTsKICAgICAgICBiaXRGaWVsZDE1XyA9IChiaXRGaWVsZDE1XyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwMyA9IDUwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwM0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDQgPSA1MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNV8gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNCA9IDUwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNCA9IDUwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDQgPSA1MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNCA9IDUwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA0KCk7CiAgICAgICAgYml0RmllbGQxNV8gPSAoYml0RmllbGQxNV8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDQgPSA1MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA1ID0gNTA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDUgPSA1MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDUgPSA1MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA1ID0gNTA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDUgPSA1MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNSgpOwogICAgICAgIGJpdEZpZWxkMTVfID0gKGJpdEZpZWxkMTVfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA1ID0gNTA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNiA9IDUwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE1XyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA2ID0gNTA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA2ID0gNTA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNiA9IDUwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA2ID0gNTA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDYoKTsKICAgICAgICBiaXRGaWVsZDE1XyA9IChiaXRGaWVsZDE1XyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNiA9IDUwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDcgPSA1MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNV8gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNyA9IDUwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNyA9IDUwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDcgPSA1MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwNyA9IDUwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwN18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA3KCk7CiAgICAgICAgYml0RmllbGQxNV8gPSAoYml0RmllbGQxNV8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDcgPSA1MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA4ID0gNTA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDggPSA1MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDggPSA1MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA4ID0gNTA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDggPSA1MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOCgpOwogICAgICAgIGJpdEZpZWxkMTVfID0gKGJpdEZpZWxkMTVfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA4ID0gNTA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwOSA9IDUwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE1XyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA5ID0gNTA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA5ID0gNTA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwOSA9IDUwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA5ID0gNTA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDkoKTsKICAgICAgICBiaXRGaWVsZDE1XyA9IChiaXRGaWVsZDE1XyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUwOSA9IDUwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTAgPSA1MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNV8gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMCA9IDUxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMCA9IDUxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTAgPSA1MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMCA9IDUxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEwKCk7CiAgICAgICAgYml0RmllbGQxNV8gPSAoYml0RmllbGQxNV8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTAgPSA1MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTExID0gNTExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTExKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTVfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTEgPSA1MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTExXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTEgPSA1MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTExQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTExXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTExID0gNTExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTExXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTEgPSA1MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTExKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMSgpOwogICAgICAgIGJpdEZpZWxkMTVfID0gKGJpdEZpZWxkMTVfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTExID0gNTExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTExQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMiA9IDUxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE1XyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEyID0gNTEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEyID0gNTEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMiA9IDUxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE1XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTEyID0gNTEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTIoKTsKICAgICAgICBiaXRGaWVsZDE1XyA9IChiaXRGaWVsZDE1XyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMiA9IDUxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTVfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTMgPSA1MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNl8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMyA9IDUxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMyA9IDUxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTMgPSA1MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxMyA9IDUxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEzKCk7CiAgICAgICAgYml0RmllbGQxNl8gPSAoYml0RmllbGQxNl8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTMgPSA1MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE0ID0gNTE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTQgPSA1MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTQgPSA1MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE0ID0gNTE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTQgPSA1MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNCgpOwogICAgICAgIGJpdEZpZWxkMTZfID0gKGJpdEZpZWxkMTZfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE0ID0gNTE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNSA9IDUxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE2XyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE1ID0gNTE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE1ID0gNTE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNSA9IDUxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE1ID0gNTE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTUoKTsKICAgICAgICBiaXRGaWVsZDE2XyA9IChiaXRGaWVsZDE2XyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNSA9IDUxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTYgPSA1MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNl8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNiA9IDUxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNiA9IDUxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTYgPSA1MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNiA9IDUxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE2KCk7CiAgICAgICAgYml0RmllbGQxNl8gPSAoYml0RmllbGQxNl8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTYgPSA1MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE3ID0gNTE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTcgPSA1MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTcgPSA1MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE3ID0gNTE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTcgPSA1MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNygpOwogICAgICAgIGJpdEZpZWxkMTZfID0gKGJpdEZpZWxkMTZfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE3ID0gNTE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxOCA9IDUxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE2XyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE4ID0gNTE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE4ID0gNTE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MThfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxOCA9IDUxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTE4ID0gNTE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTgoKTsKICAgICAgICBiaXRGaWVsZDE2XyA9IChiaXRGaWVsZDE2XyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxOCA9IDUxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTkgPSA1MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNl8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxOSA9IDUxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxOSA9IDUxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTkgPSA1MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxOSA9IDUxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE5KCk7CiAgICAgICAgYml0RmllbGQxNl8gPSAoYml0RmllbGQxNl8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MTkgPSA1MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIwID0gNTIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjAgPSA1MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjAgPSA1MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIwID0gNTIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjAgPSA1MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMCgpOwogICAgICAgIGJpdEZpZWxkMTZfID0gKGJpdEZpZWxkMTZfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIwID0gNTIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyMSA9IDUyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE2XyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIxID0gNTIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIxID0gNTIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyMSA9IDUyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIxID0gNTIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjEoKTsKICAgICAgICBiaXRGaWVsZDE2XyA9IChiaXRGaWVsZDE2XyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyMSA9IDUyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjIgPSA1MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNl8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyMiA9IDUyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyMiA9IDUyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjIgPSA1MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyMiA9IDUyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIyKCk7CiAgICAgICAgYml0RmllbGQxNl8gPSAoYml0RmllbGQxNl8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjIgPSA1MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIzID0gNTIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjMgPSA1MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjMgPSA1MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIzID0gNTIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjMgPSA1MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMygpOwogICAgICAgIGJpdEZpZWxkMTZfID0gKGJpdEZpZWxkMTZfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTIzID0gNTIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNCA9IDUyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE2XyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI0ID0gNTI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI0ID0gNTI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNCA9IDUyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI0ID0gNTI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjQoKTsKICAgICAgICBiaXRGaWVsZDE2XyA9IChiaXRGaWVsZDE2XyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNCA9IDUyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjUgPSA1MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNl8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNSA9IDUyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNSA9IDUyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjUgPSA1MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNSA9IDUyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI1KCk7CiAgICAgICAgYml0RmllbGQxNl8gPSAoYml0RmllbGQxNl8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjUgPSA1MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI2ID0gNTI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjYgPSA1MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjYgPSA1MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI2ID0gNTI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjYgPSA1MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNigpOwogICAgICAgIGJpdEZpZWxkMTZfID0gKGJpdEZpZWxkMTZfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI2ID0gNTI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNyA9IDUyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE2XyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI3ID0gNTI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI3ID0gNTI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyN187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNyA9IDUyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI3ID0gNTI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjcoKTsKICAgICAgICBiaXRGaWVsZDE2XyA9IChiaXRGaWVsZDE2XyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyNyA9IDUyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyN0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjggPSA1MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNl8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyOCA9IDUyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyOCA9IDUyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjggPSA1MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUyOCA9IDUyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI4KCk7CiAgICAgICAgYml0RmllbGQxNl8gPSAoYml0RmllbGQxNl8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjggPSA1MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI5ID0gNTI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjkgPSA1MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjkgPSA1MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI5ID0gNTI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjkgPSA1MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyOSgpOwogICAgICAgIGJpdEZpZWxkMTZfID0gKGJpdEZpZWxkMTZfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTI5ID0gNTI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMCA9IDUzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE2XyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMwID0gNTMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMwID0gNTMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMCA9IDUzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMwID0gNTMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzAoKTsKICAgICAgICBiaXRGaWVsZDE2XyA9IChiaXRGaWVsZDE2XyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMCA9IDUzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzEgPSA1MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNl8gJiAweDAwMDQwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMSA9IDUzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMSA9IDUzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzEgPSA1MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMSA9IDUzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMxKCk7CiAgICAgICAgYml0RmllbGQxNl8gPSAoYml0RmllbGQxNl8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzEgPSA1MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMyID0gNTMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzIgPSA1MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzIgPSA1MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMyID0gNTMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzIgPSA1MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMigpOwogICAgICAgIGJpdEZpZWxkMTZfID0gKGJpdEZpZWxkMTZfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMyID0gNTMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMyA9IDUzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE2XyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMzID0gNTMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMzID0gNTMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzM187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMyA9IDUzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMzID0gNTMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzMoKTsKICAgICAgICBiaXRGaWVsZDE2XyA9IChiaXRGaWVsZDE2XyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzMyA9IDUzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzM0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzQgPSA1MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNl8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNCA9IDUzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNCA9IDUzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzQgPSA1MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNCA9IDUzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM0KCk7CiAgICAgICAgYml0RmllbGQxNl8gPSAoYml0RmllbGQxNl8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzQgPSA1MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM1ID0gNTM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzUgPSA1MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzUgPSA1MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM1ID0gNTM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzUgPSA1MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNSgpOwogICAgICAgIGJpdEZpZWxkMTZfID0gKGJpdEZpZWxkMTZfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM1ID0gNTM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNiA9IDUzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE2XyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM2ID0gNTM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM2ID0gNTM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNiA9IDUzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM2ID0gNTM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzYoKTsKICAgICAgICBiaXRGaWVsZDE2XyA9IChiaXRGaWVsZDE2XyAmIH4weDAwODAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNiA9IDUzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzcgPSA1MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNl8gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNyA9IDUzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNyA9IDUzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzcgPSA1MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzNyA9IDUzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzN18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM3KCk7CiAgICAgICAgYml0RmllbGQxNl8gPSAoYml0RmllbGQxNl8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzcgPSA1MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM4ID0gNTM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzggPSA1MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzggPSA1MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM4ID0gNTM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MzggPSA1MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOCgpOwogICAgICAgIGJpdEZpZWxkMTZfID0gKGJpdEZpZWxkMTZfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM4ID0gNTM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzOSA9IDUzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE2XyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM5ID0gNTM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM5ID0gNTM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzOSA9IDUzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM5ID0gNTM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzkoKTsKICAgICAgICBiaXRGaWVsZDE2XyA9IChiaXRGaWVsZDE2XyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzOSA9IDUzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDAgPSA1NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNl8gJiAweDA4MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MCA9IDU0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MCA9IDU0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDAgPSA1NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MCA9IDU0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQwKCk7CiAgICAgICAgYml0RmllbGQxNl8gPSAoYml0RmllbGQxNl8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDAgPSA1NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQxID0gNTQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDEgPSA1NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDEgPSA1NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQxID0gNTQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDEgPSA1NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MSgpOwogICAgICAgIGJpdEZpZWxkMTZfID0gKGJpdEZpZWxkMTZfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQxID0gNTQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MiA9IDU0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE2XyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQyID0gNTQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQyID0gNTQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MiA9IDU0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQyID0gNTQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDIoKTsKICAgICAgICBiaXRGaWVsZDE2XyA9IChiaXRGaWVsZDE2XyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MiA9IDU0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDMgPSA1NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxNl8gJiAweDQwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MyA9IDU0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MyA9IDU0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDMgPSA1NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0MyA9IDU0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQzKCk7CiAgICAgICAgYml0RmllbGQxNl8gPSAoYml0RmllbGQxNl8gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDMgPSA1NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE2XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ0ID0gNTQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTZfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDQgPSA1NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDQgPSA1NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ0ID0gNTQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTZfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDQgPSA1NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NCgpOwogICAgICAgIGJpdEZpZWxkMTZfID0gKGJpdEZpZWxkMTZfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ0ID0gNTQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxNl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0NSA9IDU0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE3XyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ1ID0gNTQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ1ID0gNTQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0NSA9IDU0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ1ID0gNTQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDUoKTsKICAgICAgICBiaXRGaWVsZDE3XyA9IChiaXRGaWVsZDE3XyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0NSA9IDU0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDYgPSA1NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxN18gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0NiA9IDU0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0NiA9IDU0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDYgPSA1NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0NiA9IDU0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ2KCk7CiAgICAgICAgYml0RmllbGQxN18gPSAoYml0RmllbGQxN18gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDYgPSA1NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ3ID0gNTQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDcgPSA1NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDcgPSA1NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ3ID0gNTQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDcgPSA1NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NygpOwogICAgICAgIGJpdEZpZWxkMTdfID0gKGJpdEZpZWxkMTdfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ3ID0gNTQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0OCA9IDU0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE3XyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ4ID0gNTQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ4ID0gNTQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0OCA9IDU0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTQ4ID0gNTQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDgoKTsKICAgICAgICBiaXRGaWVsZDE3XyA9IChiaXRGaWVsZDE3XyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0OCA9IDU0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDkgPSA1NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxN18gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0OSA9IDU0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0OSA9IDU0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDkgPSA1NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0OSA9IDU0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ5KCk7CiAgICAgICAgYml0RmllbGQxN18gPSAoYml0RmllbGQxN18gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDkgPSA1NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUwID0gNTUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTAgPSA1NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTAgPSA1NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUwID0gNTUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTAgPSA1NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MCgpOwogICAgICAgIGJpdEZpZWxkMTdfID0gKGJpdEZpZWxkMTdfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUwID0gNTUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1MSA9IDU1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE3XyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUxID0gNTUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUxID0gNTUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1MSA9IDU1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUxID0gNTUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTEoKTsKICAgICAgICBiaXRGaWVsZDE3XyA9IChiaXRGaWVsZDE3XyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1MSA9IDU1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTIgPSA1NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxN18gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1MiA9IDU1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1MiA9IDU1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTIgPSA1NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1MiA9IDU1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUyKCk7CiAgICAgICAgYml0RmllbGQxN18gPSAoYml0RmllbGQxN18gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTIgPSA1NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUzID0gNTUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTMgPSA1NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTMgPSA1NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUzID0gNTUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTMgPSA1NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MygpOwogICAgICAgIGJpdEZpZWxkMTdfID0gKGJpdEZpZWxkMTdfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTUzID0gNTUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NCA9IDU1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE3XyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU0ID0gNTU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU0ID0gNTU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NCA9IDU1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU0ID0gNTU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTQoKTsKICAgICAgICBiaXRGaWVsZDE3XyA9IChiaXRGaWVsZDE3XyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NCA9IDU1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTUgPSA1NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxN18gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NSA9IDU1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NSA9IDU1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTUgPSA1NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NSA9IDU1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU1KCk7CiAgICAgICAgYml0RmllbGQxN18gPSAoYml0RmllbGQxN18gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTUgPSA1NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU2ID0gNTU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTYgPSA1NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTYgPSA1NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU2ID0gNTU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTYgPSA1NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NigpOwogICAgICAgIGJpdEZpZWxkMTdfID0gKGJpdEZpZWxkMTdfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU2ID0gNTU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NyA9IDU1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE3XyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU3ID0gNTU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU3ID0gNTU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NyA9IDU1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU3ID0gNTU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTcoKTsKICAgICAgICBiaXRGaWVsZDE3XyA9IChiaXRGaWVsZDE3XyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1NyA9IDU1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTggPSA1NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxN18gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1OCA9IDU1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NThfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1OCA9IDU1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NThCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NThfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTggPSA1NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1OCA9IDU1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU4KCk7CiAgICAgICAgYml0RmllbGQxN18gPSAoYml0RmllbGQxN18gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTggPSA1NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NThCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU5ID0gNTU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTkgPSA1NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTkgPSA1NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU5ID0gNTU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTkgPSA1NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1OSgpOwogICAgICAgIGJpdEZpZWxkMTdfID0gKGJpdEZpZWxkMTdfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU5ID0gNTU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MCA9IDU2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE3XyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYwID0gNTYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYwID0gNTYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MCA9IDU2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYwID0gNTYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjAoKTsKICAgICAgICBiaXRGaWVsZDE3XyA9IChiaXRGaWVsZDE3XyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MCA9IDU2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjEgPSA1NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxN18gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MSA9IDU2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MSA9IDU2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjEgPSA1NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MSA9IDU2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYxKCk7CiAgICAgICAgYml0RmllbGQxN18gPSAoYml0RmllbGQxN18gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjEgPSA1NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYyID0gNTYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjIgPSA1NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjIgPSA1NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYyID0gNTYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjIgPSA1NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MigpOwogICAgICAgIGJpdEZpZWxkMTdfID0gKGJpdEZpZWxkMTdfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYyID0gNTYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MyA9IDU2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE3XyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYzID0gNTYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYzID0gNTYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MyA9IDU2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTYzID0gNTYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjMoKTsKICAgICAgICBiaXRGaWVsZDE3XyA9IChiaXRGaWVsZDE3XyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MyA9IDU2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjQgPSA1NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxN18gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NCA9IDU2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NCA9IDU2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjQgPSA1NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NCA9IDU2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY0KCk7CiAgICAgICAgYml0RmllbGQxN18gPSAoYml0RmllbGQxN18gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjQgPSA1NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY1ID0gNTY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjUgPSA1NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjUgPSA1NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY1ID0gNTY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjUgPSA1NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NSgpOwogICAgICAgIGJpdEZpZWxkMTdfID0gKGJpdEZpZWxkMTdfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY1ID0gNTY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NiA9IDU2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE3XyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY2ID0gNTY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY2ID0gNTY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NiA9IDU2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY2ID0gNTY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjYoKTsKICAgICAgICBiaXRGaWVsZDE3XyA9IChiaXRGaWVsZDE3XyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NiA9IDU2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjcgPSA1NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxN18gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NyA9IDU2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NyA9IDU2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjcgPSA1NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2NyA9IDU2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY3KCk7CiAgICAgICAgYml0RmllbGQxN18gPSAoYml0RmllbGQxN18gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjcgPSA1NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY4ID0gNTY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjggPSA1NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjggPSA1NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY4ID0gNTY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NjggPSA1NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OCgpOwogICAgICAgIGJpdEZpZWxkMTdfID0gKGJpdEZpZWxkMTdfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY4ID0gNTY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2OSA9IDU2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE3XyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY5ID0gNTY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY5ID0gNTY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2OSA9IDU2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTY5ID0gNTY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjkoKTsKICAgICAgICBiaXRGaWVsZDE3XyA9IChiaXRGaWVsZDE3XyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2OSA9IDU2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzAgPSA1NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxN18gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MCA9IDU3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MCA9IDU3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzAgPSA1NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MCA9IDU3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcwKCk7CiAgICAgICAgYml0RmllbGQxN18gPSAoYml0RmllbGQxN18gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzAgPSA1NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcxID0gNTcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzEgPSA1NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzEgPSA1NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcxID0gNTcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzEgPSA1NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MSgpOwogICAgICAgIGJpdEZpZWxkMTdfID0gKGJpdEZpZWxkMTdfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcxID0gNTcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MiA9IDU3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE3XyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcyID0gNTcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcyID0gNTcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MiA9IDU3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTcyID0gNTcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzIoKTsKICAgICAgICBiaXRGaWVsZDE3XyA9IChiaXRGaWVsZDE3XyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MiA9IDU3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTczXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzMgPSA1NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTczIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxN18gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MyA9IDU3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTczLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MyA9IDU3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTczXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzMgPSA1NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTczIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3MyA9IDU3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTczKCk7CiAgICAgICAgYml0RmllbGQxN18gPSAoYml0RmllbGQxN18gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzMgPSA1NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc0ID0gNTc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTdfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzQgPSA1NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzQgPSA1NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc0ID0gNTc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzQgPSA1NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NCgpOwogICAgICAgIGJpdEZpZWxkMTdfID0gKGJpdEZpZWxkMTdfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc0ID0gNTc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NSA9IDU3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE3XyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc1ID0gNTc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc1ID0gNTc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NSA9IDU3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc1ID0gNTc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzUoKTsKICAgICAgICBiaXRGaWVsZDE3XyA9IChiaXRGaWVsZDE3XyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NSA9IDU3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTdfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzYgPSA1NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxN18gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NiA9IDU3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NiA9IDU3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzYgPSA1NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxN18gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NiA9IDU3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc2KCk7CiAgICAgICAgYml0RmllbGQxN18gPSAoYml0RmllbGQxN18gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzYgPSA1NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE3XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc3ID0gNTc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzcgPSA1NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzcgPSA1NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc3ID0gNTc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzcgPSA1NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NygpOwogICAgICAgIGJpdEZpZWxkMThfID0gKGJpdEZpZWxkMThfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc3ID0gNTc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3OCA9IDU3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE4XyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc4ID0gNTc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc4ID0gNTc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3OCA9IDU3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTc4ID0gNTc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzgoKTsKICAgICAgICBiaXRGaWVsZDE4XyA9IChiaXRGaWVsZDE4XyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3OCA9IDU3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzkgPSA1NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3OSA9IDU3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3OSA9IDU3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzkgPSA1NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3OSA9IDU3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc5KCk7CiAgICAgICAgYml0RmllbGQxOF8gPSAoYml0RmllbGQxOF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzkgPSA1NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgwID0gNTgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODAgPSA1ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODAgPSA1ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgwID0gNTgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODAgPSA1ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MCgpOwogICAgICAgIGJpdEZpZWxkMThfID0gKGJpdEZpZWxkMThfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgwID0gNTgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4MSA9IDU4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE4XyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgxID0gNTgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgxID0gNTgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4MSA9IDU4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgxID0gNTgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODEoKTsKICAgICAgICBiaXRGaWVsZDE4XyA9IChiaXRGaWVsZDE4XyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4MSA9IDU4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODIgPSA1ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4MiA9IDU4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4MiA9IDU4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODIgPSA1ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4MiA9IDU4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgyKCk7CiAgICAgICAgYml0RmllbGQxOF8gPSAoYml0RmllbGQxOF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODIgPSA1ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgzID0gNTgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODMgPSA1ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODMgPSA1ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgzID0gNTgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODMgPSA1ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MygpOwogICAgICAgIGJpdEZpZWxkMThfID0gKGJpdEZpZWxkMThfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTgzID0gNTgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NCA9IDU4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE4XyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg0ID0gNTg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg0ID0gNTg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NCA9IDU4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg0ID0gNTg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODQoKTsKICAgICAgICBiaXRGaWVsZDE4XyA9IChiaXRGaWVsZDE4XyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NCA9IDU4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODUgPSA1ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NSA9IDU4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NSA9IDU4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODUgPSA1ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NSA9IDU4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg1KCk7CiAgICAgICAgYml0RmllbGQxOF8gPSAoYml0RmllbGQxOF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODUgPSA1ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg2ID0gNTg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODYgPSA1ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODYgPSA1ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg2ID0gNTg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODYgPSA1ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NigpOwogICAgICAgIGJpdEZpZWxkMThfID0gKGJpdEZpZWxkMThfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg2ID0gNTg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NyA9IDU4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE4XyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg3ID0gNTg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg3ID0gNTg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NyA9IDU4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg3ID0gNTg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODcoKTsKICAgICAgICBiaXRGaWVsZDE4XyA9IChiaXRGaWVsZDE4XyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4NyA9IDU4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODggPSA1ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOF8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4OCA9IDU4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4OCA9IDU4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODggPSA1ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU4OCA9IDU4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg4KCk7CiAgICAgICAgYml0RmllbGQxOF8gPSAoYml0RmllbGQxOF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODggPSA1ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg5ID0gNTg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODkgPSA1ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODkgPSA1ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg5ID0gNTg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODkgPSA1ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4OSgpOwogICAgICAgIGJpdEZpZWxkMThfID0gKGJpdEZpZWxkMThfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg5ID0gNTg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MCA9IDU5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE4XyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkwID0gNTkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkwID0gNTkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MCA9IDU5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkwID0gNTkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTAoKTsKICAgICAgICBiaXRGaWVsZDE4XyA9IChiaXRGaWVsZDE4XyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MCA9IDU5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTEgPSA1OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOF8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MSA9IDU5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MSA9IDU5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTEgPSA1OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MSA9IDU5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkxKCk7CiAgICAgICAgYml0RmllbGQxOF8gPSAoYml0RmllbGQxOF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTEgPSA1OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkyID0gNTkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTIgPSA1OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTIgPSA1OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkyID0gNTkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTIgPSA1OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MigpOwogICAgICAgIGJpdEZpZWxkMThfID0gKGJpdEZpZWxkMThfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkyID0gNTkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MyA9IDU5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE4XyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkzID0gNTkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkzID0gNTkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MyA9IDU5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkzID0gNTkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTMoKTsKICAgICAgICBiaXRGaWVsZDE4XyA9IChiaXRGaWVsZDE4XyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5MyA9IDU5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTQgPSA1OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOF8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NCA9IDU5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NCA9IDU5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTQgPSA1OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NCA9IDU5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk0KCk7CiAgICAgICAgYml0RmllbGQxOF8gPSAoYml0RmllbGQxOF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTQgPSA1OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk1ID0gNTk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTUgPSA1OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTUgPSA1OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk1ID0gNTk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTUgPSA1OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NSgpOwogICAgICAgIGJpdEZpZWxkMThfID0gKGJpdEZpZWxkMThfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk1ID0gNTk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NiA9IDU5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE4XyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk2ID0gNTk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk2ID0gNTk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NiA9IDU5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk2ID0gNTk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTYoKTsKICAgICAgICBiaXRGaWVsZDE4XyA9IChiaXRGaWVsZDE4XyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NiA9IDU5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTcgPSA1OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOF8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NyA9IDU5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NyA9IDU5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTcgPSA1OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NyA9IDU5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk3KCk7CiAgICAgICAgYml0RmllbGQxOF8gPSAoYml0RmllbGQxOF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTcgPSA1OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk4ID0gNTk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTggPSA1OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OThfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTggPSA1OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk4ID0gNTk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181OTggPSA1OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OThfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OCgpOwogICAgICAgIGJpdEZpZWxkMThfID0gKGJpdEZpZWxkMThfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk4ID0gNTk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5OSA9IDU5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE4XyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk5ID0gNTk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk5ID0gNTk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5OSA9IDU5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTk5ID0gNTk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTkoKTsKICAgICAgICBiaXRGaWVsZDE4XyA9IChiaXRGaWVsZDE4XyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5OSA9IDU5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDAgPSA2MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOF8gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMCA9IDYwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMCA9IDYwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDAgPSA2MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMCA9IDYwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAwKCk7CiAgICAgICAgYml0RmllbGQxOF8gPSAoYml0RmllbGQxOF8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDAgPSA2MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAxID0gNjAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDEgPSA2MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDEgPSA2MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAxID0gNjAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDEgPSA2MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMSgpOwogICAgICAgIGJpdEZpZWxkMThfID0gKGJpdEZpZWxkMThfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAxID0gNjAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMiA9IDYwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE4XyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAyID0gNjAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAyID0gNjAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMiA9IDYwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjAyID0gNjAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDIoKTsKICAgICAgICBiaXRGaWVsZDE4XyA9IChiaXRGaWVsZDE4XyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMiA9IDYwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDMgPSA2MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOF8gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMyA9IDYwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMyA9IDYwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDMgPSA2MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwMyA9IDYwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAzKCk7CiAgICAgICAgYml0RmllbGQxOF8gPSAoYml0RmllbGQxOF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDMgPSA2MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA0ID0gNjA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDQgPSA2MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDQgPSA2MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA0ID0gNjA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDQgPSA2MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNCgpOwogICAgICAgIGJpdEZpZWxkMThfID0gKGJpdEZpZWxkMThfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA0ID0gNjA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwNSA9IDYwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE4XyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA1ID0gNjA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA1ID0gNjA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwNSA9IDYwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA1ID0gNjA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDUoKTsKICAgICAgICBiaXRGaWVsZDE4XyA9IChiaXRGaWVsZDE4XyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwNSA9IDYwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDYgPSA2MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOF8gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwNiA9IDYwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwNiA9IDYwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDYgPSA2MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwNiA9IDYwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA2KCk7CiAgICAgICAgYml0RmllbGQxOF8gPSAoYml0RmllbGQxOF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDYgPSA2MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA3ID0gNjA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMThfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDcgPSA2MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDcgPSA2MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA3ID0gNjA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDcgPSA2MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNygpOwogICAgICAgIGJpdEZpZWxkMThfID0gKGJpdEZpZWxkMThfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA3ID0gNjA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwOCA9IDYwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE4XyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA4ID0gNjA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA4ID0gNjA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwOCA9IDYwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE4XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjA4ID0gNjA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDgoKTsKICAgICAgICBiaXRGaWVsZDE4XyA9IChiaXRGaWVsZDE4XyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwOCA9IDYwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMThfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDkgPSA2MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOV8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwOSA9IDYwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwOSA9IDYwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDkgPSA2MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYwOSA9IDYwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA5KCk7CiAgICAgICAgYml0RmllbGQxOV8gPSAoYml0RmllbGQxOV8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDkgPSA2MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEwID0gNjEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTAgPSA2MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTAgPSA2MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEwID0gNjEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTAgPSA2MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMCgpOwogICAgICAgIGJpdEZpZWxkMTlfID0gKGJpdEZpZWxkMTlfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEwID0gNjEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxMSA9IDYxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE5XyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjExID0gNjExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjExKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjExXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjExID0gNjExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjExLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxMSA9IDYxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjExKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjExID0gNjExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjExXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTEoKTsKICAgICAgICBiaXRGaWVsZDE5XyA9IChiaXRGaWVsZDE5XyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxMSA9IDYxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjExIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjExXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTIgPSA2MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOV8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxMiA9IDYxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxMiA9IDYxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTIgPSA2MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxMiA9IDYxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEyKCk7CiAgICAgICAgYml0RmllbGQxOV8gPSAoYml0RmllbGQxOV8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTIgPSA2MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEzID0gNjEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTMgPSA2MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTMgPSA2MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEzID0gNjEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTMgPSA2MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMygpOwogICAgICAgIGJpdEZpZWxkMTlfID0gKGJpdEZpZWxkMTlfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEzID0gNjEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNCA9IDYxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE5XyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE0ID0gNjE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE0ID0gNjE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNCA9IDYxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE0ID0gNjE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTQoKTsKICAgICAgICBiaXRGaWVsZDE5XyA9IChiaXRGaWVsZDE5XyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNCA9IDYxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTUgPSA2MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOV8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNSA9IDYxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNSA9IDYxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTUgPSA2MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNSA9IDYxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE1KCk7CiAgICAgICAgYml0RmllbGQxOV8gPSAoYml0RmllbGQxOV8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTUgPSA2MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE2ID0gNjE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTYgPSA2MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTYgPSA2MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE2ID0gNjE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTYgPSA2MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNigpOwogICAgICAgIGJpdEZpZWxkMTlfID0gKGJpdEZpZWxkMTlfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE2ID0gNjE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNyA9IDYxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE5XyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE3ID0gNjE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE3ID0gNjE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxN187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNyA9IDYxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE3ID0gNjE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTcoKTsKICAgICAgICBiaXRGaWVsZDE5XyA9IChiaXRGaWVsZDE5XyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxNyA9IDYxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxN0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTggPSA2MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOV8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxOCA9IDYxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MThfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxOCA9IDYxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MThCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MThfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTggPSA2MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxOCA9IDYxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE4KCk7CiAgICAgICAgYml0RmllbGQxOV8gPSAoYml0RmllbGQxOV8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTggPSA2MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MThCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE5ID0gNjE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTkgPSA2MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTkgPSA2MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE5ID0gNjE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MTkgPSA2MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxOSgpOwogICAgICAgIGJpdEZpZWxkMTlfID0gKGJpdEZpZWxkMTlfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE5ID0gNjE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMCA9IDYyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE5XyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIwID0gNjIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIwID0gNjIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMCA9IDYyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIwID0gNjIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjAoKTsKICAgICAgICBiaXRGaWVsZDE5XyA9IChiaXRGaWVsZDE5XyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMCA9IDYyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjEgPSA2MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOV8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMSA9IDYyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMSA9IDYyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjEgPSA2MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMSA9IDYyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIxKCk7CiAgICAgICAgYml0RmllbGQxOV8gPSAoYml0RmllbGQxOV8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjEgPSA2MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIyID0gNjIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjIgPSA2MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjIgPSA2MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIyID0gNjIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjIgPSA2MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMigpOwogICAgICAgIGJpdEZpZWxkMTlfID0gKGJpdEZpZWxkMTlfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIyID0gNjIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMyA9IDYyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE5XyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIzID0gNjIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIzID0gNjIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyM187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMyA9IDYyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjIzID0gNjIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjMoKTsKICAgICAgICBiaXRGaWVsZDE5XyA9IChiaXRGaWVsZDE5XyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyMyA9IDYyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyM0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjQgPSA2MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOV8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNCA9IDYyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNCA9IDYyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjQgPSA2MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNCA9IDYyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI0KCk7CiAgICAgICAgYml0RmllbGQxOV8gPSAoYml0RmllbGQxOV8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjQgPSA2MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI1ID0gNjI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjUgPSA2MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjUgPSA2MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI1ID0gNjI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjUgPSA2MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNSgpOwogICAgICAgIGJpdEZpZWxkMTlfID0gKGJpdEZpZWxkMTlfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI1ID0gNjI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNiA9IDYyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE5XyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI2ID0gNjI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI2ID0gNjI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNiA9IDYyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI2ID0gNjI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjYoKTsKICAgICAgICBiaXRGaWVsZDE5XyA9IChiaXRGaWVsZDE5XyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNiA9IDYyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjcgPSA2MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOV8gJiAweDAwMDQwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNyA9IDYyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNyA9IDYyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjcgPSA2MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyNyA9IDYyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyN18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI3KCk7CiAgICAgICAgYml0RmllbGQxOV8gPSAoYml0RmllbGQxOV8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjcgPSA2MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI4ID0gNjI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjggPSA2MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjggPSA2MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI4ID0gNjI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjggPSA2MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOCgpOwogICAgICAgIGJpdEZpZWxkMTlfID0gKGJpdEZpZWxkMTlfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI4ID0gNjI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyOSA9IDYyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE5XyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI5ID0gNjI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI5ID0gNjI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyOSA9IDYyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjI5ID0gNjI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjkoKTsKICAgICAgICBiaXRGaWVsZDE5XyA9IChiaXRGaWVsZDE5XyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyOSA9IDYyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzAgPSA2MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOV8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMCA9IDYzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMCA9IDYzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzAgPSA2MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMCA9IDYzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMwKCk7CiAgICAgICAgYml0RmllbGQxOV8gPSAoYml0RmllbGQxOV8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzAgPSA2MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMxID0gNjMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzEgPSA2MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzEgPSA2MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMxID0gNjMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzEgPSA2MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMSgpOwogICAgICAgIGJpdEZpZWxkMTlfID0gKGJpdEZpZWxkMTlfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMxID0gNjMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMiA9IDYzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE5XyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMyID0gNjMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMyID0gNjMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMiA9IDYzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjMyID0gNjMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzIoKTsKICAgICAgICBiaXRGaWVsZDE5XyA9IChiaXRGaWVsZDE5XyAmIH4weDAwODAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMiA9IDYzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzMgPSA2MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOV8gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMyA9IDYzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMyA9IDYzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzMgPSA2MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzMyA9IDYzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMzKCk7CiAgICAgICAgYml0RmllbGQxOV8gPSAoYml0RmllbGQxOV8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzMgPSA2MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM0ID0gNjM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzQgPSA2MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzQgPSA2MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM0ID0gNjM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzQgPSA2MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNCgpOwogICAgICAgIGJpdEZpZWxkMTlfID0gKGJpdEZpZWxkMTlfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM0ID0gNjM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzNSA9IDYzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE5XyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM1ID0gNjM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM1ID0gNjM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzNSA9IDYzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM1ID0gNjM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzUoKTsKICAgICAgICBiaXRGaWVsZDE5XyA9IChiaXRGaWVsZDE5XyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzNSA9IDYzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzYgPSA2MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOV8gJiAweDA4MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzNiA9IDYzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzNiA9IDYzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzYgPSA2MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzNiA9IDYzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM2KCk7CiAgICAgICAgYml0RmllbGQxOV8gPSAoYml0RmllbGQxOV8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzYgPSA2MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM3ID0gNjM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzcgPSA2MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzcgPSA2MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM3ID0gNjM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzcgPSA2MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNygpOwogICAgICAgIGJpdEZpZWxkMTlfID0gKGJpdEZpZWxkMTlfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM3ID0gNjM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzOCA9IDYzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDE5XyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM4ID0gNjM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM4ID0gNjM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzOCA9IDYzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM4ID0gNjM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzgoKTsKICAgICAgICBiaXRGaWVsZDE5XyA9IChiaXRGaWVsZDE5XyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzOCA9IDYzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzkgPSA2MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxOV8gJiAweDQwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzOSA9IDYzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzOSA9IDYzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzkgPSA2MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYzOSA9IDYzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM5KCk7CiAgICAgICAgYml0RmllbGQxOV8gPSAoYml0RmllbGQxOV8gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzkgPSA2MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDE5XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQwID0gNjQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMTlfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDAgPSA2NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDAgPSA2NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQwID0gNjQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMTlfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDAgPSA2NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MCgpOwogICAgICAgIGJpdEZpZWxkMTlfID0gKGJpdEZpZWxkMTlfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQwID0gNjQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxOV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0MSA9IDY0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQxID0gNjQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQxID0gNjQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0MSA9IDY0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQxID0gNjQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDEoKTsKICAgICAgICBiaXRGaWVsZDIwXyA9IChiaXRGaWVsZDIwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0MSA9IDY0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDIgPSA2NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0MiA9IDY0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0MiA9IDY0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDIgPSA2NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0MiA9IDY0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQyKCk7CiAgICAgICAgYml0RmllbGQyMF8gPSAoYml0RmllbGQyMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDIgPSA2NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQzID0gNjQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDMgPSA2NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDMgPSA2NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQzID0gNjQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDMgPSA2NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MygpOwogICAgICAgIGJpdEZpZWxkMjBfID0gKGJpdEZpZWxkMjBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQzID0gNjQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NCA9IDY0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ0ID0gNjQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ0ID0gNjQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NCA9IDY0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ0ID0gNjQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDQoKTsKICAgICAgICBiaXRGaWVsZDIwXyA9IChiaXRGaWVsZDIwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NCA9IDY0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDUgPSA2NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NSA9IDY0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NSA9IDY0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDUgPSA2NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NSA9IDY0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ1KCk7CiAgICAgICAgYml0RmllbGQyMF8gPSAoYml0RmllbGQyMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDUgPSA2NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ2ID0gNjQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDYgPSA2NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDYgPSA2NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ2ID0gNjQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDYgPSA2NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NigpOwogICAgICAgIGJpdEZpZWxkMjBfID0gKGJpdEZpZWxkMjBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ2ID0gNjQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NyA9IDY0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ3ID0gNjQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ3ID0gNjQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NyA9IDY0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ3ID0gNjQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDcoKTsKICAgICAgICBiaXRGaWVsZDIwXyA9IChiaXRGaWVsZDIwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0NyA9IDY0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDggPSA2NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0OCA9IDY0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0OCA9IDY0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDggPSA2NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY0OCA9IDY0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ4KCk7CiAgICAgICAgYml0RmllbGQyMF8gPSAoYml0RmllbGQyMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDggPSA2NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ5ID0gNjQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDkgPSA2NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDkgPSA2NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ5ID0gNjQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NDkgPSA2NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0OSgpOwogICAgICAgIGJpdEZpZWxkMjBfID0gKGJpdEZpZWxkMjBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ5ID0gNjQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MCA9IDY1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUwID0gNjUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUwID0gNjUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MCA9IDY1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUwID0gNjUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTAoKTsKICAgICAgICBiaXRGaWVsZDIwXyA9IChiaXRGaWVsZDIwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MCA9IDY1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTEgPSA2NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMF8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MSA9IDY1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MSA9IDY1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTEgPSA2NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MSA9IDY1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUxKCk7CiAgICAgICAgYml0RmllbGQyMF8gPSAoYml0RmllbGQyMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTEgPSA2NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUyID0gNjUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTIgPSA2NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTIgPSA2NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUyID0gNjUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTIgPSA2NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MigpOwogICAgICAgIGJpdEZpZWxkMjBfID0gKGJpdEZpZWxkMjBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUyID0gNjUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MyA9IDY1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIwXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUzID0gNjUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUzID0gNjUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MyA9IDY1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjUzID0gNjUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTMoKTsKICAgICAgICBiaXRGaWVsZDIwXyA9IChiaXRGaWVsZDIwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MyA9IDY1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTQgPSA2NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMF8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NCA9IDY1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NCA9IDY1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTQgPSA2NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NCA9IDY1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU0KCk7CiAgICAgICAgYml0RmllbGQyMF8gPSAoYml0RmllbGQyMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTQgPSA2NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU1ID0gNjU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTUgPSA2NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTUgPSA2NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU1ID0gNjU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTUgPSA2NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NSgpOwogICAgICAgIGJpdEZpZWxkMjBfID0gKGJpdEZpZWxkMjBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU1ID0gNjU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NiA9IDY1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIwXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU2ID0gNjU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU2ID0gNjU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NiA9IDY1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU2ID0gNjU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTYoKTsKICAgICAgICBiaXRGaWVsZDIwXyA9IChiaXRGaWVsZDIwXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NiA9IDY1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTcgPSA2NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMF8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NyA9IDY1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NyA9IDY1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTcgPSA2NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NyA9IDY1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU3KCk7CiAgICAgICAgYml0RmllbGQyMF8gPSAoYml0RmllbGQyMF8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTcgPSA2NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU4ID0gNjU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTggPSA2NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NThfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTggPSA2NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU4ID0gNjU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NTggPSA2NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NThfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OCgpOwogICAgICAgIGJpdEZpZWxkMjBfID0gKGJpdEZpZWxkMjBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU4ID0gNjU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1OSA9IDY1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIwXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU5ID0gNjU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU5ID0gNjU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1OSA9IDY1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjU5ID0gNjU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTkoKTsKICAgICAgICBiaXRGaWVsZDIwXyA9IChiaXRGaWVsZDIwXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1OSA9IDY1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjAgPSA2NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMF8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MCA9IDY2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MCA9IDY2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjAgPSA2NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MCA9IDY2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYwKCk7CiAgICAgICAgYml0RmllbGQyMF8gPSAoYml0RmllbGQyMF8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjAgPSA2NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYxID0gNjYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjEgPSA2NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjEgPSA2NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYxID0gNjYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjEgPSA2NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MSgpOwogICAgICAgIGJpdEZpZWxkMjBfID0gKGJpdEZpZWxkMjBfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYxID0gNjYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MiA9IDY2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIwXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYyID0gNjYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYyID0gNjYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MiA9IDY2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjYyID0gNjYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjIoKTsKICAgICAgICBiaXRGaWVsZDIwXyA9IChiaXRGaWVsZDIwXyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MiA9IDY2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjMgPSA2NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMF8gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MyA9IDY2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MyA9IDY2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjMgPSA2NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2MyA9IDY2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYzKCk7CiAgICAgICAgYml0RmllbGQyMF8gPSAoYml0RmllbGQyMF8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjMgPSA2NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY0ID0gNjY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjQgPSA2NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjQgPSA2NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY0ID0gNjY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjQgPSA2NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NCgpOwogICAgICAgIGJpdEZpZWxkMjBfID0gKGJpdEZpZWxkMjBfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY0ID0gNjY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2NSA9IDY2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIwXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY1ID0gNjY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY1ID0gNjY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2NSA9IDY2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY1ID0gNjY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjUoKTsKICAgICAgICBiaXRGaWVsZDIwXyA9IChiaXRGaWVsZDIwXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2NSA9IDY2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjYgPSA2NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMF8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2NiA9IDY2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2NiA9IDY2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjYgPSA2NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2NiA9IDY2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY2KCk7CiAgICAgICAgYml0RmllbGQyMF8gPSAoYml0RmllbGQyMF8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjYgPSA2NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY3ID0gNjY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjcgPSA2NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjcgPSA2NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY3ID0gNjY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjcgPSA2NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NygpOwogICAgICAgIGJpdEZpZWxkMjBfID0gKGJpdEZpZWxkMjBfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY3ID0gNjY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2OCA9IDY2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIwXyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY4ID0gNjY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY4ID0gNjY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2OCA9IDY2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY4ID0gNjY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjgoKTsKICAgICAgICBiaXRGaWVsZDIwXyA9IChiaXRGaWVsZDIwXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2OCA9IDY2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjkgPSA2NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMF8gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2OSA9IDY2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2OSA9IDY2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjkgPSA2NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY2OSA9IDY2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY5KCk7CiAgICAgICAgYml0RmllbGQyMF8gPSAoYml0RmllbGQyMF8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjkgPSA2NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcwID0gNjcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjBfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzAgPSA2NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzAgPSA2NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcwID0gNjcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzAgPSA2NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MCgpOwogICAgICAgIGJpdEZpZWxkMjBfID0gKGJpdEZpZWxkMjBfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcwID0gNjcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3MSA9IDY3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIwXyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcxID0gNjcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcxID0gNjcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3MSA9IDY3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcxID0gNjcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzEoKTsKICAgICAgICBiaXRGaWVsZDIwXyA9IChiaXRGaWVsZDIwXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3MSA9IDY3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzIgPSA2NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMF8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3MiA9IDY3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3MiA9IDY3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzIgPSA2NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3MiA9IDY3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcyKCk7CiAgICAgICAgYml0RmllbGQyMF8gPSAoYml0RmllbGQyMF8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzIgPSA2NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjczID0gNjczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjczKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzMgPSA2NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjczXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzMgPSA2NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjczQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjczXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjczID0gNjczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjczXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzMgPSA2NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjczKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MygpOwogICAgICAgIGJpdEZpZWxkMjFfID0gKGJpdEZpZWxkMjFfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjczID0gNjczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjczQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NCA9IDY3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIxXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc0ID0gNjc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc0ID0gNjc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NCA9IDY3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc0ID0gNjc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzQoKTsKICAgICAgICBiaXRGaWVsZDIxXyA9IChiaXRGaWVsZDIxXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NCA9IDY3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzUgPSA2NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMV8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NSA9IDY3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NSA9IDY3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzUgPSA2NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NSA9IDY3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc1KCk7CiAgICAgICAgYml0RmllbGQyMV8gPSAoYml0RmllbGQyMV8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzUgPSA2NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc2ID0gNjc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzYgPSA2NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzYgPSA2NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc2ID0gNjc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzYgPSA2NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NigpOwogICAgICAgIGJpdEZpZWxkMjFfID0gKGJpdEZpZWxkMjFfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc2ID0gNjc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NyA9IDY3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIxXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc3ID0gNjc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc3ID0gNjc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NyA9IDY3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc3ID0gNjc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzcoKTsKICAgICAgICBiaXRGaWVsZDIxXyA9IChiaXRGaWVsZDIxXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NyA9IDY3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzggPSA2NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMV8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3OCA9IDY3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3OCA9IDY3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzggPSA2NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3OCA9IDY3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc4KCk7CiAgICAgICAgYml0RmllbGQyMV8gPSAoYml0RmllbGQyMV8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzggPSA2NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc5ID0gNjc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzkgPSA2NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzkgPSA2NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc5ID0gNjc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NzkgPSA2NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3OSgpOwogICAgICAgIGJpdEZpZWxkMjFfID0gKGJpdEZpZWxkMjFfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjc5ID0gNjc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MCA9IDY4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIxXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgwID0gNjgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgwID0gNjgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MCA9IDY4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgwID0gNjgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODAoKTsKICAgICAgICBiaXRGaWVsZDIxXyA9IChiaXRGaWVsZDIxXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MCA9IDY4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODEgPSA2ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMV8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MSA9IDY4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MSA9IDY4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODEgPSA2ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MSA9IDY4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgxKCk7CiAgICAgICAgYml0RmllbGQyMV8gPSAoYml0RmllbGQyMV8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODEgPSA2ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgyID0gNjgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODIgPSA2ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODIgPSA2ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgyID0gNjgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODIgPSA2ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MigpOwogICAgICAgIGJpdEZpZWxkMjFfID0gKGJpdEZpZWxkMjFfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgyID0gNjgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MyA9IDY4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIxXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgzID0gNjgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgzID0gNjgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MyA9IDY4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjgzID0gNjgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODMoKTsKICAgICAgICBiaXRGaWVsZDIxXyA9IChiaXRGaWVsZDIxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4MyA9IDY4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODQgPSA2ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMV8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NCA9IDY4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NCA9IDY4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODQgPSA2ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NCA9IDY4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg0KCk7CiAgICAgICAgYml0RmllbGQyMV8gPSAoYml0RmllbGQyMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODQgPSA2ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg1ID0gNjg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODUgPSA2ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODUgPSA2ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg1ID0gNjg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODUgPSA2ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NSgpOwogICAgICAgIGJpdEZpZWxkMjFfID0gKGJpdEZpZWxkMjFfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg1ID0gNjg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NiA9IDY4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIxXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg2ID0gNjg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg2ID0gNjg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NiA9IDY4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg2ID0gNjg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODYoKTsKICAgICAgICBiaXRGaWVsZDIxXyA9IChiaXRGaWVsZDIxXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NiA9IDY4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODcgPSA2ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMV8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NyA9IDY4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NyA9IDY4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODcgPSA2ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4NyA9IDY4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg3KCk7CiAgICAgICAgYml0RmllbGQyMV8gPSAoYml0RmllbGQyMV8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODcgPSA2ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg4ID0gNjg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODggPSA2ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODggPSA2ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg4ID0gNjg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODggPSA2ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OCgpOwogICAgICAgIGJpdEZpZWxkMjFfID0gKGJpdEZpZWxkMjFfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg4ID0gNjg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4OSA9IDY4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIxXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg5ID0gNjg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg5ID0gNjg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4OSA9IDY4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjg5ID0gNjg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODkoKTsKICAgICAgICBiaXRGaWVsZDIxXyA9IChiaXRGaWVsZDIxXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY4OSA9IDY4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTAgPSA2OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMV8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MCA9IDY5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MCA9IDY5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTAgPSA2OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MCA9IDY5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkwKCk7CiAgICAgICAgYml0RmllbGQyMV8gPSAoYml0RmllbGQyMV8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTAgPSA2OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkxID0gNjkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTEgPSA2OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTEgPSA2OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkxID0gNjkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTEgPSA2OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MSgpOwogICAgICAgIGJpdEZpZWxkMjFfID0gKGJpdEZpZWxkMjFfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkxID0gNjkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MiA9IDY5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIxXyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkyID0gNjkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkyID0gNjkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MiA9IDY5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkyID0gNjkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTIoKTsKICAgICAgICBiaXRGaWVsZDIxXyA9IChiaXRGaWVsZDIxXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MiA9IDY5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTMgPSA2OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMV8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MyA9IDY5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MyA9IDY5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTMgPSA2OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5MyA9IDY5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkzKCk7CiAgICAgICAgYml0RmllbGQyMV8gPSAoYml0RmllbGQyMV8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTMgPSA2OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk0ID0gNjk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTQgPSA2OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTQgPSA2OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk0ID0gNjk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTQgPSA2OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NCgpOwogICAgICAgIGJpdEZpZWxkMjFfID0gKGJpdEZpZWxkMjFfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk0ID0gNjk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5NSA9IDY5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIxXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk1ID0gNjk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk1ID0gNjk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5NSA9IDY5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk1ID0gNjk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTUoKTsKICAgICAgICBiaXRGaWVsZDIxXyA9IChiaXRGaWVsZDIxXyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5NSA9IDY5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTYgPSA2OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMV8gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5NiA9IDY5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5NiA9IDY5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTYgPSA2OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5NiA9IDY5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk2KCk7CiAgICAgICAgYml0RmllbGQyMV8gPSAoYml0RmllbGQyMV8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTYgPSA2OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk3ID0gNjk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTcgPSA2OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTcgPSA2OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk3ID0gNjk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTcgPSA2OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NygpOwogICAgICAgIGJpdEZpZWxkMjFfID0gKGJpdEZpZWxkMjFfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk3ID0gNjk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5OCA9IDY5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIxXyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk4ID0gNjk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk4ID0gNjk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OThfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5OCA9IDY5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk4ID0gNjk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTgoKTsKICAgICAgICBiaXRGaWVsZDIxXyA9IChiaXRGaWVsZDIxXyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5OCA9IDY5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTkgPSA2OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMV8gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5OSA9IDY5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5OSA9IDY5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTkgPSA2OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5OSA9IDY5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk5KCk7CiAgICAgICAgYml0RmllbGQyMV8gPSAoYml0RmllbGQyMV8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182OTkgPSA2OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAwID0gNzAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDAgPSA3MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDAgPSA3MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAwID0gNzAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDAgPSA3MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMCgpOwogICAgICAgIGJpdEZpZWxkMjFfID0gKGJpdEZpZWxkMjFfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAwID0gNzAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwMSA9IDcwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIxXyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAxID0gNzAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAxID0gNzAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwMSA9IDcwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAxID0gNzAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDEoKTsKICAgICAgICBiaXRGaWVsZDIxXyA9IChiaXRGaWVsZDIxXyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwMSA9IDcwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDIgPSA3MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMV8gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwMiA9IDcwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwMiA9IDcwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDIgPSA3MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwMiA9IDcwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAyKCk7CiAgICAgICAgYml0RmllbGQyMV8gPSAoYml0RmllbGQyMV8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDIgPSA3MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAzID0gNzAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjFfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDMgPSA3MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDMgPSA3MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAzID0gNzAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDMgPSA3MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMygpOwogICAgICAgIGJpdEZpZWxkMjFfID0gKGJpdEZpZWxkMjFfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzAzID0gNzAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNCA9IDcwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIxXyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA0ID0gNzA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA0ID0gNzA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNCA9IDcwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIxXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA0ID0gNzA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDQoKTsKICAgICAgICBiaXRGaWVsZDIxXyA9IChiaXRGaWVsZDIxXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNCA9IDcwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDUgPSA3MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMl8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNSA9IDcwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNSA9IDcwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDUgPSA3MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNSA9IDcwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA1KCk7CiAgICAgICAgYml0RmllbGQyMl8gPSAoYml0RmllbGQyMl8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDUgPSA3MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA2ID0gNzA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDYgPSA3MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDYgPSA3MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA2ID0gNzA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDYgPSA3MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNigpOwogICAgICAgIGJpdEZpZWxkMjJfID0gKGJpdEZpZWxkMjJfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA2ID0gNzA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNyA9IDcwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIyXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA3ID0gNzA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA3ID0gNzA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwN187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNyA9IDcwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA3ID0gNzA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDcoKTsKICAgICAgICBiaXRGaWVsZDIyXyA9IChiaXRGaWVsZDIyXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwNyA9IDcwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwN0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDggPSA3MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMl8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwOCA9IDcwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwOCA9IDcwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDggPSA3MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwOCA9IDcwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA4KCk7CiAgICAgICAgYml0RmllbGQyMl8gPSAoYml0RmllbGQyMl8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDggPSA3MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA5ID0gNzA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDkgPSA3MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDkgPSA3MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA5ID0gNzA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDkgPSA3MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwOSgpOwogICAgICAgIGJpdEZpZWxkMjJfID0gKGJpdEZpZWxkMjJfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzA5ID0gNzA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMCA9IDcxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIyXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEwID0gNzEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEwID0gNzEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMCA9IDcxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEwID0gNzEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTAoKTsKICAgICAgICBiaXRGaWVsZDIyXyA9IChiaXRGaWVsZDIyXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMCA9IDcxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzExXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTEgPSA3MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzExIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMl8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMSA9IDcxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzExLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMSA9IDcxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzExXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTEgPSA3MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzExIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMSA9IDcxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzExKCk7CiAgICAgICAgYml0RmllbGQyMl8gPSAoYml0RmllbGQyMl8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTEgPSA3MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEyID0gNzEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTIgPSA3MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTIgPSA3MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEyID0gNzEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTIgPSA3MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMigpOwogICAgICAgIGJpdEZpZWxkMjJfID0gKGJpdEZpZWxkMjJfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEyID0gNzEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMyA9IDcxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIyXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEzID0gNzEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEzID0gNzEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxM187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMyA9IDcxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzEzID0gNzEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTMoKTsKICAgICAgICBiaXRGaWVsZDIyXyA9IChiaXRGaWVsZDIyXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxMyA9IDcxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxM0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTQgPSA3MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMl8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNCA9IDcxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNCA9IDcxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTQgPSA3MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNCA9IDcxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE0KCk7CiAgICAgICAgYml0RmllbGQyMl8gPSAoYml0RmllbGQyMl8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTQgPSA3MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE1ID0gNzE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTUgPSA3MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTUgPSA3MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE1ID0gNzE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTUgPSA3MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNSgpOwogICAgICAgIGJpdEZpZWxkMjJfID0gKGJpdEZpZWxkMjJfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE1ID0gNzE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNiA9IDcxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIyXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE2ID0gNzE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE2ID0gNzE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNiA9IDcxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE2ID0gNzE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTYoKTsKICAgICAgICBiaXRGaWVsZDIyXyA9IChiaXRGaWVsZDIyXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNiA9IDcxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTcgPSA3MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMl8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNyA9IDcxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNyA9IDcxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTcgPSA3MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxNyA9IDcxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxN18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE3KCk7CiAgICAgICAgYml0RmllbGQyMl8gPSAoYml0RmllbGQyMl8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTcgPSA3MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE4ID0gNzE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTggPSA3MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MThfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTggPSA3MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE4ID0gNzE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTggPSA3MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MThfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOCgpOwogICAgICAgIGJpdEZpZWxkMjJfID0gKGJpdEZpZWxkMjJfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE4ID0gNzE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxOSA9IDcxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIyXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE5ID0gNzE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE5ID0gNzE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxOSA9IDcxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzE5ID0gNzE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTkoKTsKICAgICAgICBiaXRGaWVsZDIyXyA9IChiaXRGaWVsZDIyXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcxOSA9IDcxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjAgPSA3MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMl8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMCA9IDcyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMCA9IDcyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjAgPSA3MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMCA9IDcyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIwKCk7CiAgICAgICAgYml0RmllbGQyMl8gPSAoYml0RmllbGQyMl8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjAgPSA3MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIxID0gNzIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjEgPSA3MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjEgPSA3MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIxID0gNzIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjEgPSA3MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMSgpOwogICAgICAgIGJpdEZpZWxkMjJfID0gKGJpdEZpZWxkMjJfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIxID0gNzIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMiA9IDcyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIyXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIyID0gNzIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIyID0gNzIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMiA9IDcyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIyID0gNzIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjIoKTsKICAgICAgICBiaXRGaWVsZDIyXyA9IChiaXRGaWVsZDIyXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMiA9IDcyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjMgPSA3MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMl8gJiAweDAwMDQwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMyA9IDcyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMyA9IDcyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjMgPSA3MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyMyA9IDcyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIzKCk7CiAgICAgICAgYml0RmllbGQyMl8gPSAoYml0RmllbGQyMl8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjMgPSA3MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI0ID0gNzI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjQgPSA3MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjQgPSA3MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI0ID0gNzI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjQgPSA3MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNCgpOwogICAgICAgIGJpdEZpZWxkMjJfID0gKGJpdEZpZWxkMjJfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI0ID0gNzI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyNSA9IDcyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIyXyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI1ID0gNzI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI1ID0gNzI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyNSA9IDcyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI1ID0gNzI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjUoKTsKICAgICAgICBiaXRGaWVsZDIyXyA9IChiaXRGaWVsZDIyXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyNSA9IDcyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjYgPSA3MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMl8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyNiA9IDcyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyNiA9IDcyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjYgPSA3MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyNiA9IDcyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI2KCk7CiAgICAgICAgYml0RmllbGQyMl8gPSAoYml0RmllbGQyMl8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjYgPSA3MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI3ID0gNzI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjcgPSA3MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjcgPSA3MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI3ID0gNzI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjcgPSA3MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNygpOwogICAgICAgIGJpdEZpZWxkMjJfID0gKGJpdEZpZWxkMjJfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI3ID0gNzI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyOCA9IDcyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIyXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI4ID0gNzI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI4ID0gNzI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyOCA9IDcyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI4ID0gNzI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjgoKTsKICAgICAgICBiaXRGaWVsZDIyXyA9IChiaXRGaWVsZDIyXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyOCA9IDcyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjkgPSA3MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMl8gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyOSA9IDcyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyOSA9IDcyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjkgPSA3MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcyOSA9IDcyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI5KCk7CiAgICAgICAgYml0RmllbGQyMl8gPSAoYml0RmllbGQyMl8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MjkgPSA3MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMwID0gNzMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzAgPSA3MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzAgPSA3MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMwID0gNzMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzAgPSA3MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMCgpOwogICAgICAgIGJpdEZpZWxkMjJfID0gKGJpdEZpZWxkMjJfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMwID0gNzMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMSA9IDczMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIyXyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMxID0gNzMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMxID0gNzMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMSA9IDczMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMxID0gNzMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzEoKTsKICAgICAgICBiaXRGaWVsZDIyXyA9IChiaXRGaWVsZDIyXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMSA9IDczMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzIgPSA3MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMl8gJiAweDA4MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMiA9IDczMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMiA9IDczMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzIgPSA3MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMiA9IDczMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMyKCk7CiAgICAgICAgYml0RmllbGQyMl8gPSAoYml0RmllbGQyMl8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzIgPSA3MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMzID0gNzMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzMgPSA3MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzMgPSA3MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMzID0gNzMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzMgPSA3MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMygpOwogICAgICAgIGJpdEZpZWxkMjJfID0gKGJpdEZpZWxkMjJfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzMzID0gNzMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNCA9IDczNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIyXyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM0ID0gNzM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM0ID0gNzM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNCA9IDczNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM0ID0gNzM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzQoKTsKICAgICAgICBiaXRGaWVsZDIyXyA9IChiaXRGaWVsZDIyXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNCA9IDczNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzUgPSA3MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyMl8gJiAweDQwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNSA9IDczNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNSA9IDczNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzUgPSA3MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNSA9IDczNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM1KCk7CiAgICAgICAgYml0RmllbGQyMl8gPSAoYml0RmllbGQyMl8gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzUgPSA3MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIyXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM2ID0gNzM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjJfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzYgPSA3MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzYgPSA3MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM2ID0gNzM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjJfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzYgPSA3MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNigpOwogICAgICAgIGJpdEZpZWxkMjJfID0gKGJpdEZpZWxkMjJfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM2ID0gNzM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyMl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNyA9IDczNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIzXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM3ID0gNzM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM3ID0gNzM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczN187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNyA9IDczNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM3ID0gNzM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzcoKTsKICAgICAgICBiaXRGaWVsZDIzXyA9IChiaXRGaWVsZDIzXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNyA9IDczNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczN0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzggPSA3MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyM18gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczOCA9IDczOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczOCA9IDczOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzggPSA3MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczOCA9IDczOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM4KCk7CiAgICAgICAgYml0RmllbGQyM18gPSAoYml0RmllbGQyM18gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzggPSA3MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM5ID0gNzM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzkgPSA3MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzkgPSA3MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM5ID0gNzM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzkgPSA3MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczOSgpOwogICAgICAgIGJpdEZpZWxkMjNfID0gKGJpdEZpZWxkMjNfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzM5ID0gNzM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MCA9IDc0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIzXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQwID0gNzQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQwID0gNzQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MCA9IDc0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQwID0gNzQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDAoKTsKICAgICAgICBiaXRGaWVsZDIzXyA9IChiaXRGaWVsZDIzXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MCA9IDc0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDEgPSA3NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyM18gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MSA9IDc0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MSA9IDc0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDEgPSA3NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MSA9IDc0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQxKCk7CiAgICAgICAgYml0RmllbGQyM18gPSAoYml0RmllbGQyM18gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDEgPSA3NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQyID0gNzQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDIgPSA3NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDIgPSA3NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQyID0gNzQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDIgPSA3NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MigpOwogICAgICAgIGJpdEZpZWxkMjNfID0gKGJpdEZpZWxkMjNfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQyID0gNzQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MyA9IDc0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIzXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQzID0gNzQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQzID0gNzQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MyA9IDc0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQzID0gNzQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDMoKTsKICAgICAgICBiaXRGaWVsZDIzXyA9IChiaXRGaWVsZDIzXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0MyA9IDc0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDQgPSA3NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyM18gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NCA9IDc0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NCA9IDc0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDQgPSA3NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NCA9IDc0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ0KCk7CiAgICAgICAgYml0RmllbGQyM18gPSAoYml0RmllbGQyM18gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDQgPSA3NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ1ID0gNzQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDUgPSA3NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDUgPSA3NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ1ID0gNzQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDUgPSA3NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NSgpOwogICAgICAgIGJpdEZpZWxkMjNfID0gKGJpdEZpZWxkMjNfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ1ID0gNzQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NiA9IDc0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIzXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ2ID0gNzQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ2ID0gNzQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NiA9IDc0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ2ID0gNzQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDYoKTsKICAgICAgICBiaXRGaWVsZDIzXyA9IChiaXRGaWVsZDIzXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NiA9IDc0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDcgPSA3NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyM18gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NyA9IDc0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NyA9IDc0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDcgPSA3NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0NyA9IDc0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ3KCk7CiAgICAgICAgYml0RmllbGQyM18gPSAoYml0RmllbGQyM18gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDcgPSA3NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ4ID0gNzQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDggPSA3NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDggPSA3NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ4ID0gNzQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDggPSA3NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OCgpOwogICAgICAgIGJpdEZpZWxkMjNfID0gKGJpdEZpZWxkMjNfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ4ID0gNzQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0OSA9IDc0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIzXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ5ID0gNzQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ5ID0gNzQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0OSA9IDc0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ5ID0gNzQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDkoKTsKICAgICAgICBiaXRGaWVsZDIzXyA9IChiaXRGaWVsZDIzXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc0OSA9IDc0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTAgPSA3NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyM18gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MCA9IDc1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MCA9IDc1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTAgPSA3NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MCA9IDc1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUwKCk7CiAgICAgICAgYml0RmllbGQyM18gPSAoYml0RmllbGQyM18gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTAgPSA3NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUxID0gNzUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTEgPSA3NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTEgPSA3NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUxID0gNzUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTEgPSA3NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MSgpOwogICAgICAgIGJpdEZpZWxkMjNfID0gKGJpdEZpZWxkMjNfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUxID0gNzUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MiA9IDc1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIzXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUyID0gNzUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUyID0gNzUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MiA9IDc1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUyID0gNzUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTIoKTsKICAgICAgICBiaXRGaWVsZDIzXyA9IChiaXRGaWVsZDIzXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MiA9IDc1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTMgPSA3NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyM18gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MyA9IDc1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MyA9IDc1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTMgPSA3NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1MyA9IDc1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUzKCk7CiAgICAgICAgYml0RmllbGQyM18gPSAoYml0RmllbGQyM18gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTMgPSA3NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU0ID0gNzU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTQgPSA3NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTQgPSA3NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU0ID0gNzU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTQgPSA3NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NCgpOwogICAgICAgIGJpdEZpZWxkMjNfID0gKGJpdEZpZWxkMjNfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU0ID0gNzU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NSA9IDc1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIzXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU1ID0gNzU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU1ID0gNzU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NSA9IDc1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU1ID0gNzU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTUoKTsKICAgICAgICBiaXRGaWVsZDIzXyA9IChiaXRGaWVsZDIzXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NSA9IDc1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTYgPSA3NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyM18gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NiA9IDc1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NiA9IDc1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTYgPSA3NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NiA9IDc1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU2KCk7CiAgICAgICAgYml0RmllbGQyM18gPSAoYml0RmllbGQyM18gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTYgPSA3NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU3ID0gNzU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTcgPSA3NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTcgPSA3NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU3ID0gNzU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTcgPSA3NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NygpOwogICAgICAgIGJpdEZpZWxkMjNfID0gKGJpdEZpZWxkMjNfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU3ID0gNzU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1OCA9IDc1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIzXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU4ID0gNzU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU4ID0gNzU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NThfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1OCA9IDc1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzU4ID0gNzU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTgoKTsKICAgICAgICBiaXRGaWVsZDIzXyA9IChiaXRGaWVsZDIzXyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1OCA9IDc1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTkgPSA3NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyM18gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1OSA9IDc1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1OSA9IDc1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTkgPSA3NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1OSA9IDc1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU5KCk7CiAgICAgICAgYml0RmllbGQyM18gPSAoYml0RmllbGQyM18gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NTkgPSA3NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYwID0gNzYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjAgPSA3NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjAgPSA3NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYwID0gNzYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjAgPSA3NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MCgpOwogICAgICAgIGJpdEZpZWxkMjNfID0gKGJpdEZpZWxkMjNfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYwID0gNzYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2MSA9IDc2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIzXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYxID0gNzYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYxID0gNzYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2MSA9IDc2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYxID0gNzYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjEoKTsKICAgICAgICBiaXRGaWVsZDIzXyA9IChiaXRGaWVsZDIzXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2MSA9IDc2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjIgPSA3NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyM18gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2MiA9IDc2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2MiA9IDc2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjIgPSA3NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2MiA9IDc2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYyKCk7CiAgICAgICAgYml0RmllbGQyM18gPSAoYml0RmllbGQyM18gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjIgPSA3NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYzID0gNzYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjMgPSA3NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjMgPSA3NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYzID0gNzYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjMgPSA3NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MygpOwogICAgICAgIGJpdEZpZWxkMjNfID0gKGJpdEZpZWxkMjNfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzYzID0gNzYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NCA9IDc2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIzXyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY0ID0gNzY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY0ID0gNzY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NCA9IDc2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY0ID0gNzY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjQoKTsKICAgICAgICBiaXRGaWVsZDIzXyA9IChiaXRGaWVsZDIzXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NCA9IDc2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjUgPSA3NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyM18gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NSA9IDc2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NSA9IDc2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjUgPSA3NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NSA9IDc2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY1KCk7CiAgICAgICAgYml0RmllbGQyM18gPSAoYml0RmllbGQyM18gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjUgPSA3NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY2ID0gNzY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjNfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjYgPSA3NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjYgPSA3NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY2ID0gNzY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjYgPSA3NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NigpOwogICAgICAgIGJpdEZpZWxkMjNfID0gKGJpdEZpZWxkMjNfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY2ID0gNzY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NyA9IDc2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDIzXyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY3ID0gNzY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY3ID0gNzY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NyA9IDc2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY3ID0gNzY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjcoKTsKICAgICAgICBiaXRGaWVsZDIzXyA9IChiaXRGaWVsZDIzXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2NyA9IDc2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjNfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjggPSA3NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyM18gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2OCA9IDc2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2OCA9IDc2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjggPSA3NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyM18gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc2OCA9IDc2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY4KCk7CiAgICAgICAgYml0RmllbGQyM18gPSAoYml0RmllbGQyM18gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjggPSA3NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDIzXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY5ID0gNzY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjkgPSA3NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjkgPSA3NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY5ID0gNzY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjkgPSA3NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2OSgpOwogICAgICAgIGJpdEZpZWxkMjRfID0gKGJpdEZpZWxkMjRfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzY5ID0gNzY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MCA9IDc3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI0XyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcwID0gNzcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcwID0gNzcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MCA9IDc3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcwID0gNzcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzAoKTsKICAgICAgICBiaXRGaWVsZDI0XyA9IChiaXRGaWVsZDI0XyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MCA9IDc3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzEgPSA3NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MSA9IDc3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MSA9IDc3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzEgPSA3NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MSA9IDc3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcxKCk7CiAgICAgICAgYml0RmllbGQyNF8gPSAoYml0RmllbGQyNF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzEgPSA3NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcyID0gNzcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzIgPSA3NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzIgPSA3NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcyID0gNzcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzIgPSA3NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MigpOwogICAgICAgIGJpdEZpZWxkMjRfID0gKGJpdEZpZWxkMjRfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcyID0gNzcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MyA9IDc3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI0XyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzczID0gNzczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzczKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzczXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzczID0gNzczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzczLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MyA9IDc3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzczKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzczID0gNzczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzczXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzMoKTsKICAgICAgICBiaXRGaWVsZDI0XyA9IChiaXRGaWVsZDI0XyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3MyA9IDc3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzczIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzczXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzQgPSA3NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NCA9IDc3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NCA9IDc3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzQgPSA3NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NCA9IDc3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc0KCk7CiAgICAgICAgYml0RmllbGQyNF8gPSAoYml0RmllbGQyNF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzQgPSA3NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc1ID0gNzc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzUgPSA3NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzUgPSA3NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc1ID0gNzc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzUgPSA3NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NSgpOwogICAgICAgIGJpdEZpZWxkMjRfID0gKGJpdEZpZWxkMjRfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc1ID0gNzc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NiA9IDc3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI0XyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc2ID0gNzc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc2ID0gNzc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NiA9IDc3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc2ID0gNzc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzYoKTsKICAgICAgICBiaXRGaWVsZDI0XyA9IChiaXRGaWVsZDI0XyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NiA9IDc3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzcgPSA3NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NyA9IDc3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NyA9IDc3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzcgPSA3NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3NyA9IDc3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc3KCk7CiAgICAgICAgYml0RmllbGQyNF8gPSAoYml0RmllbGQyNF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzcgPSA3NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc4ID0gNzc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzggPSA3NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzggPSA3NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc4ID0gNzc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NzggPSA3NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OCgpOwogICAgICAgIGJpdEZpZWxkMjRfID0gKGJpdEZpZWxkMjRfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc4ID0gNzc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3OSA9IDc3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI0XyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc5ID0gNzc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc5ID0gNzc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3OSA9IDc3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc5ID0gNzc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzkoKTsKICAgICAgICBiaXRGaWVsZDI0XyA9IChiaXRGaWVsZDI0XyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3OSA9IDc3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODAgPSA3ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNF8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MCA9IDc4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MCA9IDc4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODAgPSA3ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MCA9IDc4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgwKCk7CiAgICAgICAgYml0RmllbGQyNF8gPSAoYml0RmllbGQyNF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODAgPSA3ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgxID0gNzgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODEgPSA3ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODEgPSA3ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgxID0gNzgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODEgPSA3ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MSgpOwogICAgICAgIGJpdEZpZWxkMjRfID0gKGJpdEZpZWxkMjRfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgxID0gNzgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MiA9IDc4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI0XyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgyID0gNzgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgyID0gNzgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MiA9IDc4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzgyID0gNzgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODIoKTsKICAgICAgICBiaXRGaWVsZDI0XyA9IChiaXRGaWVsZDI0XyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MiA9IDc4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODMgPSA3ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNF8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MyA9IDc4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MyA9IDc4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODMgPSA3ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4MyA9IDc4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgzKCk7CiAgICAgICAgYml0RmllbGQyNF8gPSAoYml0RmllbGQyNF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODMgPSA3ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg0ID0gNzg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODQgPSA3ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODQgPSA3ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg0ID0gNzg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODQgPSA3ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NCgpOwogICAgICAgIGJpdEZpZWxkMjRfID0gKGJpdEZpZWxkMjRfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg0ID0gNzg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NSA9IDc4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI0XyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg1ID0gNzg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg1ID0gNzg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NSA9IDc4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg1ID0gNzg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODUoKTsKICAgICAgICBiaXRGaWVsZDI0XyA9IChiaXRGaWVsZDI0XyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NSA9IDc4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODYgPSA3ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNF8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NiA9IDc4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NiA9IDc4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODYgPSA3ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NiA9IDc4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg2KCk7CiAgICAgICAgYml0RmllbGQyNF8gPSAoYml0RmllbGQyNF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODYgPSA3ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg3ID0gNzg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODcgPSA3ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODcgPSA3ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg3ID0gNzg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODcgPSA3ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NygpOwogICAgICAgIGJpdEZpZWxkMjRfID0gKGJpdEZpZWxkMjRfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg3ID0gNzg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4OCA9IDc4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI0XyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg4ID0gNzg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg4ID0gNzg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4OCA9IDc4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzg4ID0gNzg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODgoKTsKICAgICAgICBiaXRGaWVsZDI0XyA9IChiaXRGaWVsZDI0XyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4OCA9IDc4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODkgPSA3ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNF8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4OSA9IDc4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4OSA9IDc4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODkgPSA3ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4OSA9IDc4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg5KCk7CiAgICAgICAgYml0RmllbGQyNF8gPSAoYml0RmllbGQyNF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183ODkgPSA3ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkwID0gNzkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTAgPSA3OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTAgPSA3OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkwID0gNzkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTAgPSA3OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MCgpOwogICAgICAgIGJpdEZpZWxkMjRfID0gKGJpdEZpZWxkMjRfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkwID0gNzkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MSA9IDc5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI0XyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkxID0gNzkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkxID0gNzkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MSA9IDc5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkxID0gNzkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTEoKTsKICAgICAgICBiaXRGaWVsZDI0XyA9IChiaXRGaWVsZDI0XyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MSA9IDc5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTIgPSA3OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNF8gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MiA9IDc5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MiA9IDc5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTIgPSA3OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MiA9IDc5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkyKCk7CiAgICAgICAgYml0RmllbGQyNF8gPSAoYml0RmllbGQyNF8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTIgPSA3OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkzID0gNzkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTMgPSA3OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTMgPSA3OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkzID0gNzkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTMgPSA3OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MygpOwogICAgICAgIGJpdEZpZWxkMjRfID0gKGJpdEZpZWxkMjRfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzkzID0gNzkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NCA9IDc5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI0XyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk0ID0gNzk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk0ID0gNzk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NCA9IDc5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk0ID0gNzk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTQoKTsKICAgICAgICBiaXRGaWVsZDI0XyA9IChiaXRGaWVsZDI0XyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NCA9IDc5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTUgPSA3OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNF8gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NSA9IDc5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NSA9IDc5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTUgPSA3OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NSA9IDc5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk1KCk7CiAgICAgICAgYml0RmllbGQyNF8gPSAoYml0RmllbGQyNF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTUgPSA3OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk2ID0gNzk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTYgPSA3OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTYgPSA3OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk2ID0gNzk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTYgPSA3OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NigpOwogICAgICAgIGJpdEZpZWxkMjRfID0gKGJpdEZpZWxkMjRfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk2ID0gNzk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NyA9IDc5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI0XyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk3ID0gNzk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk3ID0gNzk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NyA9IDc5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk3ID0gNzk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTcoKTsKICAgICAgICBiaXRGaWVsZDI0XyA9IChiaXRGaWVsZDI0XyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5NyA9IDc5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTggPSA3OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNF8gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5OCA9IDc5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OThfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5OCA9IDc5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OThCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OThfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTggPSA3OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5OCA9IDc5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk4KCk7CiAgICAgICAgYml0RmllbGQyNF8gPSAoYml0RmllbGQyNF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTggPSA3OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OThCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk5ID0gNzk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjRfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTkgPSA3OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTkgPSA3OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk5ID0gNzk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTkgPSA3OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5OSgpOwogICAgICAgIGJpdEZpZWxkMjRfID0gKGJpdEZpZWxkMjRfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzk5ID0gNzk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMCA9IDgwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI0XyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAwID0gODAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAwID0gODAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMCA9IDgwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI0XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAwID0gODAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDAoKTsKICAgICAgICBiaXRGaWVsZDI0XyA9IChiaXRGaWVsZDI0XyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMCA9IDgwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjRfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDEgPSA4MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNV8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMSA9IDgwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMSA9IDgwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDEgPSA4MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMSA9IDgwMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAxKCk7CiAgICAgICAgYml0RmllbGQyNV8gPSAoYml0RmllbGQyNV8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDEgPSA4MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAyID0gODAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDIgPSA4MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDIgPSA4MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAyID0gODAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDIgPSA4MDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMigpOwogICAgICAgIGJpdEZpZWxkMjVfID0gKGJpdEZpZWxkMjVfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAyID0gODAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMyA9IDgwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI1XyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAzID0gODAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAzID0gODAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwM187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMyA9IDgwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAzID0gODAzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDMoKTsKICAgICAgICBiaXRGaWVsZDI1XyA9IChiaXRGaWVsZDI1XyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwMyA9IDgwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwM0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDQgPSA4MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNV8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNCA9IDgwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNCA9IDgwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDQgPSA4MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNCA9IDgwNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA0KCk7CiAgICAgICAgYml0RmllbGQyNV8gPSAoYml0RmllbGQyNV8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDQgPSA4MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA1ID0gODA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDUgPSA4MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDUgPSA4MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA1ID0gODA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDUgPSA4MDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNSgpOwogICAgICAgIGJpdEZpZWxkMjVfID0gKGJpdEZpZWxkMjVfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA1ID0gODA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNiA9IDgwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI1XyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA2ID0gODA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA2ID0gODA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNiA9IDgwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA2ID0gODA2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDYoKTsKICAgICAgICBiaXRGaWVsZDI1XyA9IChiaXRGaWVsZDI1XyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNiA9IDgwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDcgPSA4MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNV8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNyA9IDgwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNyA9IDgwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDcgPSA4MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwNyA9IDgwNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwN18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA3KCk7CiAgICAgICAgYml0RmllbGQyNV8gPSAoYml0RmllbGQyNV8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDcgPSA4MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA4ID0gODA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDggPSA4MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDggPSA4MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA4ID0gODA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MDggPSA4MDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOCgpOwogICAgICAgIGJpdEZpZWxkMjVfID0gKGJpdEZpZWxkMjVfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA4ID0gODA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwOSA9IDgwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI1XyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA5ID0gODA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA5ID0gODA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwOSA9IDgwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA5ID0gODA5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDkoKTsKICAgICAgICBiaXRGaWVsZDI1XyA9IChiaXRGaWVsZDI1XyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgwOSA9IDgwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTAgPSA4MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNV8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMCA9IDgxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMCA9IDgxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTAgPSA4MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMCA9IDgxMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEwKCk7CiAgICAgICAgYml0RmllbGQyNV8gPSAoYml0RmllbGQyNV8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTAgPSA4MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODExID0gODExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODExKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTEgPSA4MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODExXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTEgPSA4MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODExQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODExXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODExID0gODExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODExXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTEgPSA4MTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODExKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMSgpOwogICAgICAgIGJpdEZpZWxkMjVfID0gKGJpdEZpZWxkMjVfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODExID0gODExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODExQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMiA9IDgxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI1XyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEyID0gODEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEyID0gODEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMiA9IDgxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODEyID0gODEyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTIoKTsKICAgICAgICBiaXRGaWVsZDI1XyA9IChiaXRGaWVsZDI1XyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMiA9IDgxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTMgPSA4MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNV8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMyA9IDgxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMyA9IDgxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTMgPSA4MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMyA9IDgxMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEzKCk7CiAgICAgICAgYml0RmllbGQyNV8gPSAoYml0RmllbGQyNV8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTMgPSA4MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE0ID0gODE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTQgPSA4MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTQgPSA4MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE0ID0gODE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTQgPSA4MTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNCgpOwogICAgICAgIGJpdEZpZWxkMjVfID0gKGJpdEZpZWxkMjVfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE0ID0gODE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNSA9IDgxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI1XyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE1ID0gODE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE1ID0gODE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNSA9IDgxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE1ID0gODE1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTUoKTsKICAgICAgICBiaXRGaWVsZDI1XyA9IChiaXRGaWVsZDI1XyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNSA9IDgxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTYgPSA4MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNV8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNiA9IDgxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNiA9IDgxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTYgPSA4MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNiA9IDgxNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE2KCk7CiAgICAgICAgYml0RmllbGQyNV8gPSAoYml0RmllbGQyNV8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTYgPSA4MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE3ID0gODE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTcgPSA4MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTcgPSA4MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE3ID0gODE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTcgPSA4MTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNygpOwogICAgICAgIGJpdEZpZWxkMjVfID0gKGJpdEZpZWxkMjVfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE3ID0gODE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxOCA9IDgxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI1XyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE4ID0gODE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE4ID0gODE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MThfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxOCA9IDgxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODE4ID0gODE4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTgoKTsKICAgICAgICBiaXRGaWVsZDI1XyA9IChiaXRGaWVsZDI1XyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxOCA9IDgxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTkgPSA4MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNV8gJiAweDAwMDQwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxOSA9IDgxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxOSA9IDgxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTkgPSA4MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxOSA9IDgxOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE5KCk7CiAgICAgICAgYml0RmllbGQyNV8gPSAoYml0RmllbGQyNV8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MTkgPSA4MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIwID0gODIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjAgPSA4MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjAgPSA4MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIwID0gODIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjAgPSA4MjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMCgpOwogICAgICAgIGJpdEZpZWxkMjVfID0gKGJpdEZpZWxkMjVfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIwID0gODIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyMSA9IDgyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI1XyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIxID0gODIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIxID0gODIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyMSA9IDgyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIxID0gODIxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjEoKTsKICAgICAgICBiaXRGaWVsZDI1XyA9IChiaXRGaWVsZDI1XyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyMSA9IDgyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjIgPSA4MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNV8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyMiA9IDgyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyMiA9IDgyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjIgPSA4MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyMiA9IDgyMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIyKCk7CiAgICAgICAgYml0RmllbGQyNV8gPSAoYml0RmllbGQyNV8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjIgPSA4MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIzID0gODIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjMgPSA4MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjMgPSA4MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIzID0gODIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjMgPSA4MjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMygpOwogICAgICAgIGJpdEZpZWxkMjVfID0gKGJpdEZpZWxkMjVfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODIzID0gODIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNCA9IDgyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI1XyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI0ID0gODI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI0ID0gODI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNCA9IDgyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI0ID0gODI0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjQoKTsKICAgICAgICBiaXRGaWVsZDI1XyA9IChiaXRGaWVsZDI1XyAmIH4weDAwODAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNCA9IDgyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjUgPSA4MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNV8gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNSA9IDgyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNSA9IDgyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjUgPSA4MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNSA9IDgyNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI1KCk7CiAgICAgICAgYml0RmllbGQyNV8gPSAoYml0RmllbGQyNV8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjUgPSA4MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI2ID0gODI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjYgPSA4MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjYgPSA4MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI2ID0gODI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjYgPSA4MjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNigpOwogICAgICAgIGJpdEZpZWxkMjVfID0gKGJpdEZpZWxkMjVfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI2ID0gODI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNyA9IDgyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI1XyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI3ID0gODI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI3ID0gODI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyN187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNyA9IDgyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI3ID0gODI3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjcoKTsKICAgICAgICBiaXRGaWVsZDI1XyA9IChiaXRGaWVsZDI1XyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyNyA9IDgyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyN0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjggPSA4MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNV8gJiAweDA4MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyOCA9IDgyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyOCA9IDgyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjggPSA4MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgyOCA9IDgyOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI4KCk7CiAgICAgICAgYml0RmllbGQyNV8gPSAoYml0RmllbGQyNV8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjggPSA4MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI5ID0gODI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjkgPSA4MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjkgPSA4MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI5ID0gODI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjkgPSA4MjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyOSgpOwogICAgICAgIGJpdEZpZWxkMjVfID0gKGJpdEZpZWxkMjVfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI5ID0gODI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMCA9IDgzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI1XyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMwID0gODMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMwID0gODMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMCA9IDgzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMwID0gODMwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzAoKTsKICAgICAgICBiaXRGaWVsZDI1XyA9IChiaXRGaWVsZDI1XyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMCA9IDgzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzEgPSA4MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNV8gJiAweDQwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMSA9IDgzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMSA9IDgzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzEgPSA4MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMSA9IDgzMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMxKCk7CiAgICAgICAgYml0RmllbGQyNV8gPSAoYml0RmllbGQyNV8gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzEgPSA4MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI1XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMyID0gODMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjVfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzIgPSA4MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzIgPSA4MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMyID0gODMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjVfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzIgPSA4MzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMigpOwogICAgICAgIGJpdEZpZWxkMjVfID0gKGJpdEZpZWxkMjVfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMyID0gODMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMyA9IDgzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI2XyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMzID0gODMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMzID0gODMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzM187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMyA9IDgzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMzID0gODMzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzMoKTsKICAgICAgICBiaXRGaWVsZDI2XyA9IChiaXRGaWVsZDI2XyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzMyA9IDgzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzM0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzQgPSA4MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNl8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNCA9IDgzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNCA9IDgzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzQgPSA4MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNCA9IDgzNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM0KCk7CiAgICAgICAgYml0RmllbGQyNl8gPSAoYml0RmllbGQyNl8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzQgPSA4MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM1ID0gODM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzUgPSA4MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzUgPSA4MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM1ID0gODM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzUgPSA4MzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNSgpOwogICAgICAgIGJpdEZpZWxkMjZfID0gKGJpdEZpZWxkMjZfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM1ID0gODM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNiA9IDgzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI2XyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM2ID0gODM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM2ID0gODM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNiA9IDgzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM2ID0gODM2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzYoKTsKICAgICAgICBiaXRGaWVsZDI2XyA9IChiaXRGaWVsZDI2XyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNiA9IDgzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzcgPSA4MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNl8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNyA9IDgzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNyA9IDgzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzcgPSA4MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNyA9IDgzNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzN18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM3KCk7CiAgICAgICAgYml0RmllbGQyNl8gPSAoYml0RmllbGQyNl8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzcgPSA4MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM4ID0gODM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzggPSA4MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzggPSA4MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM4ID0gODM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MzggPSA4MzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOCgpOwogICAgICAgIGJpdEZpZWxkMjZfID0gKGJpdEZpZWxkMjZfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM4ID0gODM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzOSA9IDgzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI2XyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM5ID0gODM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM5ID0gODM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzOSA9IDgzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODM5ID0gODM5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzkoKTsKICAgICAgICBiaXRGaWVsZDI2XyA9IChiaXRGaWVsZDI2XyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzOSA9IDgzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDAgPSA4NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNl8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MCA9IDg0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MCA9IDg0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDAgPSA4NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MCA9IDg0MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQwKCk7CiAgICAgICAgYml0RmllbGQyNl8gPSAoYml0RmllbGQyNl8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDAgPSA4NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQxID0gODQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDEgPSA4NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDEgPSA4NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQxID0gODQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDEgPSA4NDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MSgpOwogICAgICAgIGJpdEZpZWxkMjZfID0gKGJpdEZpZWxkMjZfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQxID0gODQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MiA9IDg0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI2XyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQyID0gODQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQyID0gODQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MiA9IDg0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQyID0gODQyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDIoKTsKICAgICAgICBiaXRGaWVsZDI2XyA9IChiaXRGaWVsZDI2XyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MiA9IDg0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDMgPSA4NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNl8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MyA9IDg0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MyA9IDg0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDMgPSA4NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0MyA9IDg0MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQzKCk7CiAgICAgICAgYml0RmllbGQyNl8gPSAoYml0RmllbGQyNl8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDMgPSA4NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ0ID0gODQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDQgPSA4NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDQgPSA4NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ0ID0gODQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDQgPSA4NDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NCgpOwogICAgICAgIGJpdEZpZWxkMjZfID0gKGJpdEZpZWxkMjZfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ0ID0gODQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0NSA9IDg0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI2XyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ1ID0gODQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ1ID0gODQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0NSA9IDg0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ1ID0gODQ1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDUoKTsKICAgICAgICBiaXRGaWVsZDI2XyA9IChiaXRGaWVsZDI2XyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0NSA9IDg0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDYgPSA4NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNl8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0NiA9IDg0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0NiA9IDg0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDYgPSA4NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0NiA9IDg0NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ2KCk7CiAgICAgICAgYml0RmllbGQyNl8gPSAoYml0RmllbGQyNl8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDYgPSA4NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ3ID0gODQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDcgPSA4NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDcgPSA4NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ3ID0gODQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDcgPSA4NDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NygpOwogICAgICAgIGJpdEZpZWxkMjZfID0gKGJpdEZpZWxkMjZfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ3ID0gODQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0OCA9IDg0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI2XyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ4ID0gODQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ4ID0gODQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0OCA9IDg0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODQ4ID0gODQ4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDgoKTsKICAgICAgICBiaXRGaWVsZDI2XyA9IChiaXRGaWVsZDI2XyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0OCA9IDg0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDkgPSA4NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNl8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0OSA9IDg0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0OSA9IDg0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDkgPSA4NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg0OSA9IDg0OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ5KCk7CiAgICAgICAgYml0RmllbGQyNl8gPSAoYml0RmllbGQyNl8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDkgPSA4NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUwID0gODUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTAgPSA4NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTAgPSA4NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUwID0gODUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTAgPSA4NTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MCgpOwogICAgICAgIGJpdEZpZWxkMjZfID0gKGJpdEZpZWxkMjZfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUwID0gODUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1MSA9IDg1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI2XyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUxID0gODUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUxID0gODUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1MSA9IDg1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUxID0gODUxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTEoKTsKICAgICAgICBiaXRGaWVsZDI2XyA9IChiaXRGaWVsZDI2XyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1MSA9IDg1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTIgPSA4NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNl8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1MiA9IDg1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1MiA9IDg1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTIgPSA4NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1MiA9IDg1MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUyKCk7CiAgICAgICAgYml0RmllbGQyNl8gPSAoYml0RmllbGQyNl8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTIgPSA4NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUzID0gODUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTMgPSA4NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTMgPSA4NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUzID0gODUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTMgPSA4NTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MygpOwogICAgICAgIGJpdEZpZWxkMjZfID0gKGJpdEZpZWxkMjZfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUzID0gODUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NCA9IDg1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI2XyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU0ID0gODU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU0ID0gODU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NCA9IDg1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU0ID0gODU0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTQoKTsKICAgICAgICBiaXRGaWVsZDI2XyA9IChiaXRGaWVsZDI2XyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NCA9IDg1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTUgPSA4NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNl8gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NSA9IDg1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NSA9IDg1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTUgPSA4NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NSA9IDg1NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU1KCk7CiAgICAgICAgYml0RmllbGQyNl8gPSAoYml0RmllbGQyNl8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTUgPSA4NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU2ID0gODU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTYgPSA4NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTYgPSA4NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU2ID0gODU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTYgPSA4NTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NigpOwogICAgICAgIGJpdEZpZWxkMjZfID0gKGJpdEZpZWxkMjZfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU2ID0gODU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NyA9IDg1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI2XyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU3ID0gODU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU3ID0gODU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NyA9IDg1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU3ID0gODU3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTcoKTsKICAgICAgICBiaXRGaWVsZDI2XyA9IChiaXRGaWVsZDI2XyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1NyA9IDg1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTggPSA4NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNl8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1OCA9IDg1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NThfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1OCA9IDg1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NThCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NThfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTggPSA4NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg1OCA9IDg1OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU4KCk7CiAgICAgICAgYml0RmllbGQyNl8gPSAoYml0RmllbGQyNl8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTggPSA4NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NThCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU5ID0gODU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTkgPSA4NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTkgPSA4NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU5ID0gODU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTkgPSA4NTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1OSgpOwogICAgICAgIGJpdEZpZWxkMjZfID0gKGJpdEZpZWxkMjZfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU5ID0gODU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MCA9IDg2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI2XyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYwID0gODYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYwID0gODYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MCA9IDg2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYwID0gODYwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjAoKTsKICAgICAgICBiaXRGaWVsZDI2XyA9IChiaXRGaWVsZDI2XyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MCA9IDg2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjEgPSA4NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNl8gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MSA9IDg2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MSA9IDg2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjEgPSA4NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MSA9IDg2MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYxKCk7CiAgICAgICAgYml0RmllbGQyNl8gPSAoYml0RmllbGQyNl8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjEgPSA4NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYyID0gODYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjZfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjIgPSA4NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjIgPSA4NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYyID0gODYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjIgPSA4NjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MigpOwogICAgICAgIGJpdEZpZWxkMjZfID0gKGJpdEZpZWxkMjZfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYyID0gODYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MyA9IDg2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI2XyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYzID0gODYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYzID0gODYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MyA9IDg2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYzID0gODYzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjMoKTsKICAgICAgICBiaXRGaWVsZDI2XyA9IChiaXRGaWVsZDI2XyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2MyA9IDg2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjZfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjQgPSA4NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyNl8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NCA9IDg2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NCA9IDg2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjQgPSA4NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyNl8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NCA9IDg2NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY0KCk7CiAgICAgICAgYml0RmllbGQyNl8gPSAoYml0RmllbGQyNl8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjQgPSA4NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI2XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY1ID0gODY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjUgPSA4NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjUgPSA4NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY1ID0gODY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjUgPSA4NjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NSgpOwogICAgICAgIGJpdEZpZWxkMjdfID0gKGJpdEZpZWxkMjdfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY1ID0gODY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NiA9IDg2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI3XyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY2ID0gODY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY2ID0gODY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NiA9IDg2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY2ID0gODY2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjYoKTsKICAgICAgICBiaXRGaWVsZDI3XyA9IChiaXRGaWVsZDI3XyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NiA9IDg2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjcgPSA4NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyN18gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NyA9IDg2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NyA9IDg2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjcgPSA4NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NyA9IDg2NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY3KCk7CiAgICAgICAgYml0RmllbGQyN18gPSAoYml0RmllbGQyN18gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjcgPSA4NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY4ID0gODY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjggPSA4NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjggPSA4NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY4ID0gODY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NjggPSA4NjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OCgpOwogICAgICAgIGJpdEZpZWxkMjdfID0gKGJpdEZpZWxkMjdfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY4ID0gODY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2OSA9IDg2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI3XyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY5ID0gODY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY5ID0gODY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2OSA9IDg2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODY5ID0gODY5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjkoKTsKICAgICAgICBiaXRGaWVsZDI3XyA9IChiaXRGaWVsZDI3XyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2OSA9IDg2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzAgPSA4NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyN18gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MCA9IDg3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MCA9IDg3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzAgPSA4NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MCA9IDg3MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcwKCk7CiAgICAgICAgYml0RmllbGQyN18gPSAoYml0RmllbGQyN18gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzAgPSA4NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcxID0gODcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzEgPSA4NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzEgPSA4NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcxID0gODcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzEgPSA4NzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MSgpOwogICAgICAgIGJpdEZpZWxkMjdfID0gKGJpdEZpZWxkMjdfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcxID0gODcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MiA9IDg3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI3XyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcyID0gODcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcyID0gODcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MiA9IDg3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODcyID0gODcyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzIoKTsKICAgICAgICBiaXRGaWVsZDI3XyA9IChiaXRGaWVsZDI3XyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MiA9IDg3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODczXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzMgPSA4NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODczIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyN18gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MyA9IDg3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODczLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MyA9IDg3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODczXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzMgPSA4NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODczIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MyA9IDg3MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODczKCk7CiAgICAgICAgYml0RmllbGQyN18gPSAoYml0RmllbGQyN18gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzMgPSA4NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc0ID0gODc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzQgPSA4NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzQgPSA4NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc0ID0gODc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzQgPSA4NzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NCgpOwogICAgICAgIGJpdEZpZWxkMjdfID0gKGJpdEZpZWxkMjdfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc0ID0gODc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3NSA9IDg3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI3XyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc1ID0gODc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc1ID0gODc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3NSA9IDg3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc1ID0gODc1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzUoKTsKICAgICAgICBiaXRGaWVsZDI3XyA9IChiaXRGaWVsZDI3XyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3NSA9IDg3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzYgPSA4NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyN18gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3NiA9IDg3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3NiA9IDg3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzYgPSA4NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3NiA9IDg3NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc2KCk7CiAgICAgICAgYml0RmllbGQyN18gPSAoYml0RmllbGQyN18gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzYgPSA4NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc3ID0gODc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzcgPSA4NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzcgPSA4NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc3ID0gODc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzcgPSA4NzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NygpOwogICAgICAgIGJpdEZpZWxkMjdfID0gKGJpdEZpZWxkMjdfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc3ID0gODc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3OCA9IDg3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI3XyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc4ID0gODc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc4ID0gODc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3OCA9IDg3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODc4ID0gODc4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzgoKTsKICAgICAgICBiaXRGaWVsZDI3XyA9IChiaXRGaWVsZDI3XyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3OCA9IDg3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzkgPSA4NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyN18gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3OSA9IDg3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3OSA9IDg3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzkgPSA4NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3OSA9IDg3OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc5KCk7CiAgICAgICAgYml0RmllbGQyN18gPSAoYml0RmllbGQyN18gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzkgPSA4NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgwID0gODgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODAgPSA4ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODAgPSA4ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgwID0gODgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODAgPSA4ODAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MCgpOwogICAgICAgIGJpdEZpZWxkMjdfID0gKGJpdEZpZWxkMjdfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgwID0gODgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4MSA9IDg4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI3XyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgxID0gODgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgxID0gODgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4MSA9IDg4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgxID0gODgxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODEoKTsKICAgICAgICBiaXRGaWVsZDI3XyA9IChiaXRGaWVsZDI3XyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4MSA9IDg4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODIgPSA4ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyN18gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4MiA9IDg4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4MiA9IDg4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODIgPSA4ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4MiA9IDg4MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgyKCk7CiAgICAgICAgYml0RmllbGQyN18gPSAoYml0RmllbGQyN18gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODIgPSA4ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgzID0gODgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODMgPSA4ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODMgPSA4ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgzID0gODgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODMgPSA4ODMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MygpOwogICAgICAgIGJpdEZpZWxkMjdfID0gKGJpdEZpZWxkMjdfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgzID0gODgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NCA9IDg4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI3XyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg0ID0gODg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg0ID0gODg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NCA9IDg4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg0ID0gODg0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODQoKTsKICAgICAgICBiaXRGaWVsZDI3XyA9IChiaXRGaWVsZDI3XyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NCA9IDg4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODUgPSA4ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyN18gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NSA9IDg4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NSA9IDg4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODUgPSA4ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NSA9IDg4NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg1KCk7CiAgICAgICAgYml0RmllbGQyN18gPSAoYml0RmllbGQyN18gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODUgPSA4ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg2ID0gODg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODYgPSA4ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODYgPSA4ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg2ID0gODg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODYgPSA4ODYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NigpOwogICAgICAgIGJpdEZpZWxkMjdfID0gKGJpdEZpZWxkMjdfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg2ID0gODg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NyA9IDg4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI3XyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg3ID0gODg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg3ID0gODg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NyA9IDg4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg3ID0gODg3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODcoKTsKICAgICAgICBiaXRGaWVsZDI3XyA9IChiaXRGaWVsZDI3XyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4NyA9IDg4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODggPSA4ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyN18gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4OCA9IDg4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4OCA9IDg4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODggPSA4ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg4OCA9IDg4OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg4KCk7CiAgICAgICAgYml0RmllbGQyN18gPSAoYml0RmllbGQyN18gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODggPSA4ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg5ID0gODg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODkgPSA4ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODkgPSA4ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg5ID0gODg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184ODkgPSA4ODkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4OSgpOwogICAgICAgIGJpdEZpZWxkMjdfID0gKGJpdEZpZWxkMjdfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg5ID0gODg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MCA9IDg5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI3XyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkwID0gODkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkwID0gODkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MCA9IDg5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkwID0gODkwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTAoKTsKICAgICAgICBiaXRGaWVsZDI3XyA9IChiaXRGaWVsZDI3XyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MCA9IDg5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTEgPSA4OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyN18gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MSA9IDg5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MSA9IDg5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTEgPSA4OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MSA9IDg5MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkxKCk7CiAgICAgICAgYml0RmllbGQyN18gPSAoYml0RmllbGQyN18gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTEgPSA4OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkyID0gODkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTIgPSA4OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTIgPSA4OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkyID0gODkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTIgPSA4OTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MigpOwogICAgICAgIGJpdEZpZWxkMjdfID0gKGJpdEZpZWxkMjdfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkyID0gODkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MyA9IDg5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI3XyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkzID0gODkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkzID0gODkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MyA9IDg5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODkzID0gODkzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTMoKTsKICAgICAgICBiaXRGaWVsZDI3XyA9IChiaXRGaWVsZDI3XyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MyA9IDg5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTQgPSA4OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyN18gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NCA9IDg5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NCA9IDg5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTQgPSA4OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NCA9IDg5NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk0KCk7CiAgICAgICAgYml0RmllbGQyN18gPSAoYml0RmllbGQyN18gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTQgPSA4OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk1ID0gODk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjdfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTUgPSA4OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTUgPSA4OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk1ID0gODk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTUgPSA4OTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NSgpOwogICAgICAgIGJpdEZpZWxkMjdfID0gKGJpdEZpZWxkMjdfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk1ID0gODk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyN18gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NiA9IDg5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI3XyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk2ID0gODk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk2ID0gODk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NiA9IDg5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI3XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk2ID0gODk2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTYoKTsKICAgICAgICBiaXRGaWVsZDI3XyA9IChiaXRGaWVsZDI3XyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NiA9IDg5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjdfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTcgPSA4OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NyA9IDg5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NyA9IDg5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTcgPSA4OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NyA9IDg5NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk3KCk7CiAgICAgICAgYml0RmllbGQyOF8gPSAoYml0RmllbGQyOF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTcgPSA4OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk4ID0gODk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTggPSA4OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OThfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTggPSA4OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk4ID0gODk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OTggPSA4OTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OThfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OCgpOwogICAgICAgIGJpdEZpZWxkMjhfID0gKGJpdEZpZWxkMjhfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk4ID0gODk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5OSA9IDg5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI4XyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk5ID0gODk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk5ID0gODk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5OSA9IDg5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODk5ID0gODk5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTkoKTsKICAgICAgICBiaXRGaWVsZDI4XyA9IChiaXRGaWVsZDI4XyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5OSA9IDg5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDAgPSA5MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMCA9IDkwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMCA9IDkwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDAgPSA5MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMCA9IDkwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAwKCk7CiAgICAgICAgYml0RmllbGQyOF8gPSAoYml0RmllbGQyOF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDAgPSA5MDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAxID0gOTAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDEgPSA5MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDEgPSA5MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAxID0gOTAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDEgPSA5MDEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMSgpOwogICAgICAgIGJpdEZpZWxkMjhfID0gKGJpdEZpZWxkMjhfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAxID0gOTAxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMiA9IDkwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI4XyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAyID0gOTAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAyID0gOTAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMiA9IDkwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAyID0gOTAyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDIoKTsKICAgICAgICBiaXRGaWVsZDI4XyA9IChiaXRGaWVsZDI4XyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMiA9IDkwMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDMgPSA5MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMyA9IDkwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMyA9IDkwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDMgPSA5MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwMyA9IDkwMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAzKCk7CiAgICAgICAgYml0RmllbGQyOF8gPSAoYml0RmllbGQyOF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDMgPSA5MDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA0ID0gOTA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDQgPSA5MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDQgPSA5MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA0ID0gOTA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDQgPSA5MDQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNCgpOwogICAgICAgIGJpdEZpZWxkMjhfID0gKGJpdEZpZWxkMjhfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA0ID0gOTA0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwNSA9IDkwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI4XyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA1ID0gOTA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA1ID0gOTA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwNSA9IDkwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA1ID0gOTA1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDUoKTsKICAgICAgICBiaXRGaWVsZDI4XyA9IChiaXRGaWVsZDI4XyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwNSA9IDkwNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDYgPSA5MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOF8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwNiA9IDkwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwNiA9IDkwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDYgPSA5MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwNiA9IDkwNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA2KCk7CiAgICAgICAgYml0RmllbGQyOF8gPSAoYml0RmllbGQyOF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDYgPSA5MDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA3ID0gOTA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDcgPSA5MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDcgPSA5MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA3ID0gOTA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDcgPSA5MDcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNygpOwogICAgICAgIGJpdEZpZWxkMjhfID0gKGJpdEZpZWxkMjhfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA3ID0gOTA3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwOCA9IDkwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI4XyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA4ID0gOTA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA4ID0gOTA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwOCA9IDkwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA4ID0gOTA4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDgoKTsKICAgICAgICBiaXRGaWVsZDI4XyA9IChiaXRGaWVsZDI4XyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwOCA9IDkwOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDkgPSA5MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOF8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwOSA9IDkwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwOSA9IDkwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDkgPSA5MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkwOSA9IDkwOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA5KCk7CiAgICAgICAgYml0RmllbGQyOF8gPSAoYml0RmllbGQyOF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDkgPSA5MDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEwID0gOTEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTAgPSA5MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTAgPSA5MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEwID0gOTEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTAgPSA5MTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMCgpOwogICAgICAgIGJpdEZpZWxkMjhfID0gKGJpdEZpZWxkMjhfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEwID0gOTEwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxMSA9IDkxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI4XyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTExID0gOTExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTExKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTExXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTExID0gOTExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTExLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxMSA9IDkxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTExKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTExID0gOTExIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTExXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTEoKTsKICAgICAgICBiaXRGaWVsZDI4XyA9IChiaXRGaWVsZDI4XyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxMSA9IDkxMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTExIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTExXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTIgPSA5MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOF8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxMiA9IDkxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxMiA9IDkxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTIgPSA5MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxMiA9IDkxMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEyKCk7CiAgICAgICAgYml0RmllbGQyOF8gPSAoYml0RmllbGQyOF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTIgPSA5MTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxM18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEzID0gOTEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTMgPSA5MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTMgPSA5MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEzID0gOTEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTMgPSA5MTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMygpOwogICAgICAgIGJpdEZpZWxkMjhfID0gKGJpdEZpZWxkMjhfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTEzID0gOTEzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNCA9IDkxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI4XyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE0ID0gOTE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE0ID0gOTE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNCA9IDkxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE0ID0gOTE0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTQoKTsKICAgICAgICBiaXRGaWVsZDI4XyA9IChiaXRGaWVsZDI4XyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNCA9IDkxNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTUgPSA5MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOF8gJiAweDAwMDQwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNSA9IDkxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNSA9IDkxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTUgPSA5MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNSA9IDkxNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE1KCk7CiAgICAgICAgYml0RmllbGQyOF8gPSAoYml0RmllbGQyOF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTUgPSA5MTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE2ID0gOTE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTYgPSA5MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTYgPSA5MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE2ID0gOTE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTYgPSA5MTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNigpOwogICAgICAgIGJpdEZpZWxkMjhfID0gKGJpdEZpZWxkMjhfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE2ID0gOTE2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNyA9IDkxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI4XyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE3ID0gOTE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE3ID0gOTE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxN187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNyA9IDkxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE3ID0gOTE3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTcoKTsKICAgICAgICBiaXRGaWVsZDI4XyA9IChiaXRGaWVsZDI4XyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNyA9IDkxNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxN0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTggPSA5MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOF8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxOCA9IDkxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MThfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxOCA9IDkxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MThCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MThfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTggPSA5MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxOCA9IDkxOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE4KCk7CiAgICAgICAgYml0RmllbGQyOF8gPSAoYml0RmllbGQyOF8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTggPSA5MTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MThCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE5ID0gOTE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTkgPSA5MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTkgPSA5MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE5ID0gOTE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MTkgPSA5MTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxOSgpOwogICAgICAgIGJpdEZpZWxkMjhfID0gKGJpdEZpZWxkMjhfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTE5ID0gOTE5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMCA9IDkyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI4XyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIwID0gOTIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIwID0gOTIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMCA9IDkyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIwID0gOTIwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjAoKTsKICAgICAgICBiaXRGaWVsZDI4XyA9IChiaXRGaWVsZDI4XyAmIH4weDAwODAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMCA9IDkyMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjEgPSA5MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOF8gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMSA9IDkyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMSA9IDkyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjEgPSA5MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMSA9IDkyMSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIxKCk7CiAgICAgICAgYml0RmllbGQyOF8gPSAoYml0RmllbGQyOF8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjEgPSA5MjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIyID0gOTIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjIgPSA5MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjIgPSA5MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIyID0gOTIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjIgPSA5MjIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMigpOwogICAgICAgIGJpdEZpZWxkMjhfID0gKGJpdEZpZWxkMjhfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIyID0gOTIyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMyA9IDkyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI4XyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIzID0gOTIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIzID0gOTIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyM187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMyA9IDkyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTIzID0gOTIzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjMoKTsKICAgICAgICBiaXRGaWVsZDI4XyA9IChiaXRGaWVsZDI4XyAmIH4weDA0MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyMyA9IDkyMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyM0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjQgPSA5MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOF8gJiAweDA4MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNCA9IDkyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNCA9IDkyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjQgPSA5MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNCA9IDkyNCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI0KCk7CiAgICAgICAgYml0RmllbGQyOF8gPSAoYml0RmllbGQyOF8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjQgPSA5MjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI1ID0gOTI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjUgPSA5MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjUgPSA5MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI1ID0gOTI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjUgPSA5MjUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNSgpOwogICAgICAgIGJpdEZpZWxkMjhfID0gKGJpdEZpZWxkMjhfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI1ID0gOTI1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNiA9IDkyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI4XyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI2ID0gOTI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI2ID0gOTI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNiA9IDkyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI2ID0gOTI2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjYoKTsKICAgICAgICBiaXRGaWVsZDI4XyA9IChiaXRGaWVsZDI4XyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNiA9IDkyNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjcgPSA5MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOF8gJiAweDQwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNyA9IDkyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNyA9IDkyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjcgPSA5MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyNyA9IDkyNyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyN18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI3KCk7CiAgICAgICAgYml0RmllbGQyOF8gPSAoYml0RmllbGQyOF8gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjcgPSA5MjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI4XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI4ID0gOTI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjhfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjggPSA5MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjggPSA5MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI4ID0gOTI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjhfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjggPSA5MjggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOCgpOwogICAgICAgIGJpdEZpZWxkMjhfID0gKGJpdEZpZWxkMjhfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI4ID0gOTI4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyOSA9IDkyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI5XyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI5ID0gOTI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI5ID0gOTI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyOSA9IDkyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTI5ID0gOTI5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjkoKTsKICAgICAgICBiaXRGaWVsZDI5XyA9IChiaXRGaWVsZDI5XyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyOSA9IDkyOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzAgPSA5MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOV8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMCA9IDkzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMCA9IDkzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzAgPSA5MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMCA9IDkzMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMwKCk7CiAgICAgICAgYml0RmllbGQyOV8gPSAoYml0RmllbGQyOV8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzAgPSA5MzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMxID0gOTMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzEgPSA5MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzEgPSA5MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMxID0gOTMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzEgPSA5MzEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMSgpOwogICAgICAgIGJpdEZpZWxkMjlfID0gKGJpdEZpZWxkMjlfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMxID0gOTMxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMiA9IDkzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI5XyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMyID0gOTMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMyID0gOTMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMiA9IDkzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTMyID0gOTMyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzIoKTsKICAgICAgICBiaXRGaWVsZDI5XyA9IChiaXRGaWVsZDI5XyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMiA9IDkzMiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzMgPSA5MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOV8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMyA9IDkzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMyA9IDkzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzMgPSA5MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzMyA9IDkzMyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMzKCk7CiAgICAgICAgYml0RmllbGQyOV8gPSAoYml0RmllbGQyOV8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzMgPSA5MzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM0ID0gOTM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzQgPSA5MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzQgPSA5MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM0ID0gOTM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzQgPSA5MzQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNCgpOwogICAgICAgIGJpdEZpZWxkMjlfID0gKGJpdEZpZWxkMjlfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM0ID0gOTM0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzNSA9IDkzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI5XyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM1ID0gOTM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM1ID0gOTM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzNSA9IDkzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM1ID0gOTM1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzUoKTsKICAgICAgICBiaXRGaWVsZDI5XyA9IChiaXRGaWVsZDI5XyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzNSA9IDkzNSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzYgPSA5MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOV8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzNiA9IDkzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzNiA9IDkzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzYgPSA5MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzNiA9IDkzNiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM2KCk7CiAgICAgICAgYml0RmllbGQyOV8gPSAoYml0RmllbGQyOV8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzYgPSA5MzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzN18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM3ID0gOTM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzcgPSA5MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzcgPSA5MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM3ID0gOTM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzcgPSA5MzcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNygpOwogICAgICAgIGJpdEZpZWxkMjlfID0gKGJpdEZpZWxkMjlfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM3ID0gOTM3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzOCA9IDkzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI5XyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM4ID0gOTM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM4ID0gOTM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzOCA9IDkzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM4ID0gOTM4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzgoKTsKICAgICAgICBiaXRGaWVsZDI5XyA9IChiaXRGaWVsZDI5XyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzOCA9IDkzOCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzkgPSA5MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOV8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzOSA9IDkzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzOSA9IDkzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzkgPSA5MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkzOSA9IDkzOSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM5KCk7CiAgICAgICAgYml0RmllbGQyOV8gPSAoYml0RmllbGQyOV8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzkgPSA5MzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQwID0gOTQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDAgPSA5NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDAgPSA5NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQwID0gOTQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDAgPSA5NDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MCgpOwogICAgICAgIGJpdEZpZWxkMjlfID0gKGJpdEZpZWxkMjlfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQwID0gOTQwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0MSA9IDk0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI5XyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQxID0gOTQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQxID0gOTQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0MSA9IDk0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQxID0gOTQxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDEoKTsKICAgICAgICBiaXRGaWVsZDI5XyA9IChiaXRGaWVsZDI5XyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0MSA9IDk0MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDIgPSA5NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOV8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0MiA9IDk0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0MiA9IDk0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDIgPSA5NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0MiA9IDk0MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQyKCk7CiAgICAgICAgYml0RmllbGQyOV8gPSAoYml0RmllbGQyOV8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDIgPSA5NDIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQzID0gOTQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDMgPSA5NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQzXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDMgPSA5NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQzID0gOTQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDMgPSA5NDMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQzKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MygpOwogICAgICAgIGJpdEZpZWxkMjlfID0gKGJpdEZpZWxkMjlfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQzID0gOTQzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NCA9IDk0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI5XyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ0ID0gOTQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ0ID0gOTQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NCA9IDk0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ0ID0gOTQ0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDQoKTsKICAgICAgICBiaXRGaWVsZDI5XyA9IChiaXRGaWVsZDI5XyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NCA9IDk0NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDUgPSA5NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOV8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NSA9IDk0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NSA9IDk0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDUgPSA5NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NSA9IDk0NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ1KCk7CiAgICAgICAgYml0RmllbGQyOV8gPSAoYml0RmllbGQyOV8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDUgPSA5NDUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ2ID0gOTQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDYgPSA5NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDYgPSA5NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ2ID0gOTQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDYgPSA5NDYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NigpOwogICAgICAgIGJpdEZpZWxkMjlfID0gKGJpdEZpZWxkMjlfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ2ID0gOTQ2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NyA9IDk0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI5XyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ3ID0gOTQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ3ID0gOTQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NyA9IDk0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ3ID0gOTQ3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDcoKTsKICAgICAgICBiaXRGaWVsZDI5XyA9IChiaXRGaWVsZDI5XyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NyA9IDk0NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDggPSA5NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOV8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0OCA9IDk0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0OCA9IDk0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDggPSA5NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0OCA9IDk0OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ4KCk7CiAgICAgICAgYml0RmllbGQyOV8gPSAoYml0RmllbGQyOV8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDggPSA5NDggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ5ID0gOTQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDkgPSA5NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDkgPSA5NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ5ID0gOTQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NDkgPSA5NDkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0OSgpOwogICAgICAgIGJpdEZpZWxkMjlfID0gKGJpdEZpZWxkMjlfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQ5ID0gOTQ5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MCA9IDk1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI5XyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUwID0gOTUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUwID0gOTUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MCA9IDk1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUwID0gOTUwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTAoKTsKICAgICAgICBiaXRGaWVsZDI5XyA9IChiaXRGaWVsZDI5XyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MCA9IDk1MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTEgPSA5NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOV8gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MSA9IDk1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MSA9IDk1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTEgPSA5NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MSA9IDk1MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUxKCk7CiAgICAgICAgYml0RmllbGQyOV8gPSAoYml0RmllbGQyOV8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTEgPSA5NTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUyID0gOTUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTIgPSA5NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTIgPSA5NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUyID0gOTUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTIgPSA5NTIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MigpOwogICAgICAgIGJpdEZpZWxkMjlfID0gKGJpdEZpZWxkMjlfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUyID0gOTUyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MyA9IDk1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI5XyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUzID0gOTUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUzID0gOTUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MyA9IDk1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTUzID0gOTUzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTMoKTsKICAgICAgICBiaXRGaWVsZDI5XyA9IChiaXRGaWVsZDI5XyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MyA9IDk1MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTQgPSA5NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOV8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NCA9IDk1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NCA9IDk1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTQgPSA5NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NCA9IDk1NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU0KCk7CiAgICAgICAgYml0RmllbGQyOV8gPSAoYml0RmllbGQyOV8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTQgPSA5NTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU1ID0gOTU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTUgPSA5NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTUgPSA5NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU1ID0gOTU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTUgPSA5NTUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NSgpOwogICAgICAgIGJpdEZpZWxkMjlfID0gKGJpdEZpZWxkMjlfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU1ID0gOTU1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NiA9IDk1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI5XyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU2ID0gOTU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU2ID0gOTU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NiA9IDk1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU2ID0gOTU2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTYoKTsKICAgICAgICBiaXRGaWVsZDI5XyA9IChiaXRGaWVsZDI5XyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NiA9IDk1NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTcgPSA5NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOV8gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NyA9IDk1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NyA9IDk1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTcgPSA5NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1NyA9IDk1NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU3KCk7CiAgICAgICAgYml0RmllbGQyOV8gPSAoYml0RmllbGQyOV8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTcgPSA5NTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU4ID0gOTU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMjlfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTggPSA5NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NThfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTggPSA5NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU4ID0gOTU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTggPSA5NTggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NThfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OCgpOwogICAgICAgIGJpdEZpZWxkMjlfID0gKGJpdEZpZWxkMjlfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU4ID0gOTU4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1OSA9IDk1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDI5XyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU5ID0gOTU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU5ID0gOTU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1OSA9IDk1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTU5ID0gOTU5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTkoKTsKICAgICAgICBiaXRGaWVsZDI5XyA9IChiaXRGaWVsZDI5XyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1OSA9IDk1OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMjlfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjAgPSA5NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyOV8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MCA9IDk2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MCA9IDk2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjAgPSA5NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyOV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MCA9IDk2MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYwKCk7CiAgICAgICAgYml0RmllbGQyOV8gPSAoYml0RmllbGQyOV8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjAgPSA5NjAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDI5XyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYxID0gOTYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjEgPSA5NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjEgPSA5NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYxID0gOTYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjEgPSA5NjEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MSgpOwogICAgICAgIGJpdEZpZWxkMzBfID0gKGJpdEZpZWxkMzBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYxID0gOTYxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MiA9IDk2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDMwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYyID0gOTYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYyID0gOTYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MiA9IDk2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYyID0gOTYyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjIoKTsKICAgICAgICBiaXRGaWVsZDMwXyA9IChiaXRGaWVsZDMwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MiA9IDk2MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjMgPSA5NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MyA9IDk2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MyA9IDk2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjMgPSA5NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2MyA9IDk2MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYzKCk7CiAgICAgICAgYml0RmllbGQzMF8gPSAoYml0RmllbGQzMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjMgPSA5NjMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY0ID0gOTY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjQgPSA5NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjQgPSA5NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY0ID0gOTY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjQgPSA5NjQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NCgpOwogICAgICAgIGJpdEZpZWxkMzBfID0gKGJpdEZpZWxkMzBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY0ID0gOTY0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2NSA9IDk2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDMwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY1ID0gOTY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY1ID0gOTY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2NSA9IDk2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY1ID0gOTY1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjUoKTsKICAgICAgICBiaXRGaWVsZDMwXyA9IChiaXRGaWVsZDMwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2NSA9IDk2NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjYgPSA5NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2NiA9IDk2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2NiA9IDk2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjYgPSA5NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2NiA9IDk2NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY2KCk7CiAgICAgICAgYml0RmllbGQzMF8gPSAoYml0RmllbGQzMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjYgPSA5NjYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY3ID0gOTY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjcgPSA5NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjcgPSA5NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY3ID0gOTY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjcgPSA5NjcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NygpOwogICAgICAgIGJpdEZpZWxkMzBfID0gKGJpdEZpZWxkMzBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY3ID0gOTY3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjhfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2OCA9IDk2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDMwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY4ID0gOTY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY4ID0gOTY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjhfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2OCA9IDk2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY4ID0gOTY4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjgoKTsKICAgICAgICBiaXRGaWVsZDMwXyA9IChiaXRGaWVsZDMwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2OCA9IDk2OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjkgPSA5NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2OSA9IDk2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2OSA9IDk2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjkgPSA5NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk2OSA9IDk2OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY5KCk7CiAgICAgICAgYml0RmllbGQzMF8gPSAoYml0RmllbGQzMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NjkgPSA5NjkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcwID0gOTcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzAgPSA5NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcwXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzBfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzAgPSA5NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcwXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcwID0gOTcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzAgPSA5NzAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcwKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzBfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MCgpOwogICAgICAgIGJpdEZpZWxkMzBfID0gKGJpdEZpZWxkMzBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcwID0gOTcwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzFfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MSA9IDk3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDMwXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcxID0gOTcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcxKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcxXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcxID0gOTcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MSA9IDk3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTcxID0gOTcxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzEoKTsKICAgICAgICBiaXRGaWVsZDMwXyA9IChiaXRGaWVsZDMwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MSA9IDk3MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcyXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzIgPSA5NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMF8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MiA9IDk3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Ml8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MiA9IDk3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzIgPSA5NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MiA9IDk3MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzIoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Ml8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcyKCk7CiAgICAgICAgYml0RmllbGQzMF8gPSAoYml0RmllbGQzMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzIgPSA5NzIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3M18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTczID0gOTczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTczKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzMgPSA5NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3My4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTczXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzNfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzMgPSA5NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTczQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTczXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3M18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTczID0gOTczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTczXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzMgPSA5NzMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTczKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MygpOwogICAgICAgIGJpdEZpZWxkMzBfID0gKGJpdEZpZWxkMzBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTczID0gOTczIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTczQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzRfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NCA9IDk3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDMwXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc0ID0gOTc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc0KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc0XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc0ID0gOTc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NCA9IDk3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc0ID0gOTc0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzQoKTsKICAgICAgICBiaXRGaWVsZDMwXyA9IChiaXRGaWVsZDMwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NCA9IDk3NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc1XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzUgPSA5NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMF8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NSA9IDk3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NSA9IDk3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzUgPSA5NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NSA9IDk3NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzUoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc1KCk7CiAgICAgICAgYml0RmllbGQzMF8gPSAoYml0RmllbGQzMF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzUgPSA5NzUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Nl8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc2ID0gOTc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzYgPSA5NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc2XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzZfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzYgPSA5NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3Nl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc2ID0gOTc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzYoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzYgPSA5NzYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc2KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzZfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NigpOwogICAgICAgIGJpdEZpZWxkMzBfID0gKGJpdEZpZWxkMzBfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc2ID0gOTc2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzdfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NyA9IDk3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDMwXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc3ID0gOTc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc3KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3N187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc3XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc3ID0gOTc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3N0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3N187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NyA9IDk3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc3KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc3ID0gOTc3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzcoKTsKICAgICAgICBiaXRGaWVsZDMwXyA9IChiaXRGaWVsZDMwXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NyA9IDk3NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3N0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc4XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzggPSA5NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMF8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3OCA9IDk3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzhfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3OCA9IDk3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzggPSA5NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3OCA9IDk3OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzgoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc4KCk7CiAgICAgICAgYml0RmllbGQzMF8gPSAoYml0RmllbGQzMF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzggPSA5NzggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc5ID0gOTc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzkgPSA5NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc5XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzlfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzkgPSA5NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc5ID0gOTc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzkoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzkgPSA5NzkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc5KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzlfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3OSgpOwogICAgICAgIGJpdEZpZWxkMzBfID0gKGJpdEZpZWxkMzBfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTc5ID0gOTc5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MCA9IDk4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDMwXyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgwID0gOTgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgwKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgwXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgwID0gOTgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgwLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODBfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MCA9IDk4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgwID0gOTgwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODAoKTsKICAgICAgICBiaXRGaWVsZDMwXyA9IChiaXRGaWVsZDMwXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MCA9IDk4MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgxXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODEgPSA5ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMF8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MSA9IDk4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MSA9IDk4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgxXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODEgPSA5ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MSA9IDk4MSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODEoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgxKCk7CiAgICAgICAgYml0RmllbGQzMF8gPSAoYml0RmllbGQzMF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODEgPSA5ODEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Ml8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgyID0gOTgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODIgPSA5ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Mi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODIgPSA5ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgyXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Ml8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgyID0gOTgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODIgPSA5ODIgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgyKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MigpOwogICAgICAgIGJpdEZpZWxkMzBfID0gKGJpdEZpZWxkMzBfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgyID0gOTgyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODNfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MyA9IDk4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDMwXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgzID0gOTgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4M187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgzID0gOTgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4M0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4M187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODNfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MyA9IDk4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTgzID0gOTgzIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MygpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODMoKTsKICAgICAgICBiaXRGaWVsZDMwXyA9IChiaXRGaWVsZDMwXyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4MyA9IDk4MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4M0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg0XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODQgPSA5ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMF8gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NCA9IDk4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NCA9IDk4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg0XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODQgPSA5ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NCA9IDk4NCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODQoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg0KCk7CiAgICAgICAgYml0RmllbGQzMF8gPSAoYml0RmllbGQzMF8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODQgPSA5ODQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg1ID0gOTg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODUgPSA5ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg1XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODVfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODUgPSA5ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg1Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg1XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg1ID0gOTg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODUgPSA5ODUgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg1KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NSgpOwogICAgICAgIGJpdEZpZWxkMzBfID0gKGJpdEZpZWxkMzBfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg1ID0gOTg1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODZfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NiA9IDk4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDMwXyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg2ID0gOTg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODYuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg2KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Nl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg2XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg2ID0gOTg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Nl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODZfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NiA9IDk4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg2ID0gOTg2IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODYoKTsKICAgICAgICBiaXRGaWVsZDMwXyA9IChiaXRGaWVsZDMwXyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NiA9IDk4NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg3XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODcgPSA5ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMF8gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NyA9IDk4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4N18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NyA9IDk4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg3XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODcgPSA5ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4NyA9IDk4NyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODcoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4N18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg3KCk7CiAgICAgICAgYml0RmllbGQzMF8gPSAoYml0RmllbGQzMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODcgPSA5ODcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4N18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg4ID0gOTg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg4KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODggPSA5ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg4XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODhfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODggPSA5ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg4Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg4XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg4ID0gOTg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODggPSA5ODggW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg4KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OCgpOwogICAgICAgIGJpdEZpZWxkMzBfID0gKGJpdEZpZWxkMzBfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg4ID0gOTg4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODlfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4OSA9IDk4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDMwXyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg5ID0gOTg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODkuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg5KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg5XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg5ID0gOTg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODlfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4OSA9IDk4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg5ID0gOTg5IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODkoKTsKICAgICAgICBiaXRGaWVsZDMwXyA9IChiaXRGaWVsZDMwXyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk4OSA9IDk4OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkwXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTAgPSA5OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMF8gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MCA9IDk5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTBfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MCA9IDk5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTBCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTAgPSA5OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MCA9IDk5MCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTAoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkwKCk7CiAgICAgICAgYml0RmllbGQzMF8gPSAoYml0RmllbGQzMF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTAgPSA5OTAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MV8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkxID0gOTkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMzBfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTEgPSA5OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTEgPSA5OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkxQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkxXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkxID0gOTkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTEgPSA5OTEgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkxKCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MSgpOwogICAgICAgIGJpdEZpZWxkMzBfID0gKGJpdEZpZWxkMzBfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkxID0gOTkxIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTJfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MiA9IDk5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDMwXyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkyID0gOTkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Ml87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkyID0gOTkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Ml87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MiA9IDk5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkyID0gOTkyIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MigpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTIoKTsKICAgICAgICBiaXRGaWVsZDMwXyA9IChiaXRGaWVsZDMwXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MiA9IDk5MiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkzXyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTMgPSA5OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMV8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MyA9IDk5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5M18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MyA9IDk5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5My4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTMgPSA5OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5MyA9IDk5MyBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTMoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5M18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkzKCk7CiAgICAgICAgYml0RmllbGQzMV8gPSAoYml0RmllbGQzMV8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTMgPSA5OTMgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NF8gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk0ID0gOTk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMzFfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTQgPSA5OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTQgPSA5OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk0ID0gOTk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTQgPSA5OTQgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk0KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NCgpOwogICAgICAgIGJpdEZpZWxkMzFfID0gKGJpdEZpZWxkMzFfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk0ID0gOTk0IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTVfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NSA9IDk5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDMxXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk1ID0gOTk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk1ID0gOTk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NSA9IDk5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk1KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk1ID0gOTk1IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NSgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTUoKTsKICAgICAgICBiaXRGaWVsZDMxXyA9IChiaXRGaWVsZDMxXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NSA9IDk5NSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk2XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTYgPSA5OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMV8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NiA9IDk5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Nl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NiA9IDk5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Ni4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTZCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk2XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTYgPSA5OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NiA9IDk5NiBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTYoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Nl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk2KCk7CiAgICAgICAgYml0RmllbGQzMV8gPSAoYml0RmllbGQzMV8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTYgPSA5OTYgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Nl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5N18gPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk3ID0gOTk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMzFfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTcgPSA5OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5Ny4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTcgPSA5OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk3Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk3XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5N18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk3ID0gOTk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTcgPSA5OTcgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk3KCkgewogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NygpOwogICAgICAgIGJpdEZpZWxkMzFfID0gKGJpdEZpZWxkMzFfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk3ID0gOTk3IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OThfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5OCA9IDk5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDMxXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk4ID0gOTk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk4ID0gOTk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OThfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5OCA9IDk5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk4KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk4ID0gOTk4IFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTgoKTsKICAgICAgICBiaXRGaWVsZDMxXyA9IChiaXRGaWVsZDMxXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5OCA9IDk5OCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMzFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk5XyA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTkgPSA5OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMV8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5OSA9IDk5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5OSA9IDk5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTlCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk5XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTkgPSA5OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQzMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5OSA9IDk5OSBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTkoKSB7CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk5KCk7CiAgICAgICAgYml0RmllbGQzMV8gPSAoYml0RmllbGQzMV8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185OTkgPSA5OTkgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMxXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMDBfID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMDAgPSAxMDAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMDAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMDAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQzMV8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMDAgPSAxMDAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMDAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEwMDAgPSAxMDAwIFtkZWZhdWx0ID0gImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldExvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDAwID0gMTAwMCBbZGVmYXVsdCA9ICJsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMDAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAwMCA9IDEwMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMCgpIHsKICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMCgpOwogICAgICAgIGJpdEZpZWxkMzFfID0gKGJpdEZpZWxkMzFfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTAwMCA9IDEwMDAgW2RlZmF1bHQgPSAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBsb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAwMF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDMxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5UZXN0RW5vcm1vdXNEZXNjcmlwdG9yKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RW5vcm1vdXNEZXNjcmlwdG9yPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RFbm9ybW91c0Rlc2NyaXB0b3I+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0RW5vcm1vdXNEZXNjcmlwdG9yIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEVub3Jtb3VzRGVzY3JpcHRvcj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RW5vcm1vdXNEZXNjcmlwdG9yPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVuaXR0ZXN0RW5vcm1vdXNEZXNjcmlwdG9yLlRlc3RFbm9ybW91c0Rlc2NyaXB0b3IgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVub3Jtb3VzRGVzY3JpcHRvcl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW5vcm1vdXNEZXNjcmlwdG9yX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4yZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2Vub3Jtb3VzX2Rlc2MiICsKICAgICAgInJpcHRvci5wcm90b1wwMjJcMDIxcHJvdG9idWZfdW5pdHRlc3RcIlwyMjZcMzM0XHJcblwwMjZUZXMiICsKICAgICAgInRFbm9ybW91c0Rlc2NyaXB0b3JcMDIyXDMzM1wwMDFcbmFsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICIxXDAzMFwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbiIgKwogICAgICAiZ1wwMjJcMzMzXDAwMVxuYWxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29uZ18yXDAzMFwwMDIgXDAwMShcdDpwbG9uZyBkZWZhIiArCiAgICAgICJ1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzMzXDAwMVxuYWxvbmdfZmllbGRfbiIgKwogICAgICAiYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib25nXzNcMDMwXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyAiICsKICAgICAgImxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb25nXDAyMlwzMzNcMDAxXG5hbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb25nXzRcMDMwXDAwNCBcMDAxKFx0OnBsb25nICIgKwogICAgICAiZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzNcMDAxXG5hbG9uZ19maWUiICsKICAgICAgImxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vbmdfNVwwMzBcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzM1wwMDFcbmFsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNlwwMzBcMDA2IFwwMDEoXHQ6cGwiICsKICAgICAgIm9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzM1wwMDFcbmFsb25nIiArCiAgICAgICJfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29uZ183XDAzMFwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlICIgKwogICAgICAiaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29uZ1wwMjJcMzMzXDAwMVxuYWxvbmdfZmllbGRfbmFtZV9pc19sb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184XDAzMFwwMTAgXDAwMSgiICsKICAgICAgIlx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzMzXDAwMVxuYSIgKwogICAgICAibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb25nXzlcMDMwXHQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhIiArCiAgICAgICJsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pcyIgKwogICAgICAiX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMCIgKwogICAgICAiXDAzMFxuIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIiArCiAgICAgICJcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vbmdfMTFcMDMwXDAxMyBcMDAxKFx0OnBsb25nIGRlZmEiICsKICAgICAgInVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uIiArCiAgICAgICJhbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvbmdfMTJcMDMwXDAxNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyIgKwogICAgICAiIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb25nXzEzXDAzMFxyIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ18xNFwwMzBcMDE2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpIiArCiAgICAgICJzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfbG9vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTVcMDMwXDAxNyBcMDAxKCIgKwogICAgICAiXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5iIiArCiAgICAgICJsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vbmdfMTZcMDMwXDAyMCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdiIgKwogICAgICAiYWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2kiICsKICAgICAgInNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEiICsKICAgICAgIjdcMDMwXDAyMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uIiArCiAgICAgICJnXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb25nXzE4XDAzMFwwMjIgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzE5XDAzMFwwMjMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFscyIgKwogICAgICAibyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMFwwMzBcMDI0IFwwMDEoXHQ6cGxvIiArCiAgICAgICJuZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nXyIgKwogICAgICAiZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29uZ18yMVwwMzBcMDI1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSAiICsKICAgICAgImlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfbG9vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjJcMDMwXDAyNiBcMDAxIiArCiAgICAgICIoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG4iICsKICAgICAgImJsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vbmdfMjNcMDMwXDAyNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiMjRcMDMwXDAzMCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm5nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb25nXzI1XDAzMFwwMzEgXDAwMShcdDpwbG9uZyBkZSIgKwogICAgICAiZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGQiICsKICAgICAgIl9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb25nXzI2XDAzMFwwMzIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsIiArCiAgICAgICJzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yN1wwMzBcMDMzIFwwMDEoXHQ6cGwiICsKICAgICAgIm9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nIiArCiAgICAgICJfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29uZ18yOFwwMzBcMDM0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjlcMDMwXDAzNSAiICsKICAgICAgIlwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxIiArCiAgICAgICJcbmJsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vbmdfMzBcMDMwXDAzNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQiICsKICAgICAgIiB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lIiArCiAgICAgICJfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIiArCiAgICAgICJfMzFcMDMwXDAzNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb25nXzMyXDAzMCAgXDAwMShcdDpwbG9uZyBkIiArCiAgICAgICJlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbCIgKwogICAgICAiZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb25nXzMzXDAzMCEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNFwwMzBcIiBcMDAxKFx0OnAiICsKICAgICAgImxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uIiArCiAgICAgICJnX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vbmdfMzVcMDMwIyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdSIgKwogICAgICAiZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2wiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM2XDAzMCQiICsKICAgICAgIiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0IiArCiAgICAgICJcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb25nXzM3XDAzMCUgXDAwMShcdDpwbG9uZyBkZWZhdWwiICsKICAgICAgInQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtIiArCiAgICAgICJlX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uIiArCiAgICAgICJnXzM4XDAzMCYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ18zOVwwMzBcJyBcMDAxKFx0OnBsb25nICIgKwogICAgICAiZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWUiICsKICAgICAgImxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vbmdfNDBcMDMwKCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgIiArCiAgICAgICJhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQxXDAzMCkgXDAwMShcdDoiICsKICAgICAgInBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvIiArCiAgICAgICJuZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb25nXzQyXDAzMCogXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbCIgKwogICAgICAidWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc18iICsKICAgICAgImxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180M1wwMzAiICsKICAgICAgIisgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ180NFwwMzAsIFwwMDEoXHQ6cGxvbmcgZGVmYXUiICsKICAgICAgImx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hIiArCiAgICAgICJtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJuZ180NVwwMzAtIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvICIgKwogICAgICAibG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vbmdfNDZcMDMwLiBcMDAxKFx0OnBsb25nIiArCiAgICAgICIgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maSIgKwogICAgICAiZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vbmdfNDdcMDMwLyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMiICsKICAgICAgIiBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4XDAzMDAgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmwiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzQ5XDAzMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhIiArCiAgICAgICJsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pcyIgKwogICAgICAiX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MCIgKwogICAgICAiXDAzMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmciICsKICAgICAgIlwwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29uZ181MVwwMzAzIFwwMDEoXHQ6cGxvbmcgZGVmYSIgKwogICAgICAidWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX24iICsKICAgICAgImFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9uZ181MlwwMzA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIiArCiAgICAgICIgbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vbmdfNTNcMDMwNSBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNTRcMDMwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaSIgKwogICAgICAicyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU1XDAzMDcgXDAwMSgiICsKICAgICAgIlx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYiIgKwogICAgICAibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb25nXzU2XDAzMDggXDAwMShcdDpwbG9uZyBkZWZhdWx0IHYiICsKICAgICAgImFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pIiArCiAgICAgICJzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181IiArCiAgICAgICI3XDAzMDkgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbiIgKwogICAgICAiZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29uZ181OFwwMzA6IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ181OVwwMzA7IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHMiICsKICAgICAgIm8gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjBcMDMwPCBcMDAxKFx0OnBsbyIgKwogICAgICAibmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ18iICsKICAgICAgImZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vbmdfNjFcMDMwPSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgIiArCiAgICAgICJpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyXDAzMD4gXDAwMSIgKwogICAgICAiKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuIiArCiAgICAgICJibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb25nXzYzXDAzMD8gXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjY0XDAzMEAgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJuZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29uZ182NVwwMzBBIFwwMDEoXHQ6cGxvbmcgZGUiICsKICAgICAgImZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkIiArCiAgICAgICJfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29uZ182NlwwMzBCIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbCIgKwogICAgICAic28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjdcMDMwQyBcMDAxKFx0OnBsIiArCiAgICAgICJvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZyIgKwogICAgICAiX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vbmdfNjhcMDMwRCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5XDAzMEUgIiArCiAgICAgICJcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMSIgKwogICAgICAiXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb25nXzcwXDAzMEYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IiArCiAgICAgICIgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZSIgKwogICAgICAiX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZyIgKwogICAgICAiXzcxXDAzMEcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiwKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb25nXzcyXDAzMEggXDAwMShcdDpwbG9uZyBkIiArCiAgICAgICJlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbCIgKwogICAgICAiZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb25nXzczXDAzMEkgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NFwwMzBKIFwwMDEoXHQ6cCIgKwogICAgICAibG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb24iICsKICAgICAgImdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29uZ183NVwwMzBLIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1IiArCiAgICAgICJlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzZcMDMwTCIgKwogICAgICAiIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzQiICsKICAgICAgIlwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vbmdfNzdcMDMwTSBcMDAxKFx0OnBsb25nIGRlZmF1bCIgKwogICAgICAidCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW0iICsKICAgICAgImVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb24iICsKICAgICAgImdfNzhcMDMwTiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzc5XDAzME8gXDAwMShcdDpwbG9uZyAiICsKICAgICAgImRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllIiArCiAgICAgICJsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb25nXzgwXDAzMFAgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzICIgKwogICAgICAiYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc19sb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MVwwMzBRIFwwMDEoXHQ6IiArCiAgICAgICJwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsbyIgKwogICAgICAibmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29uZ184MlwwMzBSIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWwiICsKICAgICAgInVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfIiArCiAgICAgICJsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODNcMDMwIiArCiAgICAgICJTIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfODRcMDMwVCBcMDAxKFx0OnBsb25nIGRlZmF1IiArCiAgICAgICJsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYSIgKwogICAgICAibWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAibmdfODVcMDMwVSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyAiICsKICAgICAgImxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb25nXzg2XDAzMFYgXDAwMShcdDpwbG9uZyIgKwogICAgICAiIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmkiICsKICAgICAgImVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb25nXzg3XDAzMFcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIiArCiAgICAgICIgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc19sb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OFwwMzBYIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ184OVwwMzBZIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YSIgKwogICAgICAibHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXMiICsKICAgICAgIl9sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTAiICsKICAgICAgIlwwMzBaIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nIiArCiAgICAgICJcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vbmdfOTFcMDMwWyBcMDAxKFx0OnBsb25nIGRlZmEiICsKICAgICAgInVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uIiArCiAgICAgICJhbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvbmdfOTJcMDMwXFwgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28iICsKICAgICAgIiBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29uZ185M1wwMzBdIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ185NFwwMzBeIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpIiArCiAgICAgICJzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vbmdcMDIyXDMzNFwwMDFcbmJsb25nX2ZpZWxkX25hbWVfaXNfbG9vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTVcMDMwXyBcMDAxKCIgKwogICAgICAiXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5iIiArCiAgICAgICJsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vbmdfOTZcMDMwYCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdiIgKwogICAgICAiYWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb25nXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2kiICsKICAgICAgInNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkiICsKICAgICAgIjdcMDMwYSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uIiArCiAgICAgICJnXDAyMlwzMzRcMDAxXG5ibG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb25nXzk4XDAzMGIgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM0XDAwMVxuYmxvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzk5XDAzMGMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFscyIgKwogICAgICAibyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29uZ1wwMjJcMzM1XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDBcMDMwZCBcMDAxKFx0OnBsIiArCiAgICAgICJvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzVcMDAxXG5jbG9uZyIgKwogICAgICAiX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vbmdfMTAxXDAzMGUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHUiICsKICAgICAgImUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29uZ1wwMjJcMzM1XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMDJcMDMwIiArCiAgICAgICJmIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNVwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMTAzXDAzMGcgXDAwMShcdDpwbG9uZyBkZWZhIiArCiAgICAgICJ1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM1XDAwMVxuY2xvbmdfZmllbGRfbiIgKwogICAgICAiYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib25nXzEwNFwwMzBoIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHMiICsKICAgICAgIm8gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vbmdcMDIyXDMzNVwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA1XDAzMGkgXDAwMShcdDpwbCIgKwogICAgICAib25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM1XDAwMVxuY2xvbmciICsKICAgICAgIl9maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb25nXzEwNlwwMzBqIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1IiArCiAgICAgICJlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vbmdcMDIyXDMzNVwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTA3XDAzMCIgKwogICAgICAiayBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzVcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzEwOFwwMzBsIFwwMDEoXHQ6cGxvbmcgZGVmYSIgKwogICAgICAidWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNVwwMDFcbmNsb25nX2ZpZWxkX24iICsKICAgICAgImFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9uZ18xMDlcMDMwbSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzIiArCiAgICAgICJvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb25nXDAyMlwzMzVcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMFwwMzBuIFwwMDEoXHQ6cGwiICsKICAgICAgIm9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNVwwMDFcbmNsb25nIiArCiAgICAgICJfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29uZ18xMTFcMDMwbyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdSIgKwogICAgICAiZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb25nXDAyMlwzMzVcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2wiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzExMlwwMzAiICsKICAgICAgInAgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM1XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ18xMTNcMDMwcSBcMDAxKFx0OnBsb25nIGRlZmEiICsKICAgICAgInVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzVcMDAxXG5jbG9uZ19maWVsZF9uIiArCiAgICAgICJhbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvbmdfMTE0XDAzMHIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFscyIgKwogICAgICAibyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29uZ1wwMjJcMzM1XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTVcMDMwcyBcMDAxKFx0OnBsIiArCiAgICAgICJvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzVcMDAxXG5jbG9uZyIgKwogICAgICAiX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vbmdfMTE2XDAzMHQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHUiICsKICAgICAgImUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29uZ1wwMjJcMzM1XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMTdcMDMwIiArCiAgICAgICJ1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNVwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMTE4XDAzMHYgXDAwMShcdDpwbG9uZyBkZWZhIiArCiAgICAgICJ1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM1XDAwMVxuY2xvbmdfZmllbGRfbiIgKwogICAgICAiYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib25nXzExOVwwMzB3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHMiICsKICAgICAgIm8gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vbmdcMDIyXDMzNVwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIwXDAzMHggXDAwMShcdDpwbCIgKwogICAgICAib25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM1XDAwMVxuY2xvbmciICsKICAgICAgIl9maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb25nXzEyMVwwMzB5IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1IiArCiAgICAgICJlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vbmdcMDIyXDMzNVwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTIyXDAzMCIgKwogICAgICAieiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzVcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzEyM1wwMzB7IFwwMDEoXHQ6cGxvbmcgZGVmYSIgKwogICAgICAidWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNVwwMDFcbmNsb25nX2ZpZWxkX24iICsKICAgICAgImFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9uZ18xMjRcMDMwfCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzIiArCiAgICAgICJvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb25nXDAyMlwzMzVcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyNVwwMzB9IFwwMDEoXHQ6cGwiICsKICAgICAgIm9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNVwwMDFcbmNsb25nIiArCiAgICAgICJfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29uZ18xMjZcMDMwfiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdSIgKwogICAgICAiZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb25nXDAyMlwzMzVcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2wiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEyN1wwMzAiICsKICAgICAgIlwxNzcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ18xMjhcMDMwXDIwMFwwMDEgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzEyOVwwMzBcMjAxXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzMFwwMzBcMjAyXDAwMSBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfMTMxXDAzMFwyMDNcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICIxMzJcMDMwXDIwNFwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ18xMzNcMDMwXDIwNVwwMDEgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzEzNFwwMzBcMjA2XDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzEzNVwwMzBcMjA3IiArCiAgICAgICJcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMTM2XDAzMFwyMTBcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ18xMzdcMDMwXDIxMVwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xMzhcMDMwXDIxMlwwMDEgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzEzOVwwMzBcMjEzXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiMTQwXDAzMFwyMTRcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfMTQxXDAzMFwyMTVcMDAxIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ18xNDJcMDMwXDIxNlwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDNcMDMwXDIxNyIgKwogICAgICAiXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iLAogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMTQ0XDAzMFwyMjBcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ18xNDVcMDMwXDIyMVwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNDZcMDMwXDIyMlwwMDEgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzE0N1wwMzBcMjIzXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiMTQ4XDAzMFwyMjRcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfMTQ5XDAzMFwyMjVcMDAxIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ18xNTBcMDMwXDIyNlwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNTFcMDMwXDIyNyIgKwogICAgICAiXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzE1MlwwMzBcMjMwXDAwMSBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfMTUzXDAzMFwyMzFcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU0XDAzMFwyMzJcMDAxIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ18xNTVcMDMwXDIzM1wwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjE1NlwwMzBcMjM0XDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzE1N1wwMzBcMjM1XDAwMSBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfMTU4XDAzMFwyMzZcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTU5XDAzMFwyMzciICsKICAgICAgIlwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ18xNjBcMDMwXDI0MFwwMDEgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzE2MVwwMzBcMjQxXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2MlwwMzBcMjQyXDAwMSBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfMTYzXDAzMFwyNDNcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICIxNjRcMDMwXDI0NFwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ18xNjVcMDMwXDI0NVwwMDEgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzE2NlwwMzBcMjQ2XDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE2N1wwMzBcMjQ3IiArCiAgICAgICJcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMTY4XDAzMFwyNTBcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ18xNjlcMDMwXDI1MVwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzBcMDMwXDI1MlwwMDEgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzE3MVwwMzBcMjUzXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiMTcyXDAzMFwyNTRcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfMTczXDAzMFwyNTVcMDAxIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ18xNzRcMDMwXDI1NlwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xNzVcMDMwXDI1NyIgKwogICAgICAiXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzE3NlwwMzBcMjYwXDAwMSBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfMTc3XDAzMFwyNjFcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTc4XDAzMFwyNjJcMDAxIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ18xNzlcMDMwXDI2M1wwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjE4MFwwMzBcMjY0XDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzE4MVwwMzBcMjY1XDAwMSBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfMTgyXDAzMFwyNjZcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMTgzXDAzMFwyNjciICsKICAgICAgIlwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ18xODRcMDMwXDI3MFwwMDEgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzE4NVwwMzBcMjcxXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE4NlwwMzBcMjcyXDAwMSBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfMTg3XDAzMFwyNzNcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICIxODhcMDMwXDI3NFwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ18xODlcMDMwXDI3NVwwMDEgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzE5MFwwMzBcMjc2XDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzE5MVwwMzBcMjc3IiArCiAgICAgICJcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMTkyXDAzMFwzMDBcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ18xOTNcMDMwXDMwMVwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTRcMDMwXDMwMlwwMDEgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzE5NVwwMzBcMzAzXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiMTk2XDAzMFwzMDRcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfMTk3XDAzMFwzMDVcMDAxIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ18xOThcMDMwXDMwNlwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18xOTlcMDMwXDMwNyIgKwogICAgICAiXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzIwMFwwMzBcMzEwXDAwMSBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfMjAxXDAzMFwzMTFcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjAyXDAzMFwzMTJcMDAxIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ18yMDNcMDMwXDMxM1wwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjIwNFwwMzBcMzE0XDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzIwNVwwMzBcMzE1XDAwMSBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfMjA2XDAzMFwzMTZcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjA3XDAzMFwzMTciICsKICAgICAgIlwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ18yMDhcMDMwXDMyMFwwMDEgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzIwOVwwMzBcMzIxXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxMFwwMzBcMzIyXDAwMSBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfMjExXDAzMFwzMjNcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICIyMTJcMDMwXDMyNFwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ18yMTNcMDMwXDMyNVwwMDEgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzIxNFwwMzBcMzI2XDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iLAogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjE1XDAzMFwzMjciICsKICAgICAgIlwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ18yMTZcMDMwXDMzMFwwMDEgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzIxN1wwMzBcMzMxXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIxOFwwMzBcMzMyXDAwMSBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfMjE5XDAzMFwzMzNcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICIyMjBcMDMwXDMzNFwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ18yMjFcMDMwXDMzNVwwMDEgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzIyMlwwMzBcMzM2XDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzIyM1wwMzBcMzM3IiArCiAgICAgICJcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMjI0XDAzMFwzNDBcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ18yMjVcMDMwXDM0MVwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMjZcMDMwXDM0MlwwMDEgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzIyN1wwMzBcMzQzXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiMjI4XDAzMFwzNDRcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfMjI5XDAzMFwzNDVcMDAxIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ18yMzBcMDMwXDM0NlwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yMzFcMDMwXDM0NyIgKwogICAgICAiXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzIzMlwwMzBcMzUwXDAwMSBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfMjMzXDAzMFwzNTFcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM0XDAzMFwzNTJcMDAxIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ18yMzVcMDMwXDM1M1wwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjIzNlwwMzBcMzU0XDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzIzN1wwMzBcMzU1XDAwMSBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfMjM4XDAzMFwzNTZcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjM5XDAzMFwzNTciICsKICAgICAgIlwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ18yNDBcMDMwXDM2MFwwMDEgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzI0MVwwMzBcMzYxXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0MlwwMzBcMzYyXDAwMSBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfMjQzXDAzMFwzNjNcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICIyNDRcMDMwXDM2NFwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ18yNDVcMDMwXDM2NVwwMDEgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzI0NlwwMzBcMzY2XDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI0N1wwMzBcMzY3IiArCiAgICAgICJcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMjQ4XDAzMFwzNzBcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ18yNDlcMDMwXDM3MVwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTBcMDMwXDM3MlwwMDEgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzI1MVwwMzBcMzczXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiMjUyXDAzMFwzNzRcMDAxIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfMjUzXDAzMFwzNzVcMDAxIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ18yNTRcMDMwXDM3NlwwMDEgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNTVcMDMwXDM3NyIgKwogICAgICAiXDAwMSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzI1NlwwMzBcMjAwXDAwMiBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfMjU3XDAzMFwyMDFcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjU4XDAzMFwyMDJcMDAyIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ18yNTlcMDMwXDIwM1wwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjI2MFwwMzBcMjA0XDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzI2MVwwMzBcMjA1XDAwMiBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfMjYyXDAzMFwyMDZcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjYzXDAzMFwyMDciICsKICAgICAgIlwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ18yNjRcMDMwXDIxMFwwMDIgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzI2NVwwMzBcMjExXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI2NlwwMzBcMjEyXDAwMiBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfMjY3XDAzMFwyMTNcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICIyNjhcMDMwXDIxNFwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ18yNjlcMDMwXDIxNVwwMDIgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzI3MFwwMzBcMjE2XDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI3MVwwMzBcMjE3IiArCiAgICAgICJcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMjcyXDAzMFwyMjBcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ18yNzNcMDMwXDIyMVwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzRcMDMwXDIyMlwwMDIgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzI3NVwwMzBcMjIzXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiMjc2XDAzMFwyMjRcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfMjc3XDAzMFwyMjVcMDAyIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ18yNzhcMDMwXDIyNlwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yNzlcMDMwXDIyNyIgKwogICAgICAiXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzI4MFwwMzBcMjMwXDAwMiBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfMjgxXDAzMFwyMzFcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjgyXDAzMFwyMzJcMDAyIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ18yODNcMDMwXDIzM1wwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjI4NFwwMzBcMjM0XDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzI4NVwwMzBcMjM1XDAwMiBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiwKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ18yODZcMDMwXDIzNlwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18yODdcMDMwXDIzNyIgKwogICAgICAiXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzI4OFwwMzBcMjQwXDAwMiBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfMjg5XDAzMFwyNDFcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjkwXDAzMFwyNDJcMDAyIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ18yOTFcMDMwXDI0M1wwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjI5MlwwMzBcMjQ0XDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzI5M1wwMzBcMjQ1XDAwMiBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfMjk0XDAzMFwyNDZcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMjk1XDAzMFwyNDciICsKICAgICAgIlwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ18yOTZcMDMwXDI1MFwwMDIgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzI5N1wwMzBcMjUxXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzI5OFwwMzBcMjUyXDAwMiBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfMjk5XDAzMFwyNTNcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICIzMDBcMDMwXDI1NFwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ18zMDFcMDMwXDI1NVwwMDIgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzMwMlwwMzBcMjU2XDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMwM1wwMzBcMjU3IiArCiAgICAgICJcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMzA0XDAzMFwyNjBcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ18zMDVcMDMwXDI2MVwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMDZcMDMwXDI2MlwwMDIgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzMwN1wwMzBcMjYzXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiMzA4XDAzMFwyNjRcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfMzA5XDAzMFwyNjVcMDAyIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ18zMTBcMDMwXDI2NlwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMTFcMDMwXDI2NyIgKwogICAgICAiXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzMxMlwwMzBcMjcwXDAwMiBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfMzEzXDAzMFwyNzFcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE0XDAzMFwyNzJcMDAyIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ18zMTVcMDMwXDI3M1wwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjMxNlwwMzBcMjc0XDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzMxN1wwMzBcMjc1XDAwMiBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfMzE4XDAzMFwyNzZcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzE5XDAzMFwyNzciICsKICAgICAgIlwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ18zMjBcMDMwXDMwMFwwMDIgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzMyMVwwMzBcMzAxXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyMlwwMzBcMzAyXDAwMiBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfMzIzXDAzMFwzMDNcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICIzMjRcMDMwXDMwNFwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ18zMjVcMDMwXDMwNVwwMDIgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzMyNlwwMzBcMzA2XDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzMyN1wwMzBcMzA3IiArCiAgICAgICJcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMzI4XDAzMFwzMTBcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ18zMjlcMDMwXDMxMVwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzBcMDMwXDMxMlwwMDIgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzMzMVwwMzBcMzEzXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiMzMyXDAzMFwzMTRcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfMzMzXDAzMFwzMTVcMDAyIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ18zMzRcMDMwXDMxNlwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zMzVcMDMwXDMxNyIgKwogICAgICAiXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzMzNlwwMzBcMzIwXDAwMiBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfMzM3XDAzMFwzMjFcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzM4XDAzMFwzMjJcMDAyIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ18zMzlcMDMwXDMyM1wwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjM0MFwwMzBcMzI0XDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzM0MVwwMzBcMzI1XDAwMiBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfMzQyXDAzMFwzMjZcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzQzXDAzMFwzMjciICsKICAgICAgIlwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ18zNDRcMDMwXDMzMFwwMDIgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzM0NVwwMzBcMzMxXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM0NlwwMzBcMzMyXDAwMiBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfMzQ3XDAzMFwzMzNcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICIzNDhcMDMwXDMzNFwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ18zNDlcMDMwXDMzNVwwMDIgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzM1MFwwMzBcMzM2XDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1MVwwMzBcMzM3IiArCiAgICAgICJcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMzUyXDAzMFwzNDBcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ18zNTNcMDMwXDM0MVwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNTRcMDMwXDM0MlwwMDIgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzM1NVwwMzBcMzQzXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiMzU2XDAzMFwzNDRcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiwKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ18zNTdcMDMwXDM0NVwwMDIgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzM1OFwwMzBcMzQ2XDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM1OVwwMzBcMzQ3IiArCiAgICAgICJcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMzYwXDAzMFwzNTBcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ18zNjFcMDMwXDM1MVwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjJcMDMwXDM1MlwwMDIgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzM2M1wwMzBcMzUzXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiMzY0XDAzMFwzNTRcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfMzY1XDAzMFwzNTVcMDAyIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ18zNjZcMDMwXDM1NlwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zNjdcMDMwXDM1NyIgKwogICAgICAiXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzM2OFwwMzBcMzYwXDAwMiBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfMzY5XDAzMFwzNjFcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzcwXDAzMFwzNjJcMDAyIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ18zNzFcMDMwXDM2M1wwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjM3MlwwMzBcMzY0XDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzM3M1wwMzBcMzY1XDAwMiBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfMzc0XDAzMFwzNjZcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzc1XDAzMFwzNjciICsKICAgICAgIlwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ18zNzZcMDMwXDM3MFwwMDIgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzM3N1wwMzBcMzcxXDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM3OFwwMzBcMzcyXDAwMiBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfMzc5XDAzMFwzNzNcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICIzODBcMDMwXDM3NFwwMDIgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ18zODFcMDMwXDM3NVwwMDIgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzM4MlwwMzBcMzc2XDAwMiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzM4M1wwMzBcMzc3IiArCiAgICAgICJcMDAyIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfMzg0XDAzMFwyMDBcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ18zODVcMDMwXDIwMVwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zODZcMDMwXDIwMlwwMDMgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzM4N1wwMzBcMjAzXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiMzg4XDAzMFwyMDRcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfMzg5XDAzMFwyMDVcMDAzIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ18zOTBcMDMwXDIwNlwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18zOTFcMDMwXDIwNyIgKwogICAgICAiXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzM5MlwwMzBcMjEwXDAwMyBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfMzkzXDAzMFwyMTFcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk0XDAzMFwyMTJcMDAzIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ18zOTVcMDMwXDIxM1wwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjM5NlwwMzBcMjE0XDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzM5N1wwMzBcMjE1XDAwMyBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfMzk4XDAzMFwyMTZcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfMzk5XDAzMFwyMTciICsKICAgICAgIlwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ180MDBcMDMwXDIyMFwwMDMgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzQwMVwwMzBcMjIxXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwMlwwMzBcMjIyXDAwMyBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNDAzXDAzMFwyMjNcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI0MDRcMDMwXDIyNFwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ180MDVcMDMwXDIyNVwwMDMgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzQwNlwwMzBcMjI2XDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQwN1wwMzBcMjI3IiArCiAgICAgICJcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNDA4XDAzMFwyMzBcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ180MDlcMDMwXDIzMVwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTBcMDMwXDIzMlwwMDMgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzQxMVwwMzBcMjMzXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNDEyXDAzMFwyMzRcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNDEzXDAzMFwyMzVcMDAzIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ180MTRcMDMwXDIzNlwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180MTVcMDMwXDIzNyIgKwogICAgICAiXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzQxNlwwMzBcMjQwXDAwMyBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNDE3XDAzMFwyNDFcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDE4XDAzMFwyNDJcMDAzIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ180MTlcMDMwXDI0M1wwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjQyMFwwMzBcMjQ0XDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzQyMVwwMzBcMjQ1XDAwMyBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNDIyXDAzMFwyNDZcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDIzXDAzMFwyNDciICsKICAgICAgIlwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ180MjRcMDMwXDI1MFwwMDMgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzQyNVwwMzBcMjUxXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQyNlwwMzBcMjUyXDAwMyBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNDI3XDAzMFwyNTNcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiwKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjQyOFwwMzBcMjU0XDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzQyOVwwMzBcMjU1XDAwMyBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNDMwXDAzMFwyNTZcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDMxXDAzMFwyNTciICsKICAgICAgIlwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ180MzJcMDMwXDI2MFwwMDMgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzQzM1wwMzBcMjYxXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzNFwwMzBcMjYyXDAwMyBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNDM1XDAzMFwyNjNcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI0MzZcMDMwXDI2NFwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ180MzdcMDMwXDI2NVwwMDMgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzQzOFwwMzBcMjY2XDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQzOVwwMzBcMjY3IiArCiAgICAgICJcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNDQwXDAzMFwyNzBcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ180NDFcMDMwXDI3MVwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDJcMDMwXDI3MlwwMDMgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzQ0M1wwMzBcMjczXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNDQ0XDAzMFwyNzRcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNDQ1XDAzMFwyNzVcMDAzIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ180NDZcMDMwXDI3NlwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NDdcMDMwXDI3NyIgKwogICAgICAiXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzQ0OFwwMzBcMzAwXDAwMyBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNDQ5XDAzMFwzMDFcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDUwXDAzMFwzMDJcMDAzIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ180NTFcMDMwXDMwM1wwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjQ1MlwwMzBcMzA0XDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzQ1M1wwMzBcMzA1XDAwMyBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNDU0XDAzMFwzMDZcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDU1XDAzMFwzMDciICsKICAgICAgIlwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ180NTZcMDMwXDMxMFwwMDMgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzQ1N1wwMzBcMzExXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ1OFwwMzBcMzEyXDAwMyBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNDU5XDAzMFwzMTNcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI0NjBcMDMwXDMxNFwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ180NjFcMDMwXDMxNVwwMDMgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzQ2MlwwMzBcMzE2XDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ2M1wwMzBcMzE3IiArCiAgICAgICJcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNDY0XDAzMFwzMjBcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ180NjVcMDMwXDMyMVwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NjZcMDMwXDMyMlwwMDMgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzQ2N1wwMzBcMzIzXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNDY4XDAzMFwzMjRcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNDY5XDAzMFwzMjVcMDAzIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ180NzBcMDMwXDMyNlwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180NzFcMDMwXDMyNyIgKwogICAgICAiXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzQ3MlwwMzBcMzMwXDAwMyBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNDczXDAzMFwzMzFcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc0XDAzMFwzMzJcMDAzIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ180NzVcMDMwXDMzM1wwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjQ3NlwwMzBcMzM0XDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzQ3N1wwMzBcMzM1XDAwMyBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNDc4XDAzMFwzMzZcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDc5XDAzMFwzMzciICsKICAgICAgIlwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ180ODBcMDMwXDM0MFwwMDMgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzQ4MVwwMzBcMzQxXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4MlwwMzBcMzQyXDAwMyBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNDgzXDAzMFwzNDNcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI0ODRcMDMwXDM0NFwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ180ODVcMDMwXDM0NVwwMDMgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzQ4NlwwMzBcMzQ2XDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzQ4N1wwMzBcMzQ3IiArCiAgICAgICJcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNDg4XDAzMFwzNTBcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ180ODlcMDMwXDM1MVwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTBcMDMwXDM1MlwwMDMgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzQ5MVwwMzBcMzUzXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNDkyXDAzMFwzNTRcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNDkzXDAzMFwzNTVcMDAzIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ180OTRcMDMwXDM1NlwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ180OTVcMDMwXDM1NyIgKwogICAgICAiXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzQ5NlwwMzBcMzYwXDAwMyBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNDk3XDAzMFwzNjFcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNDk4XDAzMFwzNjJcMDAzIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiwKICAgICAgIm9vb29vb29vb29vb25nXzQ5OVwwMzBcMzYzXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNTAwXDAzMFwzNjRcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNTAxXDAzMFwzNjVcMDAzIFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ181MDJcMDMwXDM2NlwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MDNcMDMwXDM2NyIgKwogICAgICAiXDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzUwNFwwMzBcMzcwXDAwMyBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNTA1XDAzMFwzNzFcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTA2XDAzMFwzNzJcMDAzIFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ181MDdcMDMwXDM3M1wwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjUwOFwwMzBcMzc0XDAwMyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzUwOVwwMzBcMzc1XDAwMyBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNTEwXDAzMFwzNzZcMDAzIFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTExXDAzMFwzNzciICsKICAgICAgIlwwMDMgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ181MTJcMDMwXDIwMFwwMDQgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzUxM1wwMzBcMjAxXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxNFwwMzBcMjAyXDAwNCBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNTE1XDAzMFwyMDNcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI1MTZcMDMwXDIwNFwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ181MTdcMDMwXDIwNVwwMDQgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzUxOFwwMzBcMjA2XDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUxOVwwMzBcMjA3IiArCiAgICAgICJcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNTIwXDAzMFwyMTBcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ181MjFcMDMwXDIxMVwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjJcMDMwXDIxMlwwMDQgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzUyM1wwMzBcMjEzXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNTI0XDAzMFwyMTRcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNTI1XDAzMFwyMTVcMDA0IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ181MjZcMDMwXDIxNlwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181MjdcMDMwXDIxNyIgKwogICAgICAiXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzUyOFwwMzBcMjIwXDAwNCBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNTI5XDAzMFwyMjFcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTMwXDAzMFwyMjJcMDA0IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ181MzFcMDMwXDIyM1wwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjUzMlwwMzBcMjI0XDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzUzM1wwMzBcMjI1XDAwNCBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNTM0XDAzMFwyMjZcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTM1XDAzMFwyMjciICsKICAgICAgIlwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ181MzZcMDMwXDIzMFwwMDQgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzUzN1wwMzBcMjMxXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzUzOFwwMzBcMjMyXDAwNCBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNTM5XDAzMFwyMzNcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI1NDBcMDMwXDIzNFwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ181NDFcMDMwXDIzNVwwMDQgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzU0MlwwMzBcMjM2XDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU0M1wwMzBcMjM3IiArCiAgICAgICJcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNTQ0XDAzMFwyNDBcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ181NDVcMDMwXDI0MVwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NDZcMDMwXDI0MlwwMDQgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzU0N1wwMzBcMjQzXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNTQ4XDAzMFwyNDRcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNTQ5XDAzMFwyNDVcMDA0IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ181NTBcMDMwXDI0NlwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NTFcMDMwXDI0NyIgKwogICAgICAiXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzU1MlwwMzBcMjUwXDAwNCBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNTUzXDAzMFwyNTFcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU0XDAzMFwyNTJcMDA0IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ181NTVcMDMwXDI1M1wwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjU1NlwwMzBcMjU0XDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzU1N1wwMzBcMjU1XDAwNCBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNTU4XDAzMFwyNTZcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTU5XDAzMFwyNTciICsKICAgICAgIlwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ181NjBcMDMwXDI2MFwwMDQgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzU2MVwwMzBcMjYxXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2MlwwMzBcMjYyXDAwNCBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNTYzXDAzMFwyNjNcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI1NjRcMDMwXDI2NFwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ181NjVcMDMwXDI2NVwwMDQgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzU2NlwwMzBcMjY2XDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU2N1wwMzBcMjY3IiArCiAgICAgICJcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNTY4XDAzMFwyNzBcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ181NjlcMDMwXDI3MVwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzBcMDMwXDI3MlwwMDQgXDAwMShcdCIsCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNTcxXDAzMFwyNzNcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI1NzJcMDMwXDI3NFwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ181NzNcMDMwXDI3NVwwMDQgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzU3NFwwMzBcMjc2XDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU3NVwwMzBcMjc3IiArCiAgICAgICJcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNTc2XDAzMFwzMDBcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ181NzdcMDMwXDMwMVwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181NzhcMDMwXDMwMlwwMDQgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzU3OVwwMzBcMzAzXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNTgwXDAzMFwzMDRcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNTgxXDAzMFwzMDVcMDA0IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ181ODJcMDMwXDMwNlwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ181ODNcMDMwXDMwNyIgKwogICAgICAiXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzU4NFwwMzBcMzEwXDAwNCBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNTg1XDAzMFwzMTFcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTg2XDAzMFwzMTJcMDA0IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ181ODdcMDMwXDMxM1wwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjU4OFwwMzBcMzE0XDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzU4OVwwMzBcMzE1XDAwNCBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNTkwXDAzMFwzMTZcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNTkxXDAzMFwzMTciICsKICAgICAgIlwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ181OTJcMDMwXDMyMFwwMDQgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzU5M1wwMzBcMzIxXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5NFwwMzBcMzIyXDAwNCBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNTk1XDAzMFwzMjNcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI1OTZcMDMwXDMyNFwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ181OTdcMDMwXDMyNVwwMDQgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzU5OFwwMzBcMzI2XDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzU5OVwwMzBcMzI3IiArCiAgICAgICJcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNjAwXDAzMFwzMzBcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ182MDFcMDMwXDMzMVwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDJcMDMwXDMzMlwwMDQgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzYwM1wwMzBcMzMzXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNjA0XDAzMFwzMzRcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNjA1XDAzMFwzMzVcMDA0IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ182MDZcMDMwXDMzNlwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MDdcMDMwXDMzNyIgKwogICAgICAiXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzYwOFwwMzBcMzQwXDAwNCBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNjA5XDAzMFwzNDFcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjEwXDAzMFwzNDJcMDA0IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ182MTFcMDMwXDM0M1wwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjYxMlwwMzBcMzQ0XDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzYxM1wwMzBcMzQ1XDAwNCBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNjE0XDAzMFwzNDZcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjE1XDAzMFwzNDciICsKICAgICAgIlwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ182MTZcMDMwXDM1MFwwMDQgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzYxN1wwMzBcMzUxXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYxOFwwMzBcMzUyXDAwNCBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNjE5XDAzMFwzNTNcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI2MjBcMDMwXDM1NFwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ182MjFcMDMwXDM1NVwwMDQgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzYyMlwwMzBcMzU2XDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzYyM1wwMzBcMzU3IiArCiAgICAgICJcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNjI0XDAzMFwzNjBcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ182MjVcMDMwXDM2MVwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MjZcMDMwXDM2MlwwMDQgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzYyN1wwMzBcMzYzXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNjI4XDAzMFwzNjRcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNjI5XDAzMFwzNjVcMDA0IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ182MzBcMDMwXDM2NlwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182MzFcMDMwXDM2NyIgKwogICAgICAiXDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzYzMlwwMzBcMzcwXDAwNCBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNjMzXDAzMFwzNzFcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM0XDAzMFwzNzJcMDA0IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ182MzVcMDMwXDM3M1wwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjYzNlwwMzBcMzc0XDAwNCBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzYzN1wwMzBcMzc1XDAwNCBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNjM4XDAzMFwzNzZcMDA0IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjM5XDAzMFwzNzciICsKICAgICAgIlwwMDQgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ182NDBcMDMwXDIwMFwwMDUgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzY0MVwwMzBcMjAxXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIsCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQyXDAzMFwyMDJcMDA1IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ182NDNcMDMwXDIwM1wwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjY0NFwwMzBcMjA0XDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzY0NVwwMzBcMjA1XDAwNSBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNjQ2XDAzMFwyMDZcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjQ3XDAzMFwyMDciICsKICAgICAgIlwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ182NDhcMDMwXDIxMFwwMDUgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzY0OVwwMzBcMjExXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1MFwwMzBcMjEyXDAwNSBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNjUxXDAzMFwyMTNcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI2NTJcMDMwXDIxNFwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ182NTNcMDMwXDIxNVwwMDUgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzY1NFwwMzBcMjE2XDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY1NVwwMzBcMjE3IiArCiAgICAgICJcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNjU2XDAzMFwyMjBcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ182NTdcMDMwXDIyMVwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NThcMDMwXDIyMlwwMDUgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzY1OVwwMzBcMjIzXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNjYwXDAzMFwyMjRcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNjYxXDAzMFwyMjVcMDA1IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ182NjJcMDMwXDIyNlwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182NjNcMDMwXDIyNyIgKwogICAgICAiXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzY2NFwwMzBcMjMwXDAwNSBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNjY1XDAzMFwyMzFcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjY2XDAzMFwyMzJcMDA1IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ182NjdcMDMwXDIzM1wwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjY2OFwwMzBcMjM0XDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzY2OVwwMzBcMjM1XDAwNSBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNjcwXDAzMFwyMzZcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjcxXDAzMFwyMzciICsKICAgICAgIlwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ182NzJcMDMwXDI0MFwwMDUgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzY3M1wwMzBcMjQxXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3NFwwMzBcMjQyXDAwNSBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNjc1XDAzMFwyNDNcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI2NzZcMDMwXDI0NFwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ182NzdcMDMwXDI0NVwwMDUgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzY3OFwwMzBcMjQ2XDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY3OVwwMzBcMjQ3IiArCiAgICAgICJcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNjgwXDAzMFwyNTBcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ182ODFcMDMwXDI1MVwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODJcMDMwXDI1MlwwMDUgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzY4M1wwMzBcMjUzXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNjg0XDAzMFwyNTRcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNjg1XDAzMFwyNTVcMDA1IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ182ODZcMDMwXDI1NlwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ182ODdcMDMwXDI1NyIgKwogICAgICAiXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzY4OFwwMzBcMjYwXDAwNSBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNjg5XDAzMFwyNjFcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjkwXDAzMFwyNjJcMDA1IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ182OTFcMDMwXDI2M1wwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjY5MlwwMzBcMjY0XDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzY5M1wwMzBcMjY1XDAwNSBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNjk0XDAzMFwyNjZcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNjk1XDAzMFwyNjciICsKICAgICAgIlwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ182OTZcMDMwXDI3MFwwMDUgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzY5N1wwMzBcMjcxXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzY5OFwwMzBcMjcyXDAwNSBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNjk5XDAzMFwyNzNcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI3MDBcMDMwXDI3NFwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ183MDFcMDMwXDI3NVwwMDUgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzcwMlwwMzBcMjc2XDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzcwM1wwMzBcMjc3IiArCiAgICAgICJcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNzA0XDAzMFwzMDBcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ183MDVcMDMwXDMwMVwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MDZcMDMwXDMwMlwwMDUgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzcwN1wwMzBcMzAzXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNzA4XDAzMFwzMDRcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNzA5XDAzMFwzMDVcMDA1IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ183MTBcMDMwXDMwNlwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTFcMDMwXDMwNyIgKwogICAgICAiXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzcxMlwwMzBcMzEwXDAwNSBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIsCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ183MTNcMDMwXDMxMVwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTRcMDMwXDMxMlwwMDUgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzcxNVwwMzBcMzEzXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNzE2XDAzMFwzMTRcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNzE3XDAzMFwzMTVcMDA1IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ183MThcMDMwXDMxNlwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MTlcMDMwXDMxNyIgKwogICAgICAiXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzcyMFwwMzBcMzIwXDAwNSBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNzIxXDAzMFwzMjFcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzIyXDAzMFwzMjJcMDA1IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ183MjNcMDMwXDMyM1wwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjcyNFwwMzBcMzI0XDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzcyNVwwMzBcMzI1XDAwNSBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNzI2XDAzMFwzMjZcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzI3XDAzMFwzMjciICsKICAgICAgIlwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ183MjhcMDMwXDMzMFwwMDUgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzcyOVwwMzBcMzMxXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczMFwwMzBcMzMyXDAwNSBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNzMxXDAzMFwzMzNcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI3MzJcMDMwXDMzNFwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ183MzNcMDMwXDMzNVwwMDUgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzczNFwwMzBcMzM2XDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzczNVwwMzBcMzM3IiArCiAgICAgICJcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNzM2XDAzMFwzNDBcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ183MzdcMDMwXDM0MVwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183MzhcMDMwXDM0MlwwMDUgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzczOVwwMzBcMzQzXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNzQwXDAzMFwzNDRcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNzQxXDAzMFwzNDVcMDA1IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ183NDJcMDMwXDM0NlwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NDNcMDMwXDM0NyIgKwogICAgICAiXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzc0NFwwMzBcMzUwXDAwNSBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNzQ1XDAzMFwzNTFcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzQ2XDAzMFwzNTJcMDA1IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ183NDdcMDMwXDM1M1wwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjc0OFwwMzBcMzU0XDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzc0OVwwMzBcMzU1XDAwNSBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNzUwXDAzMFwzNTZcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzUxXDAzMFwzNTciICsKICAgICAgIlwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ183NTJcMDMwXDM2MFwwMDUgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzc1M1wwMzBcMzYxXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1NFwwMzBcMzYyXDAwNSBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNzU1XDAzMFwzNjNcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI3NTZcMDMwXDM2NFwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ183NTdcMDMwXDM2NVwwMDUgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzc1OFwwMzBcMzY2XDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc1OVwwMzBcMzY3IiArCiAgICAgICJcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNzYwXDAzMFwzNzBcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ183NjFcMDMwXDM3MVwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjJcMDMwXDM3MlwwMDUgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzc2M1wwMzBcMzczXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNzY0XDAzMFwzNzRcMDA1IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNzY1XDAzMFwzNzVcMDA1IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ183NjZcMDMwXDM3NlwwMDUgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183NjdcMDMwXDM3NyIgKwogICAgICAiXDAwNSBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzc2OFwwMzBcMjAwXDAwNiBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfNzY5XDAzMFwyMDFcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzcwXDAzMFwyMDJcMDA2IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ183NzFcMDMwXDIwM1wwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjc3MlwwMzBcMjA0XDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzc3M1wwMzBcMjA1XDAwNiBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfNzc0XDAzMFwyMDZcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfNzc1XDAzMFwyMDciICsKICAgICAgIlwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ183NzZcMDMwXDIxMFwwMDYgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzc3N1wwMzBcMjExXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc3OFwwMzBcMjEyXDAwNiBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNzc5XDAzMFwyMTNcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI3ODBcMDMwXDIxNFwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ183ODFcMDMwXDIxNVwwMDYgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzc4MlwwMzBcMjE2XDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4M1wwMzBcMjE3IiArCiAgICAgICJcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIsCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ183ODRcMDMwXDIyMFwwMDYgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzc4NVwwMzBcMjIxXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc4NlwwMzBcMjIyXDAwNiBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfNzg3XDAzMFwyMjNcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI3ODhcMDMwXDIyNFwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ183ODlcMDMwXDIyNVwwMDYgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzc5MFwwMzBcMjI2XDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzc5MVwwMzBcMjI3IiArCiAgICAgICJcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfNzkyXDAzMFwyMzBcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ183OTNcMDMwXDIzMVwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTRcMDMwXDIzMlwwMDYgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzc5NVwwMzBcMjMzXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiNzk2XDAzMFwyMzRcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfNzk3XDAzMFwyMzVcMDA2IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ183OThcMDMwXDIzNlwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ183OTlcMDMwXDIzNyIgKwogICAgICAiXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzgwMFwwMzBcMjQwXDAwNiBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfODAxXDAzMFwyNDFcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODAyXDAzMFwyNDJcMDA2IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ184MDNcMDMwXDI0M1wwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjgwNFwwMzBcMjQ0XDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzgwNVwwMzBcMjQ1XDAwNiBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfODA2XDAzMFwyNDZcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODA3XDAzMFwyNDciICsKICAgICAgIlwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ184MDhcMDMwXDI1MFwwMDYgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzgwOVwwMzBcMjUxXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxMFwwMzBcMjUyXDAwNiBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfODExXDAzMFwyNTNcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI4MTJcMDMwXDI1NFwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ184MTNcMDMwXDI1NVwwMDYgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzgxNFwwMzBcMjU2XDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgxNVwwMzBcMjU3IiArCiAgICAgICJcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfODE2XDAzMFwyNjBcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ184MTdcMDMwXDI2MVwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MThcMDMwXDI2MlwwMDYgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzgxOVwwMzBcMjYzXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiODIwXDAzMFwyNjRcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfODIxXDAzMFwyNjVcMDA2IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ184MjJcMDMwXDI2NlwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184MjNcMDMwXDI2NyIgKwogICAgICAiXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzgyNFwwMzBcMjcwXDAwNiBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfODI1XDAzMFwyNzFcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODI2XDAzMFwyNzJcMDA2IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ184MjdcMDMwXDI3M1wwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjgyOFwwMzBcMjc0XDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzgyOVwwMzBcMjc1XDAwNiBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfODMwXDAzMFwyNzZcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODMxXDAzMFwyNzciICsKICAgICAgIlwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ184MzJcMDMwXDMwMFwwMDYgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzgzM1wwMzBcMzAxXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzNFwwMzBcMzAyXDAwNiBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfODM1XDAzMFwzMDNcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI4MzZcMDMwXDMwNFwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ184MzdcMDMwXDMwNVwwMDYgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzgzOFwwMzBcMzA2XDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzgzOVwwMzBcMzA3IiArCiAgICAgICJcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfODQwXDAzMFwzMTBcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ184NDFcMDMwXDMxMVwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDJcMDMwXDMxMlwwMDYgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzg0M1wwMzBcMzEzXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiODQ0XDAzMFwzMTRcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfODQ1XDAzMFwzMTVcMDA2IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ184NDZcMDMwXDMxNlwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NDdcMDMwXDMxNyIgKwogICAgICAiXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzg0OFwwMzBcMzIwXDAwNiBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfODQ5XDAzMFwzMjFcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODUwXDAzMFwzMjJcMDA2IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ184NTFcMDMwXDMyM1wwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjg1MlwwMzBcMzI0XDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzg1M1wwMzBcMzI1XDAwNiBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfODU0XDAzMFwzMjZcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIsCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NTVcMDMwXDMyNyIgKwogICAgICAiXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzg1NlwwMzBcMzMwXDAwNiBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfODU3XDAzMFwzMzFcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODU4XDAzMFwzMzJcMDA2IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ184NTlcMDMwXDMzM1wwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjg2MFwwMzBcMzM0XDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzg2MVwwMzBcMzM1XDAwNiBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfODYyXDAzMFwzMzZcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODYzXDAzMFwzMzciICsKICAgICAgIlwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ184NjRcMDMwXDM0MFwwMDYgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzg2NVwwMzBcMzQxXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg2NlwwMzBcMzQyXDAwNiBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfODY3XDAzMFwzNDNcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI4NjhcMDMwXDM0NFwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ184NjlcMDMwXDM0NVwwMDYgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzg3MFwwMzBcMzQ2XDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg3MVwwMzBcMzQ3IiArCiAgICAgICJcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfODcyXDAzMFwzNTBcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ184NzNcMDMwXDM1MVwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzRcMDMwXDM1MlwwMDYgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzg3NVwwMzBcMzUzXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiODc2XDAzMFwzNTRcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfODc3XDAzMFwzNTVcMDA2IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ184NzhcMDMwXDM1NlwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184NzlcMDMwXDM1NyIgKwogICAgICAiXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzg4MFwwMzBcMzYwXDAwNiBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfODgxXDAzMFwzNjFcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODgyXDAzMFwzNjJcMDA2IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ184ODNcMDMwXDM2M1wwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjg4NFwwMzBcMzY0XDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzg4NVwwMzBcMzY1XDAwNiBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfODg2XDAzMFwzNjZcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfODg3XDAzMFwzNjciICsKICAgICAgIlwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ184ODhcMDMwXDM3MFwwMDYgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzg4OVwwMzBcMzcxXDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5MFwwMzBcMzcyXDAwNiBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfODkxXDAzMFwzNzNcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI4OTJcMDMwXDM3NFwwMDYgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ184OTNcMDMwXDM3NVwwMDYgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzg5NFwwMzBcMzc2XDAwNiBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzg5NVwwMzBcMzc3IiArCiAgICAgICJcMDA2IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfODk2XDAzMFwyMDBcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ184OTdcMDMwXDIwMVwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ184OThcMDMwXDIwMlwwMDcgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzg5OVwwMzBcMjAzXDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiOTAwXDAzMFwyMDRcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfOTAxXDAzMFwyMDVcMDA3IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ185MDJcMDMwXDIwNlwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MDNcMDMwXDIwNyIgKwogICAgICAiXDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzkwNFwwMzBcMjEwXDAwNyBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfOTA1XDAzMFwyMTFcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTA2XDAzMFwyMTJcMDA3IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ185MDdcMDMwXDIxM1wwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjkwOFwwMzBcMjE0XDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzkwOVwwMzBcMjE1XDAwNyBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfOTEwXDAzMFwyMTZcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTExXDAzMFwyMTciICsKICAgICAgIlwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ185MTJcMDMwXDIyMFwwMDcgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzkxM1wwMzBcMjIxXDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxNFwwMzBcMjIyXDAwNyBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfOTE1XDAzMFwyMjNcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI5MTZcMDMwXDIyNFwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ185MTdcMDMwXDIyNVwwMDcgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzkxOFwwMzBcMjI2XDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkxOVwwMzBcMjI3IiArCiAgICAgICJcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfOTIwXDAzMFwyMzBcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ185MjFcMDMwXDIzMVwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MjJcMDMwXDIzMlwwMDcgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzkyM1wwMzBcMjMzXDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiOTI0XDAzMFwyMzRcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfOTI1XDAzMFwyMzVcMDA3IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiLAogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzkyNlwwMzBcMjM2XDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzkyN1wwMzBcMjM3IiArCiAgICAgICJcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfOTI4XDAzMFwyNDBcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ185MjlcMDMwXDI0MVwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzBcMDMwXDI0MlwwMDcgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzkzMVwwMzBcMjQzXDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiOTMyXDAzMFwyNDRcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfOTMzXDAzMFwyNDVcMDA3IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ185MzRcMDMwXDI0NlwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185MzVcMDMwXDI0NyIgKwogICAgICAiXDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzkzNlwwMzBcMjUwXDAwNyBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfOTM3XDAzMFwyNTFcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTM4XDAzMFwyNTJcMDA3IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ185MzlcMDMwXDI1M1wwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjk0MFwwMzBcMjU0XDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzk0MVwwMzBcMjU1XDAwNyBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfOTQyXDAzMFwyNTZcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTQzXDAzMFwyNTciICsKICAgICAgIlwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ185NDRcMDMwXDI2MFwwMDcgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzk0NVwwMzBcMjYxXDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk0NlwwMzBcMjYyXDAwNyBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfOTQ3XDAzMFwyNjNcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI5NDhcMDMwXDI2NFwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ185NDlcMDMwXDI2NVwwMDcgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzk1MFwwMzBcMjY2XDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk1MVwwMzBcMjY3IiArCiAgICAgICJcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfOTUyXDAzMFwyNzBcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ185NTNcMDMwXDI3MVwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTRcMDMwXDI3MlwwMDcgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzk1NVwwMzBcMjczXDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiOTU2XDAzMFwyNzRcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfOTU3XDAzMFwyNzVcMDA3IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ185NThcMDMwXDI3NlwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NTlcMDMwXDI3NyIgKwogICAgICAiXDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzk2MFwwMzBcMzAwXDAwNyBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfOTYxXDAzMFwzMDFcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTYyXDAzMFwzMDJcMDA3IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ185NjNcMDMwXDMwM1wwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjk2NFwwMzBcMzA0XDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzk2NVwwMzBcMzA1XDAwNyBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfOTY2XDAzMFwzMDZcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTY3XDAzMFwzMDciICsKICAgICAgIlwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ185NjhcMDMwXDMxMFwwMDcgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzk2OVwwMzBcMzExXDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3MFwwMzBcMzEyXDAwNyBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfOTcxXDAzMFwzMTNcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI5NzJcMDMwXDMxNFwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ185NzNcMDMwXDMxNVwwMDcgXDAwMShcdDpwbG9uIiArCiAgICAgICJnIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZiIgKwogICAgICAiaWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXzk3NFwwMzBcMzE2XDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUiICsKICAgICAgIiBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk3NVwwMzBcMzE3IiArCiAgICAgICJcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMiIgKwogICAgICAiXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdfOTc2XDAzMFwzMjBcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmIiArCiAgICAgICJhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkXyIgKwogICAgICAibmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ185NzdcMDMwXDMyMVwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGEiICsKICAgICAgImxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185NzhcMDMwXDMyMlwwMDcgXDAwMShcdCIgKwogICAgICAiOnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2wiICsKICAgICAgIm9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb25nXzk3OVwwMzBcMzIzXDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgIiArCiAgICAgICJ2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lXyIgKwogICAgICAiaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXyIgKwogICAgICAiOTgwXDAzMFwzMjRcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGwiICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vbmdfOTgxXDAzMFwzMjVcMDA3IFwwMDEoXHQ6cGxvbiIgKwogICAgICAiZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2YiICsKICAgICAgImllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29uZ185ODJcMDMwXDMyNlwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIiArCiAgICAgICIgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ185ODNcMDMwXDMyNyIgKwogICAgICAiXDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ1wwMjIiICsKICAgICAgIlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb25nXzk4NFwwMzBcMzMwXDAwNyBcMDAxKFx0OnBsb25nIGRlZiIgKwogICAgICAiYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF8iICsKICAgICAgIm5hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vbmdfOTg1XDAzMFwzMzFcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhIiArCiAgICAgICJsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG9vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTg2XDAzMFwzMzJcMDA3IFwwMDEoXHQiICsKICAgICAgIjpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsIiArCiAgICAgICJvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29uZ185ODdcMDMwXDMzM1wwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0ICIgKwogICAgICAidmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV8iICsKICAgICAgImlzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZ18iICsKICAgICAgIjk4OFwwMzBcMzM0XDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYWxzbyBsIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzk4OVwwMzBcMzM1XDAwNyBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfOTkwXDAzMFwzMzZcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTkxXDAzMFwzMzciICsKICAgICAgIlwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ185OTJcMDMwXDM0MFwwMDcgXDAwMShcdDpwbG9uZyBkZWYiICsKICAgICAgImF1bHQgdmFsdWUgaXMgYWxzbyBsb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfIiArCiAgICAgICJuYW1lX2lzX2xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb25nXzk5M1wwMzBcMzQxXDAwNyBcMDAxKFx0OnBsb25nIGRlZmF1bHQgdmFsdWUgaXMgYSIgKwogICAgICAibHNvIGxvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19maWVsZF9uYW1lX2lzX2xvb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXzk5NFwwMzBcMzQyXDAwNyBcMDAxKFx0IiArCiAgICAgICI6cGxvbmcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbCIgKwogICAgICAib25nX2ZpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdfOTk1XDAzMFwzNDNcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCAiICsKICAgICAgInZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfIiArCiAgICAgICJpc19sb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfIiArCiAgICAgICI5OTZcMDMwXDM0NFwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbCIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29uZ1wwMjJcMzM2XDAwMVxuY2xvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb28iLAogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb25nXzk5N1wwMzBcMzQ1XDAwNyBcMDAxKFx0OnBsb24iICsKICAgICAgImcgZGVmYXVsdCB2YWx1ZSBpcyBhbHNvIGxvb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb25nXDAyMlwzMzZcMDAxXG5jbG9uZ19mIiArCiAgICAgICJpZWxkX25hbWVfaXNfbG9vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vbmdfOTk4XDAzMFwzNDZcMDA3IFwwMDEoXHQ6cGxvbmcgZGVmYXVsdCB2YWx1ZSIgKwogICAgICAiIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vbmdcMDIyXDMzNlwwMDFcbmNsb25nX2ZpZWxkX25hbWVfaXNfbG8iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdfOTk5XDAzMFwzNDciICsKICAgICAgIlwwMDcgXDAwMShcdDpwbG9uZyBkZWZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vIiArCiAgICAgICJvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmdcMDIyIiArCiAgICAgICJcMzM3XDAwMVxuZGxvbmdfZmllbGRfbmFtZV9pc19sb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbyIgKwogICAgICAib29vb29vb29vb29vb29vb29uZ18xMDAwXDAzMFwzNTBcMDA3IFwwMDEoXHQ6cGxvbmcgZGUiICsKICAgICAgImZhdWx0IHZhbHVlIGlzIGFsc28gbG9vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28iICsKICAgICAgIm9vb29vb29vb29vb29vb29vb29vb29vbmdCXDAyN1xuXDAyM2NvbS5nb29nbGUuIiArCiAgICAgICJwcm90b2J1ZkhcMDAyIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVub3Jtb3VzRGVzY3JpcHRvcl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW5vcm1vdXNEZXNjcmlwdG9yX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbm9ybW91c0Rlc2NyaXB0b3JfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwMSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTAyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEwNyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTA4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTExIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExMyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExNiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTE3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMTgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzExOSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyMiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTIzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyNSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMjciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEyOCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTI5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzMSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTMyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzEzNyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTM4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMzkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTQ3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNDgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE0OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTUzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNTciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE1OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTU5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTYyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE2NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTY4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNjkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTcxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTc3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxNzgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE3OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTgzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxODciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE4OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTg5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTkyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzE5NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMTk4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxOTkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjAxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwMyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwNiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjA3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMDgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIwOSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxMiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjEzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxNSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMTciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIxOCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjE5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyMSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjIyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIyNyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjI4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMjkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjMxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzMyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzNiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjM3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyMzgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzIzOSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNDciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI0OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjQ5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjUyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI1NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjU4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNTkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjYxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjY3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNjgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI2OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjcwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjczIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyNzciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI3OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjc5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjgyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI4NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjg4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyODkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjkxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMjk3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcyOTgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzI5OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwMiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzAzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwNSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMDciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMwOCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzA5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxMSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzEyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMxNyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzE4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMTkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzIxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyMyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyNiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzI3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMjgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMyOSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzMiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzMzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzNSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczMzciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzMzOCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzM5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM0NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzQ4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNDkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzUxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzU3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNTgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM1OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzYzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNjciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM2OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzY5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzcyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM3NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzc4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczNzkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzgxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzg3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczODgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM4OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzkzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmczOTciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzM5OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nMzk5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwMSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDAyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQwNyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDA4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MDkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDExIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxMyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxNiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDE3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MTgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQxOSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyMiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDIzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyNSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MjciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQyOCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDI5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzMSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDMyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQzNyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDM4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0MzkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDQ3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NDgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ0OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDUzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NTciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ1OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDU5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDYyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ2NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDY4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NjkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDcxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDc3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0NzgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ3OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDgzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0ODciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ4OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDg5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDkyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzQ5NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNDk4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc0OTkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTAxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwMyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwNiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTA3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MDgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUwOSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxMiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTEzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxNSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MTciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUxOCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTE5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyMSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTIyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUyNyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTI4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MjkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTMxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzMyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzNiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTM3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1MzgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzUzOSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NDciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU0OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTQ5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTUyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU1NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTU4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NTkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTYxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTY3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NjgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU2OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTcwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTczIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1NzciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU3OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTc5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTgyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU4NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTg4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1ODkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTkxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNTk3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc1OTgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzU5OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwMiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjAzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwNSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MDciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYwOCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjA5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxMSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjEyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYxNyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjE4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MTkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjIxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyMyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyNiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjI3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MjgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYyOSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzMiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjMzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzNSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2MzciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzYzOCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjM5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY0NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjQ4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NDkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjUxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjU3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NTgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY1OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjYzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NjciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY2OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjY5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjcyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY3NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjc4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2NzkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjgxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjg3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2ODgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY4OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjkzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc2OTciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzY5OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNjk5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwMSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzAyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcwNyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzA4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MDkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzExIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxMyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxNiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzE3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MTgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcxOSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyMiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzIzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyNSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MjciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzcyOCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzI5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczMSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzMyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzczNyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzM4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3MzkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzQ3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NDgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc0OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzUzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NTciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc1OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzU5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzYyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc2NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzY4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NjkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzcxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzc3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3NzgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc3OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzgzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3ODciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc4OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzg5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzkyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzc5NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nNzk4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc3OTkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODAxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwMyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwNiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODA3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MDgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgwOSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxMiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODEzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxNSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MTciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgxOCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODE5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyMSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODIyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgyNyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODI4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MjkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODMxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzMyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzNiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODM3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4MzgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzgzOSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NDciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg0OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODQ5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODUyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg1NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODU4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NTkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODYxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODY3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NjgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg2OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODcwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODczIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4NzciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg3OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODc5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODgyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg4NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODg4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4ODkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODkxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nODk3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc4OTgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzg5OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwMiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTAzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwNSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MDciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkwOCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTA5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxMSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTEyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkxNyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTE4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MTkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTIxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyMyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyNiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTI3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MjgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkyOSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzMiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTMzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzNSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5MzciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzkzOCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTM5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk0NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTQ4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NDkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTUxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTU3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NTgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk1OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTYzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NjciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk2OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTY5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzAiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3MSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTcyIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzMiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc1IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzYiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk3NyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTc4IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5NzkiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTgxIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODIiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4MyIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg0IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODUiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4NiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTg3IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5ODgiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk4OSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkwIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTEiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5MiIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTkzIiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTQiLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5NSIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk2IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmc5OTciLCAiTG9uZ0ZpZWxkTmFtZUlzTG9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29uZzk5OCIsICJMb25nRmllbGROYW1lSXNMb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb25nOTk5IiwgIkxvbmdGaWVsZE5hbWVJc0xvb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vbmcxMDAwIiwgfSk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQDBifR6/EoDAPxKAwAvAAAAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0L01hcFdlbGxLbm93blR5cGVzLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF93ZWxsX2tub3duX3R5cGVzLnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3Q7CgovKioKICogPHByZT4KICogQSBtYXAgZmllbGQgZm9yIGVhY2ggd2VsbC1rbm93biB0eXBlLiBXZSBvbmx5CiAqIG5lZWQgdG8gd29ycnkgYWJvdXQgdGhlIHZhbHVlIHBhcnQgb2YgdGhlIG1hcCBiZWluZyB0aGUKICogd2VsbC1rbm93biB0eXBlcywgYXMgbWVzc2FnZXMgY2FuJ3QgYmUgbWFwIGtleXMuCiAqIDwvcHJlPgogKgogKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NYXBXZWxsS25vd25UeXBlc30KICovCnB1YmxpYyBmaW5hbCBjbGFzcyBNYXBXZWxsS25vd25UeXBlcyBleHRlbmRzCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzKQogICAgTWFwV2VsbEtub3duVHlwZXNPckJ1aWxkZXIgewpwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAvLyBVc2UgTWFwV2VsbEtub3duVHlwZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICBwcml2YXRlIE1hcFdlbGxLbm93blR5cGVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgc3VwZXIoYnVpbGRlcik7CiAgfQogIHByaXZhdGUgTWFwV2VsbEtub3duVHlwZXMoKSB7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgIHJldHVybiBuZXcgTWFwV2VsbEtub3duVHlwZXMoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0V2VsbEtub3duVHlwZXMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3I7CiAgfQoKICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICBpbnQgbnVtYmVyKSB7CiAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICBjYXNlIDE6CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QW55RmllbGQoKTsKICAgICAgY2FzZSAyOgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFwaUZpZWxkKCk7CiAgICAgIGNhc2UgMzoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXREdXJhdGlvbkZpZWxkKCk7CiAgICAgIGNhc2UgNDoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbXB0eUZpZWxkKCk7CiAgICAgIGNhc2UgNToKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hc2tGaWVsZCgpOwogICAgICBjYXNlIDY6CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U291cmNlQ29udGV4dEZpZWxkKCk7CiAgICAgIGNhc2UgNzoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJ1Y3RGaWVsZCgpOwogICAgICBjYXNlIDg6CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VGltZXN0YW1wRmllbGQoKTsKICAgICAgY2FzZSA5OgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFR5cGVGaWVsZCgpOwogICAgICBjYXNlIDEwOgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldERvdWJsZUZpZWxkKCk7CiAgICAgIGNhc2UgMTE6CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmxvYXRGaWVsZCgpOwogICAgICBjYXNlIDEyOgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDY0RmllbGQoKTsKICAgICAgY2FzZSAxMzoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVaW50NjRGaWVsZCgpOwogICAgICBjYXNlIDE0OgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyRmllbGQoKTsKICAgICAgY2FzZSAxNToKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVaW50MzJGaWVsZCgpOwogICAgICBjYXNlIDE2OgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEJvb2xGaWVsZCgpOwogICAgICBjYXNlIDE3OgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ0ZpZWxkKCk7CiAgICAgIGNhc2UgMTg6CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Qnl0ZXNGaWVsZCgpOwogICAgICBkZWZhdWx0OgogICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgIH0KICB9CiAgQGphdmEubGFuZy5PdmVycmlkZQogIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0V2VsbEtub3duVHlwZXMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuTWFwV2VsbEtub3duVHlwZXMuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5NYXBXZWxsS25vd25UeXBlcy5CdWlsZGVyLmNsYXNzKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFOWV9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEFueUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RXZWxsS25vd25UeXBlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfQW55RmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIH0KICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueT4gYW55RmllbGRfOwogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Bbnk+CiAgaW50ZXJuYWxHZXRBbnlGaWVsZCgpIHsKICAgIGlmIChhbnlGaWVsZF8gPT0gbnVsbCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgQW55RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgIH0KICAgIHJldHVybiBhbnlGaWVsZF87CiAgfQogIHB1YmxpYyBpbnQgZ2V0QW55RmllbGRDb3VudCgpIHsKICAgIHJldHVybiBpbnRlcm5hbEdldEFueUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQW55Jmd0OyBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gY29udGFpbnNBbnlGaWVsZCgKICAgICAgaW50IGtleSkgewoKICAgIHJldHVybiBpbnRlcm5hbEdldEFueUZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICB9CiAgLyoqCiAgICogVXNlIHtAbGluayAjZ2V0QW55RmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55PiBnZXRBbnlGaWVsZCgpIHsKICAgIHJldHVybiBnZXRBbnlGaWVsZE1hcCgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQW55Jmd0OyBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55PiBnZXRBbnlGaWVsZE1hcCgpIHsKICAgIHJldHVybiBpbnRlcm5hbEdldEFueUZpZWxkKCkuZ2V0TWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5BbnkmZ3Q7IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkgZ2V0QW55RmllbGRPckRlZmF1bHQoCiAgICAgIGludCBrZXksCiAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQW55IGRlZmF1bHRWYWx1ZSkgewoKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55PiBtYXAgPQogICAgICAgIGludGVybmFsR2V0QW55RmllbGQoKS5nZXRNYXAoKTsKICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkFueSZndDsgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSBnZXRBbnlGaWVsZE9yVGhyb3coCiAgICAgIGludCBrZXkpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueT4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldEFueUZpZWxkKCkuZ2V0TWFwKCk7CiAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICB9CiAgICByZXR1cm4gbWFwLmdldChrZXkpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVBJX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDI7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQXBpRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19BcGlGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgfQogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpPiBhcGlGaWVsZF87CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaT4KICBpbnRlcm5hbEdldEFwaUZpZWxkKCkgewogICAgaWYgKGFwaUZpZWxkXyA9PSBudWxsKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICBBcGlGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgfQogICAgcmV0dXJuIGFwaUZpZWxkXzsKICB9CiAgcHVibGljIGludCBnZXRBcGlGaWVsZENvdW50KCkgewogICAgcmV0dXJuIGludGVybmFsR2V0QXBpRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5BcGkmZ3Q7IGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0FwaUZpZWxkKAogICAgICBpbnQga2V5KSB7CgogICAgcmV0dXJuIGludGVybmFsR2V0QXBpRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogIH0KICAvKioKICAgKiBVc2Uge0BsaW5rICNnZXRBcGlGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGk+IGdldEFwaUZpZWxkKCkgewogICAgcmV0dXJuIGdldEFwaUZpZWxkTWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5BcGkmZ3Q7IGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGk+IGdldEFwaUZpZWxkTWFwKCkgewogICAgcmV0dXJuIGludGVybmFsR2V0QXBpRmllbGQoKS5nZXRNYXAoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkFwaSZndDsgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSBnZXRBcGlGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkgZGVmYXVsdFZhbHVlKSB7CgogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGk+IG1hcCA9CiAgICAgICAgaW50ZXJuYWxHZXRBcGlGaWVsZCgpLmdldE1hcCgpOwogICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQXBpJmd0OyBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQXBpIGdldEFwaUZpZWxkT3JUaHJvdygKICAgICAgaW50IGtleSkgewoKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpPiBtYXAgPQogICAgICAgIGludGVybmFsR2V0QXBpRmllbGQoKS5nZXRNYXAoKTsKICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgIH0KICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVVJBVElPTl9GSUVMRF9GSUVMRF9OVU1CRVIgPSAzOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIER1cmF0aW9uRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RXZWxsS25vd25UeXBlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRHVyYXRpb25GaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICB9CiAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbj4gZHVyYXRpb25GaWVsZF87CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uPgogIGludGVybmFsR2V0RHVyYXRpb25GaWVsZCgpIHsKICAgIGlmIChkdXJhdGlvbkZpZWxkXyA9PSBudWxsKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICBEdXJhdGlvbkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICB9CiAgICByZXR1cm4gZHVyYXRpb25GaWVsZF87CiAgfQogIHB1YmxpYyBpbnQgZ2V0RHVyYXRpb25GaWVsZENvdW50KCkgewogICAgcmV0dXJuIGludGVybmFsR2V0RHVyYXRpb25GaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uJmd0OyBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0R1cmF0aW9uRmllbGQoCiAgICAgIGludCBrZXkpIHsKCiAgICByZXR1cm4gaW50ZXJuYWxHZXREdXJhdGlvbkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICB9CiAgLyoqCiAgICogVXNlIHtAbGluayAjZ2V0RHVyYXRpb25GaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbj4gZ2V0RHVyYXRpb25GaWVsZCgpIHsKICAgIHJldHVybiBnZXREdXJhdGlvbkZpZWxkTWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiZndDsgZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24+IGdldER1cmF0aW9uRmllbGRNYXAoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxHZXREdXJhdGlvbkZpZWxkKCkuZ2V0TWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiZndDsgZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZ2V0RHVyYXRpb25GaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkZWZhdWx0VmFsdWUpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uPiBtYXAgPQogICAgICAgIGludGVybmFsR2V0RHVyYXRpb25GaWVsZCgpLmdldE1hcCgpOwogICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24mZ3Q7IGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGdldER1cmF0aW9uRmllbGRPclRocm93KAogICAgICBpbnQga2V5KSB7CgogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbj4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldER1cmF0aW9uRmllbGQoKS5nZXRNYXAoKTsKICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgIH0KICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTVBUWV9GSUVMRF9GSUVMRF9OVU1CRVIgPSA0OwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEVtcHR5RmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHk+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RXZWxsS25vd25UeXBlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRW1wdHlGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICB9CiAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eT4gZW1wdHlGaWVsZF87CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PgogIGludGVybmFsR2V0RW1wdHlGaWVsZCgpIHsKICAgIGlmIChlbXB0eUZpZWxkXyA9PSBudWxsKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICBFbXB0eUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICB9CiAgICByZXR1cm4gZW1wdHlGaWVsZF87CiAgfQogIHB1YmxpYyBpbnQgZ2V0RW1wdHlGaWVsZENvdW50KCkgewogICAgcmV0dXJuIGludGVybmFsR2V0RW1wdHlGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkVtcHR5Jmd0OyBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0VtcHR5RmllbGQoCiAgICAgIGludCBrZXkpIHsKCiAgICByZXR1cm4gaW50ZXJuYWxHZXRFbXB0eUZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICB9CiAgLyoqCiAgICogVXNlIHtAbGluayAjZ2V0RW1wdHlGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eT4gZ2V0RW1wdHlGaWVsZCgpIHsKICAgIHJldHVybiBnZXRFbXB0eUZpZWxkTWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSZndDsgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHk+IGdldEVtcHR5RmllbGRNYXAoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxHZXRFbXB0eUZpZWxkKCkuZ2V0TWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSZndDsgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgZ2V0RW1wdHlGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBkZWZhdWx0VmFsdWUpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PiBtYXAgPQogICAgICAgIGludGVybmFsR2V0RW1wdHlGaWVsZCgpLmdldE1hcCgpOwogICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRW1wdHkmZ3Q7IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGdldEVtcHR5RmllbGRPclRocm93KAogICAgICBpbnQga2V5KSB7CgogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eT4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldEVtcHR5RmllbGQoKS5nZXRNYXAoKTsKICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgIH0KICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVNLX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRmllbGRNYXNrRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19GaWVsZE1hc2tGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgfQogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrPiBmaWVsZE1hc2tGaWVsZF87CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaz4KICBpbnRlcm5hbEdldEZpZWxkTWFza0ZpZWxkKCkgewogICAgaWYgKGZpZWxkTWFza0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICBGaWVsZE1hc2tGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgfQogICAgcmV0dXJuIGZpZWxkTWFza0ZpZWxkXzsKICB9CiAgcHVibGljIGludCBnZXRGaWVsZE1hc2tGaWVsZENvdW50KCkgewogICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXNrRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2smZ3Q7IGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGaWVsZE1hc2tGaWVsZCgKICAgICAgaW50IGtleSkgewoKICAgIHJldHVybiBpbnRlcm5hbEdldEZpZWxkTWFza0ZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICB9CiAgLyoqCiAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXNrRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrPiBnZXRGaWVsZE1hc2tGaWVsZCgpIHsKICAgIHJldHVybiBnZXRGaWVsZE1hc2tGaWVsZE1hcCgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrJmd0OyBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaz4gZ2V0RmllbGRNYXNrRmllbGRNYXAoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hc2tGaWVsZCgpLmdldE1hcCgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrJmd0OyBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBnZXRGaWVsZE1hc2tGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZGVmYXVsdFZhbHVlKSB7CgogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2s+IG1hcCA9CiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hc2tGaWVsZCgpLmdldE1hcCgpOwogICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrJmd0OyBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBnZXRGaWVsZE1hc2tGaWVsZE9yVGhyb3coCiAgICAgIGludCBrZXkpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaz4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldEZpZWxkTWFza0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICB9CiAgICByZXR1cm4gbWFwLmdldChrZXkpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09VUkNFX0NPTlRFWFRfRklFTERfRklFTERfTlVNQkVSID0gNjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTb3VyY2VDb250ZXh0RmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0V2VsbEtub3duVHlwZXMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX1NvdXJjZUNvbnRleHRGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIH0KICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ+IHNvdXJjZUNvbnRleHRGaWVsZF87CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ+CiAgaW50ZXJuYWxHZXRTb3VyY2VDb250ZXh0RmllbGQoKSB7CiAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkXyA9PSBudWxsKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICBTb3VyY2VDb250ZXh0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgIH0KICAgIHJldHVybiBzb3VyY2VDb250ZXh0RmllbGRfOwogIH0KICBwdWJsaWMgaW50IGdldFNvdXJjZUNvbnRleHRGaWVsZENvdW50KCkgewogICAgcmV0dXJuIGludGVybmFsR2V0U291cmNlQ29udGV4dEZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCZndDsgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTb3VyY2VDb250ZXh0RmllbGQoCiAgICAgIGludCBrZXkpIHsKCiAgICByZXR1cm4gaW50ZXJuYWxHZXRTb3VyY2VDb250ZXh0RmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogIH0KICAvKioKICAgKiBVc2Uge0BsaW5rICNnZXRTb3VyY2VDb250ZXh0RmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dD4gZ2V0U291cmNlQ29udGV4dEZpZWxkKCkgewogICAgcmV0dXJuIGdldFNvdXJjZUNvbnRleHRGaWVsZE1hcCgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCZndDsgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dD4gZ2V0U291cmNlQ29udGV4dEZpZWxkTWFwKCkgewogICAgcmV0dXJuIGludGVybmFsR2V0U291cmNlQ29udGV4dEZpZWxkKCkuZ2V0TWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0Jmd0OyBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IGdldFNvdXJjZUNvbnRleHRGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IGRlZmF1bHRWYWx1ZSkgewoKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dD4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldFNvdXJjZUNvbnRleHRGaWVsZCgpLmdldE1hcCgpOwogICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCZndDsgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBnZXRTb3VyY2VDb250ZXh0RmllbGRPclRocm93KAogICAgICBpbnQga2V5KSB7CgogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0PiBtYXAgPQogICAgICAgIGludGVybmFsR2V0U291cmNlQ29udGV4dEZpZWxkKCkuZ2V0TWFwKCk7CiAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICB9CiAgICByZXR1cm4gbWFwLmdldChrZXkpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSVUNUX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDc7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU3RydWN0RmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19TdHJ1Y3RGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgfQogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0PiBzdHJ1Y3RGaWVsZF87CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdD4KICBpbnRlcm5hbEdldFN0cnVjdEZpZWxkKCkgewogICAgaWYgKHN0cnVjdEZpZWxkXyA9PSBudWxsKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICBTdHJ1Y3RGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgfQogICAgcmV0dXJuIHN0cnVjdEZpZWxkXzsKICB9CiAgcHVibGljIGludCBnZXRTdHJ1Y3RGaWVsZENvdW50KCkgewogICAgcmV0dXJuIGludGVybmFsR2V0U3RydWN0RmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QmZ3Q7IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1N0cnVjdEZpZWxkKAogICAgICBpbnQga2V5KSB7CgogICAgcmV0dXJuIGludGVybmFsR2V0U3RydWN0RmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogIH0KICAvKioKICAgKiBVc2Uge0BsaW5rICNnZXRTdHJ1Y3RGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Q+IGdldFN0cnVjdEZpZWxkKCkgewogICAgcmV0dXJuIGdldFN0cnVjdEZpZWxkTWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QmZ3Q7IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Q+IGdldFN0cnVjdEZpZWxkTWFwKCkgewogICAgcmV0dXJuIGludGVybmFsR2V0U3RydWN0RmllbGQoKS5nZXRNYXAoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCZndDsgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBnZXRTdHJ1Y3RGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QgZGVmYXVsdFZhbHVlKSB7CgogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Q+IG1hcCA9CiAgICAgICAgaW50ZXJuYWxHZXRTdHJ1Y3RGaWVsZCgpLmdldE1hcCgpOwogICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU3RydWN0Jmd0OyBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IGdldFN0cnVjdEZpZWxkT3JUaHJvdygKICAgICAgaW50IGtleSkgewoKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0PiBtYXAgPQogICAgICAgIGludGVybmFsR2V0U3RydWN0RmllbGQoKS5nZXRNYXAoKTsKICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgIH0KICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUSU1FU1RBTVBfRklFTERfRklFTERfTlVNQkVSID0gODsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBUaW1lc3RhbXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXA+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXA+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0V2VsbEtub3duVHlwZXMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX1RpbWVzdGFtcEZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICB9CiAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXA+IHRpbWVzdGFtcEZpZWxkXzsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wPgogIGludGVybmFsR2V0VGltZXN0YW1wRmllbGQoKSB7CiAgICBpZiAodGltZXN0YW1wRmllbGRfID09IG51bGwpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgIFRpbWVzdGFtcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICB9CiAgICByZXR1cm4gdGltZXN0YW1wRmllbGRfOwogIH0KICBwdWJsaWMgaW50IGdldFRpbWVzdGFtcEZpZWxkQ291bnQoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxHZXRUaW1lc3RhbXBGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCZndDsgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVGltZXN0YW1wRmllbGQoCiAgICAgIGludCBrZXkpIHsKCiAgICByZXR1cm4gaW50ZXJuYWxHZXRUaW1lc3RhbXBGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgfQogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldFRpbWVzdGFtcEZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcD4gZ2V0VGltZXN0YW1wRmllbGQoKSB7CiAgICByZXR1cm4gZ2V0VGltZXN0YW1wRmllbGRNYXAoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCZndDsgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcD4gZ2V0VGltZXN0YW1wRmllbGRNYXAoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxHZXRUaW1lc3RhbXBGaWVsZCgpLmdldE1hcCgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wJmd0OyB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIGdldFRpbWVzdGFtcEZpZWxkT3JEZWZhdWx0KAogICAgICBpbnQga2V5LAogICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBkZWZhdWx0VmFsdWUpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcD4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldFRpbWVzdGFtcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAmZ3Q7IHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgZ2V0VGltZXN0YW1wRmllbGRPclRocm93KAogICAgICBpbnQga2V5KSB7CgogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXA+IG1hcCA9CiAgICAgICAgaW50ZXJuYWxHZXRUaW1lc3RhbXBGaWVsZCgpLmdldE1hcCgpOwogICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgfQogICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfRklFTERfRklFTERfTlVNQkVSID0gOTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBUeXBlRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0V2VsbEtub3duVHlwZXMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX1R5cGVGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIH0KICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGU+IHR5cGVGaWVsZF87CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGU+CiAgaW50ZXJuYWxHZXRUeXBlRmllbGQoKSB7CiAgICBpZiAodHlwZUZpZWxkXyA9PSBudWxsKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICBUeXBlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgIH0KICAgIHJldHVybiB0eXBlRmllbGRfOwogIH0KICBwdWJsaWMgaW50IGdldFR5cGVGaWVsZENvdW50KCkgewogICAgcmV0dXJuIGludGVybmFsR2V0VHlwZUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVHlwZSZndDsgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1R5cGVGaWVsZCgKICAgICAgaW50IGtleSkgewoKICAgIHJldHVybiBpbnRlcm5hbEdldFR5cGVGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgfQogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldFR5cGVGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlPiBnZXRUeXBlRmllbGQoKSB7CiAgICByZXR1cm4gZ2V0VHlwZUZpZWxkTWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5UeXBlJmd0OyB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGU+IGdldFR5cGVGaWVsZE1hcCgpIHsKICAgIHJldHVybiBpbnRlcm5hbEdldFR5cGVGaWVsZCgpLmdldE1hcCgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVHlwZSZndDsgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlIGdldFR5cGVGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlIGRlZmF1bHRWYWx1ZSkgewoKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZT4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldFR5cGVGaWVsZCgpLmdldE1hcCgpOwogICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVHlwZSZndDsgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlIGdldFR5cGVGaWVsZE9yVGhyb3coCiAgICAgIGludCBrZXkpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGU+IG1hcCA9CiAgICAgICAgaW50ZXJuYWxHZXRUeXBlRmllbGQoKS5nZXRNYXAoKTsKICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgIH0KICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBET1VCTEVfRklFTERfRklFTERfTlVNQkVSID0gMTA7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRG91YmxlRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RXZWxsS25vd25UeXBlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRG91YmxlRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgfQogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+IGRvdWJsZUZpZWxkXzsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+CiAgaW50ZXJuYWxHZXREb3VibGVGaWVsZCgpIHsKICAgIGlmIChkb3VibGVGaWVsZF8gPT0gbnVsbCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgRG91YmxlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgIH0KICAgIHJldHVybiBkb3VibGVGaWVsZF87CiAgfQogIHB1YmxpYyBpbnQgZ2V0RG91YmxlRmllbGRDb3VudCgpIHsKICAgIHJldHVybiBpbnRlcm5hbEdldERvdWJsZUZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUmZ3Q7IGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gY29udGFpbnNEb3VibGVGaWVsZCgKICAgICAgaW50IGtleSkgewoKICAgIHJldHVybiBpbnRlcm5hbEdldERvdWJsZUZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICB9CiAgLyoqCiAgICogVXNlIHtAbGluayAjZ2V0RG91YmxlRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+IGdldERvdWJsZUZpZWxkKCkgewogICAgcmV0dXJuIGdldERvdWJsZUZpZWxkTWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSZndDsgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZT4gZ2V0RG91YmxlRmllbGRNYXAoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxHZXREb3VibGVGaWVsZCgpLmdldE1hcCgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUmZ3Q7IGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZ2V0RG91YmxlRmllbGRPckRlZmF1bHQoCiAgICAgIGludCBrZXksCiAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZGVmYXVsdFZhbHVlKSB7CgogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZT4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldERvdWJsZUZpZWxkKCkuZ2V0TWFwKCk7CiAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSZndDsgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBnZXREb3VibGVGaWVsZE9yVGhyb3coCiAgICAgIGludCBrZXkpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlPiBtYXAgPQogICAgICAgIGludGVybmFsR2V0RG91YmxlRmllbGQoKS5nZXRNYXAoKTsKICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgIH0KICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGTE9BVF9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxMTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGbG9hdEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19GbG9hdEZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgfQogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZT4gZmxvYXRGaWVsZF87CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWU+CiAgaW50ZXJuYWxHZXRGbG9hdEZpZWxkKCkgewogICAgaWYgKGZsb2F0RmllbGRfID09IG51bGwpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgIEZsb2F0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgIH0KICAgIHJldHVybiBmbG9hdEZpZWxkXzsKICB9CiAgcHVibGljIGludCBnZXRGbG9hdEZpZWxkQ291bnQoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxHZXRGbG9hdEZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSZndDsgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmxvYXRGaWVsZCgKICAgICAgaW50IGtleSkgewoKICAgIHJldHVybiBpbnRlcm5hbEdldEZsb2F0RmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogIH0KICAvKioKICAgKiBVc2Uge0BsaW5rICNnZXRGbG9hdEZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWU+IGdldEZsb2F0RmllbGQoKSB7CiAgICByZXR1cm4gZ2V0RmxvYXRGaWVsZE1hcCgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSZndDsgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWU+IGdldEZsb2F0RmllbGRNYXAoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxHZXRGbG9hdEZpZWxkKCkuZ2V0TWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlJmd0OyBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBnZXRGbG9hdEZpZWxkT3JEZWZhdWx0KAogICAgICBpbnQga2V5LAogICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZGVmYXVsdFZhbHVlKSB7CgogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlPiBtYXAgPQogICAgICAgIGludGVybmFsR2V0RmxvYXRGaWVsZCgpLmdldE1hcCgpOwogICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSZndDsgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZ2V0RmxvYXRGaWVsZE9yVGhyb3coCiAgICAgIGludCBrZXkpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWU+IG1hcCA9CiAgICAgICAgaW50ZXJuYWxHZXRGbG9hdEZpZWxkKCkuZ2V0TWFwKCk7CiAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICB9CiAgICByZXR1cm4gbWFwLmdldChrZXkpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UNjRfRklFTERfRklFTERfTlVNQkVSID0gMTI7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgSW50NjRGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RXZWxsS25vd25UeXBlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfSW50NjRGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIH0KICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWU+IGludDY0RmllbGRfOwogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPgogIGludGVybmFsR2V0SW50NjRGaWVsZCgpIHsKICAgIGlmIChpbnQ2NEZpZWxkXyA9PSBudWxsKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICBJbnQ2NEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICB9CiAgICByZXR1cm4gaW50NjRGaWVsZF87CiAgfQogIHB1YmxpYyBpbnQgZ2V0SW50NjRGaWVsZENvdW50KCkgewogICAgcmV0dXJuIGludGVybmFsR2V0SW50NjRGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUmZ3Q7IGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0ludDY0RmllbGQoCiAgICAgIGludCBrZXkpIHsKCiAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQ2NEZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICB9CiAgLyoqCiAgICogVXNlIHtAbGluayAjZ2V0SW50NjRGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPiBnZXRJbnQ2NEZpZWxkKCkgewogICAgcmV0dXJuIGdldEludDY0RmllbGRNYXAoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUmZ3Q7IGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPiBnZXRJbnQ2NEZpZWxkTWFwKCkgewogICAgcmV0dXJuIGludGVybmFsR2V0SW50NjRGaWVsZCgpLmdldE1hcCgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSZndDsgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgZ2V0SW50NjRGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGRlZmF1bHRWYWx1ZSkgewoKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZT4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldEludDY0RmllbGQoKS5nZXRNYXAoKTsKICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUmZ3Q7IGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGdldEludDY0RmllbGRPclRocm93KAogICAgICBpbnQga2V5KSB7CgogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPiBtYXAgPQogICAgICAgIGludGVybmFsR2V0SW50NjRGaWVsZCgpLmdldE1hcCgpOwogICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgfQogICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVJTlQ2NF9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxMzsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBVaW50NjRGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19VaW50NjRGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICB9CiAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZT4gdWludDY0RmllbGRfOwogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZT4KICBpbnRlcm5hbEdldFVpbnQ2NEZpZWxkKCkgewogICAgaWYgKHVpbnQ2NEZpZWxkXyA9PSBudWxsKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICBVaW50NjRGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgfQogICAgcmV0dXJuIHVpbnQ2NEZpZWxkXzsKICB9CiAgcHVibGljIGludCBnZXRVaW50NjRGaWVsZENvdW50KCkgewogICAgcmV0dXJuIGludGVybmFsR2V0VWludDY0RmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSZndDsgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1VpbnQ2NEZpZWxkKAogICAgICBpbnQga2V5KSB7CgogICAgcmV0dXJuIGludGVybmFsR2V0VWludDY0RmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogIH0KICAvKioKICAgKiBVc2Uge0BsaW5rICNnZXRVaW50NjRGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZT4gZ2V0VWludDY0RmllbGQoKSB7CiAgICByZXR1cm4gZ2V0VWludDY0RmllbGRNYXAoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlJmd0OyB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlPiBnZXRVaW50NjRGaWVsZE1hcCgpIHsKICAgIHJldHVybiBpbnRlcm5hbEdldFVpbnQ2NEZpZWxkKCkuZ2V0TWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSZndDsgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBnZXRVaW50NjRGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlPiBtYXAgPQogICAgICAgIGludGVybmFsR2V0VWludDY0RmllbGQoKS5nZXRNYXAoKTsKICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlJmd0OyB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIGdldFVpbnQ2NEZpZWxkT3JUaHJvdygKICAgICAgaW50IGtleSkgewoKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWU+IG1hcCA9CiAgICAgICAgaW50ZXJuYWxHZXRVaW50NjRGaWVsZCgpLmdldE1hcCgpOwogICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgfQogICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE0OwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0V2VsbEtub3duVHlwZXMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICB9CiAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlPiBpbnQzMkZpZWxkXzsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZT4KICBpbnRlcm5hbEdldEludDMyRmllbGQoKSB7CiAgICBpZiAoaW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgfQogICAgcmV0dXJuIGludDMyRmllbGRfOwogIH0KICBwdWJsaWMgaW50IGdldEludDMyRmllbGRDb3VudCgpIHsKICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlJmd0OyBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMkZpZWxkKAogICAgICBpbnQga2V5KSB7CgogICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgfQogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldEludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZT4gZ2V0SW50MzJGaWVsZCgpIHsKICAgIHJldHVybiBnZXRJbnQzMkZpZWxkTWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlJmd0OyBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZT4gZ2V0SW50MzJGaWVsZE1hcCgpIHsKICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyRmllbGQoKS5nZXRNYXAoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUmZ3Q7IGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGdldEludDMyRmllbGRPckRlZmF1bHQoCiAgICAgIGludCBrZXksCiAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWU+IG1hcCA9CiAgICAgICAgaW50ZXJuYWxHZXRJbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlJmd0OyBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBnZXRJbnQzMkZpZWxkT3JUaHJvdygKICAgICAgaW50IGtleSkgewoKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZT4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldEludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgIH0KICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVSU5UMzJfRklFTERfRklFTERfTlVNQkVSID0gMTU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVWludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RXZWxsS25vd25UeXBlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfVWludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgfQogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+IHVpbnQzMkZpZWxkXzsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+CiAgaW50ZXJuYWxHZXRVaW50MzJGaWVsZCgpIHsKICAgIGlmICh1aW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgVWludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgIH0KICAgIHJldHVybiB1aW50MzJGaWVsZF87CiAgfQogIHB1YmxpYyBpbnQgZ2V0VWludDMyRmllbGRDb3VudCgpIHsKICAgIHJldHVybiBpbnRlcm5hbEdldFVpbnQzMkZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUmZ3Q7IHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVaW50MzJGaWVsZCgKICAgICAgaW50IGtleSkgewoKICAgIHJldHVybiBpbnRlcm5hbEdldFVpbnQzMkZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICB9CiAgLyoqCiAgICogVXNlIHtAbGluayAjZ2V0VWludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+IGdldFVpbnQzMkZpZWxkKCkgewogICAgcmV0dXJuIGdldFVpbnQzMkZpZWxkTWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSZndDsgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZT4gZ2V0VWludDMyRmllbGRNYXAoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxHZXRVaW50MzJGaWVsZCgpLmdldE1hcCgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUmZ3Q7IHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgZ2V0VWludDMyRmllbGRPckRlZmF1bHQoCiAgICAgIGludCBrZXksCiAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgZGVmYXVsdFZhbHVlKSB7CgogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZT4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldFVpbnQzMkZpZWxkKCkuZ2V0TWFwKCk7CiAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSZndDsgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBnZXRVaW50MzJGaWVsZE9yVGhyb3coCiAgICAgIGludCBrZXkpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlPiBtYXAgPQogICAgICAgIGludGVybmFsR2V0VWludDMyRmllbGQoKS5nZXRNYXAoKTsKICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgIH0KICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCT09MX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE2OwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEJvb2xGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0V2VsbEtub3duVHlwZXMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0Jvb2xGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgfQogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlPiBib29sRmllbGRfOwogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWU+CiAgaW50ZXJuYWxHZXRCb29sRmllbGQoKSB7CiAgICBpZiAoYm9vbEZpZWxkXyA9PSBudWxsKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICBCb29sRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgIH0KICAgIHJldHVybiBib29sRmllbGRfOwogIH0KICBwdWJsaWMgaW50IGdldEJvb2xGaWVsZENvdW50KCkgewogICAgcmV0dXJuIGludGVybmFsR2V0Qm9vbEZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlJmd0OyBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0Jvb2xGaWVsZCgKICAgICAgaW50IGtleSkgewoKICAgIHJldHVybiBpbnRlcm5hbEdldEJvb2xGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgfQogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldEJvb2xGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWU+IGdldEJvb2xGaWVsZCgpIHsKICAgIHJldHVybiBnZXRCb29sRmllbGRNYXAoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSZndDsgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlPiBnZXRCb29sRmllbGRNYXAoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxHZXRCb29sRmllbGQoKS5nZXRNYXAoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSZndDsgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGdldEJvb2xGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgZGVmYXVsdFZhbHVlKSB7CgogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWU+IG1hcCA9CiAgICAgICAgaW50ZXJuYWxHZXRCb29sRmllbGQoKS5nZXRNYXAoKTsKICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSZndDsgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGdldEJvb2xGaWVsZE9yVGhyb3coCiAgICAgIGludCBrZXkpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZT4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldEJvb2xGaWVsZCgpLmdldE1hcCgpOwogICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgfQogICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklOR19GSUVMRF9GSUVMRF9OVU1CRVIgPSAxNzsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBTdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19TdHJpbmdGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICB9CiAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZT4gc3RyaW5nRmllbGRfOwogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZT4KICBpbnRlcm5hbEdldFN0cmluZ0ZpZWxkKCkgewogICAgaWYgKHN0cmluZ0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICBTdHJpbmdGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgfQogICAgcmV0dXJuIHN0cmluZ0ZpZWxkXzsKICB9CiAgcHVibGljIGludCBnZXRTdHJpbmdGaWVsZENvdW50KCkgewogICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSZndDsgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1N0cmluZ0ZpZWxkKAogICAgICBpbnQga2V5KSB7CgogICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogIH0KICAvKioKICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZT4gZ2V0U3RyaW5nRmllbGQoKSB7CiAgICByZXR1cm4gZ2V0U3RyaW5nRmllbGRNYXAoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlJmd0OyBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlPiBnZXRTdHJpbmdGaWVsZE1hcCgpIHsKICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ0ZpZWxkKCkuZ2V0TWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSZndDsgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBnZXRTdHJpbmdGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlPiBtYXAgPQogICAgICAgIGludGVybmFsR2V0U3RyaW5nRmllbGQoKS5nZXRNYXAoKTsKICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlJmd0OyBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGdldFN0cmluZ0ZpZWxkT3JUaHJvdygKICAgICAgaW50IGtleSkgewoKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWU+IG1hcCA9CiAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdGaWVsZCgpLmdldE1hcCgpOwogICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgfQogICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJZVEVTX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE4OwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEJ5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0V2VsbEtub3duVHlwZXMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICB9CiAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlPiBieXRlc0ZpZWxkXzsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZT4KICBpbnRlcm5hbEdldEJ5dGVzRmllbGQoKSB7CiAgICBpZiAoYnl0ZXNGaWVsZF8gPT0gbnVsbCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgQnl0ZXNGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgfQogICAgcmV0dXJuIGJ5dGVzRmllbGRfOwogIH0KICBwdWJsaWMgaW50IGdldEJ5dGVzRmllbGRDb3VudCgpIHsKICAgIHJldHVybiBpbnRlcm5hbEdldEJ5dGVzRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlJmd0OyBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gY29udGFpbnNCeXRlc0ZpZWxkKAogICAgICBpbnQga2V5KSB7CgogICAgcmV0dXJuIGludGVybmFsR2V0Qnl0ZXNGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgfQogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldEJ5dGVzRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZT4gZ2V0Qnl0ZXNGaWVsZCgpIHsKICAgIHJldHVybiBnZXRCeXRlc0ZpZWxkTWFwKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlJmd0OyBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZT4gZ2V0Qnl0ZXNGaWVsZE1hcCgpIHsKICAgIHJldHVybiBpbnRlcm5hbEdldEJ5dGVzRmllbGQoKS5nZXRNYXAoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUmZ3Q7IGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGdldEJ5dGVzRmllbGRPckRlZmF1bHQoCiAgICAgIGludCBrZXksCiAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWU+IG1hcCA9CiAgICAgICAgaW50ZXJuYWxHZXRCeXRlc0ZpZWxkKCkuZ2V0TWFwKCk7CiAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgfQogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlJmd0OyBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBnZXRCeXRlc0ZpZWxkT3JUaHJvdygKICAgICAgaW50IGtleSkgewoKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZT4gbWFwID0KICAgICAgICBpbnRlcm5hbEdldEJ5dGVzRmllbGQoKS5nZXRNYXAoKTsKICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgIH0KICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgfQoKICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgb3V0cHV0LAogICAgICAgIGludGVybmFsR2V0QW55RmllbGQoKSwKICAgICAgICBBbnlGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgMSk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgIG91dHB1dCwKICAgICAgICBpbnRlcm5hbEdldEFwaUZpZWxkKCksCiAgICAgICAgQXBpRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgIDIpOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICBvdXRwdXQsCiAgICAgICAgaW50ZXJuYWxHZXREdXJhdGlvbkZpZWxkKCksCiAgICAgICAgRHVyYXRpb25GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgMyk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgIG91dHB1dCwKICAgICAgICBpbnRlcm5hbEdldEVtcHR5RmllbGQoKSwKICAgICAgICBFbXB0eUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICA0KTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgb3V0cHV0LAogICAgICAgIGludGVybmFsR2V0RmllbGRNYXNrRmllbGQoKSwKICAgICAgICBGaWVsZE1hc2tGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgNSk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgIG91dHB1dCwKICAgICAgICBpbnRlcm5hbEdldFNvdXJjZUNvbnRleHRGaWVsZCgpLAogICAgICAgIFNvdXJjZUNvbnRleHRGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgNik7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgIG91dHB1dCwKICAgICAgICBpbnRlcm5hbEdldFN0cnVjdEZpZWxkKCksCiAgICAgICAgU3RydWN0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgIDcpOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICBvdXRwdXQsCiAgICAgICAgaW50ZXJuYWxHZXRUaW1lc3RhbXBGaWVsZCgpLAogICAgICAgIFRpbWVzdGFtcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICA4KTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgb3V0cHV0LAogICAgICAgIGludGVybmFsR2V0VHlwZUZpZWxkKCksCiAgICAgICAgVHlwZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICA5KTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgb3V0cHV0LAogICAgICAgIGludGVybmFsR2V0RG91YmxlRmllbGQoKSwKICAgICAgICBEb3VibGVGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgMTApOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICBvdXRwdXQsCiAgICAgICAgaW50ZXJuYWxHZXRGbG9hdEZpZWxkKCksCiAgICAgICAgRmxvYXRGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgMTEpOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICBvdXRwdXQsCiAgICAgICAgaW50ZXJuYWxHZXRJbnQ2NEZpZWxkKCksCiAgICAgICAgSW50NjRGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgMTIpOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICBvdXRwdXQsCiAgICAgICAgaW50ZXJuYWxHZXRVaW50NjRGaWVsZCgpLAogICAgICAgIFVpbnQ2NEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAxMyk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgIG91dHB1dCwKICAgICAgICBpbnRlcm5hbEdldEludDMyRmllbGQoKSwKICAgICAgICBJbnQzMkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAxNCk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgIG91dHB1dCwKICAgICAgICBpbnRlcm5hbEdldFVpbnQzMkZpZWxkKCksCiAgICAgICAgVWludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgIDE1KTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgb3V0cHV0LAogICAgICAgIGludGVybmFsR2V0Qm9vbEZpZWxkKCksCiAgICAgICAgQm9vbEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAxNik7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgIG91dHB1dCwKICAgICAgICBpbnRlcm5hbEdldFN0cmluZ0ZpZWxkKCksCiAgICAgICAgU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgIDE3KTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgb3V0cHV0LAogICAgICAgIGludGVybmFsR2V0Qnl0ZXNGaWVsZCgpLAogICAgICAgIEJ5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgIDE4KTsKICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgIHNpemUgPSAwOwogICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueT4gZW50cnkKICAgICAgICAgOiBpbnRlcm5hbEdldEFueUZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueT4KICAgICAgYW55RmllbGRfXyA9IEFueUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAuYnVpbGQoKTsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGFueUZpZWxkX18pOwogICAgfQogICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaT4gZW50cnkKICAgICAgICAgOiBpbnRlcm5hbEdldEFwaUZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaT4KICAgICAgYXBpRmllbGRfXyA9IEFwaUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAuYnVpbGQoKTsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIsIGFwaUZpZWxkX18pOwogICAgfQogICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uPiBlbnRyeQogICAgICAgICA6IGludGVybmFsR2V0RHVyYXRpb25GaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbj4KICAgICAgZHVyYXRpb25GaWVsZF9fID0gRHVyYXRpb25GaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgLmJ1aWxkKCk7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzLCBkdXJhdGlvbkZpZWxkX18pOwogICAgfQogICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PiBlbnRyeQogICAgICAgICA6IGludGVybmFsR2V0RW1wdHlGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eT4KICAgICAgZW1wdHlGaWVsZF9fID0gRW1wdHlGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgLmJ1aWxkKCk7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBlbXB0eUZpZWxkX18pOwogICAgfQogICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaz4gZW50cnkKICAgICAgICAgOiBpbnRlcm5hbEdldEZpZWxkTWFza0ZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaz4KICAgICAgZmllbGRNYXNrRmllbGRfXyA9IEZpZWxkTWFza0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAuYnVpbGQoKTsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGZpZWxkTWFza0ZpZWxkX18pOwogICAgfQogICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ+IGVudHJ5CiAgICAgICAgIDogaW50ZXJuYWxHZXRTb3VyY2VDb250ZXh0RmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dD4KICAgICAgc291cmNlQ29udGV4dEZpZWxkX18gPSBTb3VyY2VDb250ZXh0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgIC5idWlsZCgpOwogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNiwgc291cmNlQ29udGV4dEZpZWxkX18pOwogICAgfQogICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdD4gZW50cnkKICAgICAgICAgOiBpbnRlcm5hbEdldFN0cnVjdEZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdD4KICAgICAgc3RydWN0RmllbGRfXyA9IFN0cnVjdEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAuYnVpbGQoKTsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcsIHN0cnVjdEZpZWxkX18pOwogICAgfQogICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcD4gZW50cnkKICAgICAgICAgOiBpbnRlcm5hbEdldFRpbWVzdGFtcEZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcD4KICAgICAgdGltZXN0YW1wRmllbGRfXyA9IFRpbWVzdGFtcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAuYnVpbGQoKTsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDgsIHRpbWVzdGFtcEZpZWxkX18pOwogICAgfQogICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGU+IGVudHJ5CiAgICAgICAgIDogaW50ZXJuYWxHZXRUeXBlRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZT4KICAgICAgdHlwZUZpZWxkX18gPSBUeXBlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgIC5idWlsZCgpOwogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOSwgdHlwZUZpZWxkX18pOwogICAgfQogICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlPiBlbnRyeQogICAgICAgICA6IGludGVybmFsR2V0RG91YmxlRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+CiAgICAgIGRvdWJsZUZpZWxkX18gPSBEb3VibGVGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgLmJ1aWxkKCk7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgZG91YmxlRmllbGRfXyk7CiAgICB9CiAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZT4gZW50cnkKICAgICAgICAgOiBpbnRlcm5hbEdldEZsb2F0RmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZT4KICAgICAgZmxvYXRGaWVsZF9fID0gRmxvYXRGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgLmJ1aWxkKCk7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMSwgZmxvYXRGaWVsZF9fKTsKICAgIH0KICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPiBlbnRyeQogICAgICAgICA6IGludGVybmFsR2V0SW50NjRGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPgogICAgICBpbnQ2NEZpZWxkX18gPSBJbnQ2NEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAuYnVpbGQoKTsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyLCBpbnQ2NEZpZWxkX18pOwogICAgfQogICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlPiBlbnRyeQogICAgICAgICA6IGludGVybmFsR2V0VWludDY0RmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWU+CiAgICAgIHVpbnQ2NEZpZWxkX18gPSBVaW50NjRGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgLmJ1aWxkKCk7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMywgdWludDY0RmllbGRfXyk7CiAgICB9CiAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZT4gZW50cnkKICAgICAgICAgOiBpbnRlcm5hbEdldEludDMyRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZT4KICAgICAgaW50MzJGaWVsZF9fID0gSW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgLmJ1aWxkKCk7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNCwgaW50MzJGaWVsZF9fKTsKICAgIH0KICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZT4gZW50cnkKICAgICAgICAgOiBpbnRlcm5hbEdldFVpbnQzMkZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlPgogICAgICB1aW50MzJGaWVsZF9fID0gVWludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgIC5idWlsZCgpOwogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTUsIHVpbnQzMkZpZWxkX18pOwogICAgfQogICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZT4gZW50cnkKICAgICAgICAgOiBpbnRlcm5hbEdldEJvb2xGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWU+CiAgICAgIGJvb2xGaWVsZF9fID0gQm9vbEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAuYnVpbGQoKTsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE2LCBib29sRmllbGRfXyk7CiAgICB9CiAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWU+IGVudHJ5CiAgICAgICAgIDogaW50ZXJuYWxHZXRTdHJpbmdGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZT4KICAgICAgc3RyaW5nRmllbGRfXyA9IFN0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAuYnVpbGQoKTsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3LCBzdHJpbmdGaWVsZF9fKTsKICAgIH0KICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlPiBlbnRyeQogICAgICAgICA6IGludGVybmFsR2V0Qnl0ZXNGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlPgogICAgICBieXRlc0ZpZWxkX18gPSBCeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAuYnVpbGQoKTsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE4LCBieXRlc0ZpZWxkX18pOwogICAgfQogICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICByZXR1cm4gc2l6ZTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgIGlmIChvYmogPT0gdGhpcykgewogICAgIHJldHVybiB0cnVlOwogICAgfQogICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzKSkgewogICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICB9CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuTWFwV2VsbEtub3duVHlwZXMgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzKSBvYmo7CgogICAgaWYgKCFpbnRlcm5hbEdldEFueUZpZWxkKCkuZXF1YWxzKAogICAgICAgIG90aGVyLmludGVybmFsR2V0QW55RmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIGlmICghaW50ZXJuYWxHZXRBcGlGaWVsZCgpLmVxdWFscygKICAgICAgICBvdGhlci5pbnRlcm5hbEdldEFwaUZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoIWludGVybmFsR2V0RHVyYXRpb25GaWVsZCgpLmVxdWFscygKICAgICAgICBvdGhlci5pbnRlcm5hbEdldER1cmF0aW9uRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIGlmICghaW50ZXJuYWxHZXRFbXB0eUZpZWxkKCkuZXF1YWxzKAogICAgICAgIG90aGVyLmludGVybmFsR2V0RW1wdHlGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFza0ZpZWxkKCkuZXF1YWxzKAogICAgICAgIG90aGVyLmludGVybmFsR2V0RmllbGRNYXNrRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIGlmICghaW50ZXJuYWxHZXRTb3VyY2VDb250ZXh0RmllbGQoKS5lcXVhbHMoCiAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRTb3VyY2VDb250ZXh0RmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIGlmICghaW50ZXJuYWxHZXRTdHJ1Y3RGaWVsZCgpLmVxdWFscygKICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cnVjdEZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoIWludGVybmFsR2V0VGltZXN0YW1wRmllbGQoKS5lcXVhbHMoCiAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRUaW1lc3RhbXBGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFpbnRlcm5hbEdldFR5cGVGaWVsZCgpLmVxdWFscygKICAgICAgICBvdGhlci5pbnRlcm5hbEdldFR5cGVGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFpbnRlcm5hbEdldERvdWJsZUZpZWxkKCkuZXF1YWxzKAogICAgICAgIG90aGVyLmludGVybmFsR2V0RG91YmxlRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIGlmICghaW50ZXJuYWxHZXRGbG9hdEZpZWxkKCkuZXF1YWxzKAogICAgICAgIG90aGVyLmludGVybmFsR2V0RmxvYXRGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFpbnRlcm5hbEdldEludDY0RmllbGQoKS5lcXVhbHMoCiAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQ2NEZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoIWludGVybmFsR2V0VWludDY0RmllbGQoKS5lcXVhbHMoCiAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVaW50NjRGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFpbnRlcm5hbEdldEludDMyRmllbGQoKS5lcXVhbHMoCiAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoIWludGVybmFsR2V0VWludDMyRmllbGQoKS5lcXVhbHMoCiAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVaW50MzJGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFpbnRlcm5hbEdldEJvb2xGaWVsZCgpLmVxdWFscygKICAgICAgICBvdGhlci5pbnRlcm5hbEdldEJvb2xGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFpbnRlcm5hbEdldFN0cmluZ0ZpZWxkKCkuZXF1YWxzKAogICAgICAgIG90aGVyLmludGVybmFsR2V0U3RyaW5nRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIGlmICghaW50ZXJuYWxHZXRCeXRlc0ZpZWxkKCkuZXF1YWxzKAogICAgICAgIG90aGVyLmludGVybmFsR2V0Qnl0ZXNGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgfQogICAgaW50IGhhc2ggPSA0MTsKICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgaWYgKCFpbnRlcm5hbEdldEFueUZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFOWV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0QW55RmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKCFpbnRlcm5hbEdldEFwaUZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFQSV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0QXBpRmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKCFpbnRlcm5hbEdldER1cmF0aW9uRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVSQVRJT05fRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldER1cmF0aW9uRmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKCFpbnRlcm5hbEdldEVtcHR5RmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRU1QVFlfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEVtcHR5RmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKCFpbnRlcm5hbEdldEZpZWxkTWFza0ZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BU0tfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEZpZWxkTWFza0ZpZWxkKCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGlmICghaW50ZXJuYWxHZXRTb3VyY2VDb250ZXh0RmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU09VUkNFX0NPTlRFWFRfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFNvdXJjZUNvbnRleHRGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoIWludGVybmFsR2V0U3RydWN0RmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSVUNUX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRTdHJ1Y3RGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoIWludGVybmFsR2V0VGltZXN0YW1wRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVElNRVNUQU1QX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRUaW1lc3RhbXBGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoIWludGVybmFsR2V0VHlwZUZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFRZUEVfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFR5cGVGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoIWludGVybmFsR2V0RG91YmxlRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRE9VQkxFX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXREb3VibGVGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoIWludGVybmFsR2V0RmxvYXRGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGTE9BVF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RmxvYXRGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoIWludGVybmFsR2V0SW50NjRGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQ2NF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50NjRGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoIWludGVybmFsR2V0VWludDY0RmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVUlOVDY0X0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRVaW50NjRGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoIWludGVybmFsR2V0SW50MzJGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0SW50MzJGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoIWludGVybmFsR2V0VWludDMyRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVUlOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRVaW50MzJGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoIWludGVybmFsR2V0Qm9vbEZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEJPT0xfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEJvb2xGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoIWludGVybmFsR2V0U3RyaW5nRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSSU5HX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRTdHJpbmdGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoIWludGVybmFsR2V0Qnl0ZXNGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCWVRFU19GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0Qnl0ZXNGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgcmV0dXJuIGhhc2g7CiAgfQoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5NYXBXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5NYXBXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuTWFwV2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5NYXBXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGJ5dGVbXSBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuTWFwV2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuTWFwV2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKAogICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5NYXBXZWxsS25vd25UeXBlcyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5NYXBXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5NYXBXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogIH0KICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuTWFwV2VsbEtub3duVHlwZXMgcHJvdG90eXBlKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICB9CiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICByZXR1cm4gYnVpbGRlcjsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBBIG1hcCBmaWVsZCBmb3IgZWFjaCB3ZWxsLWtub3duIHR5cGUuIFdlIG9ubHkKICAgKiBuZWVkIHRvIHdvcnJ5IGFib3V0IHRoZSB2YWx1ZSBwYXJ0IG9mIHRoZSBtYXAgYmVpbmcgdGhlCiAgICogd2VsbC1rbm93biB0eXBlcywgYXMgbWVzc2FnZXMgY2FuJ3QgYmUgbWFwIGtleXMuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NYXBXZWxsS25vd25UeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5NYXBXZWxsS25vd25UeXBlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzT3JCdWlsZGVyIHsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBbnlGaWVsZCgpOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFwaUZpZWxkKCk7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RHVyYXRpb25GaWVsZCgpOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVtcHR5RmllbGQoKTsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hc2tGaWVsZCgpOwogICAgICAgIGNhc2UgNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFNvdXJjZUNvbnRleHRGaWVsZCgpOwogICAgICAgIGNhc2UgNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cnVjdEZpZWxkKCk7CiAgICAgICAgY2FzZSA4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VGltZXN0YW1wRmllbGQoKTsKICAgICAgICBjYXNlIDk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRUeXBlRmllbGQoKTsKICAgICAgICBjYXNlIDEwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RG91YmxlRmllbGQoKTsKICAgICAgICBjYXNlIDExOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RmxvYXRGaWVsZCgpOwogICAgICAgIGNhc2UgMTI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQ2NEZpZWxkKCk7CiAgICAgICAgY2FzZSAxMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVpbnQ2NEZpZWxkKCk7CiAgICAgICAgY2FzZSAxNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyRmllbGQoKTsKICAgICAgICBjYXNlIDE1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VWludDMyRmllbGQoKTsKICAgICAgICBjYXNlIDE2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0Qm9vbEZpZWxkKCk7CiAgICAgICAgY2FzZSAxNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ0ZpZWxkKCk7CiAgICAgICAgY2FzZSAxODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEJ5dGVzRmllbGQoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUFueUZpZWxkKCk7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUFwaUZpZWxkKCk7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUR1cmF0aW9uRmllbGQoKTsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRW1wdHlGaWVsZCgpOwogICAgICAgIGNhc2UgNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hc2tGaWVsZCgpOwogICAgICAgIGNhc2UgNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTb3VyY2VDb250ZXh0RmllbGQoKTsKICAgICAgICBjYXNlIDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlU3RydWN0RmllbGQoKTsKICAgICAgICBjYXNlIDg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVGltZXN0YW1wRmllbGQoKTsKICAgICAgICBjYXNlIDk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVHlwZUZpZWxkKCk7CiAgICAgICAgY2FzZSAxMDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVEb3VibGVGaWVsZCgpOwogICAgICAgIGNhc2UgMTE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmxvYXRGaWVsZCgpOwogICAgICAgIGNhc2UgMTI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50NjRGaWVsZCgpOwogICAgICAgIGNhc2UgMTM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVWludDY0RmllbGQoKTsKICAgICAgICBjYXNlIDE0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDMyRmllbGQoKTsKICAgICAgICBjYXNlIDE1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVVpbnQzMkZpZWxkKCk7CiAgICAgICAgY2FzZSAxNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVCb29sRmllbGQoKTsKICAgICAgICBjYXNlIDE3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ0ZpZWxkKCk7CiAgICAgICAgY2FzZSAxODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVCeXRlc0ZpZWxkKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RXZWxsS25vd25UeXBlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuTWFwV2VsbEtub3duVHlwZXMuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5NYXBXZWxsS25vd25UeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzLm5ld0J1aWxkZXIoKQogICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgIH0KCiAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgc3VwZXIocGFyZW50KTsKCiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUFueUZpZWxkKCkuY2xlYXIoKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQXBpRmllbGQoKS5jbGVhcigpOwogICAgICBpbnRlcm5hbEdldE11dGFibGVEdXJhdGlvbkZpZWxkKCkuY2xlYXIoKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW1wdHlGaWVsZCgpLmNsZWFyKCk7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFza0ZpZWxkKCkuY2xlYXIoKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU291cmNlQ29udGV4dEZpZWxkKCkuY2xlYXIoKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RydWN0RmllbGQoKS5jbGVhcigpOwogICAgICBpbnRlcm5hbEdldE11dGFibGVUaW1lc3RhbXBGaWVsZCgpLmNsZWFyKCk7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZVR5cGVGaWVsZCgpLmNsZWFyKCk7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZURvdWJsZUZpZWxkKCkuY2xlYXIoKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmxvYXRGaWVsZCgpLmNsZWFyKCk7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDY0RmllbGQoKS5jbGVhcigpOwogICAgICBpbnRlcm5hbEdldE11dGFibGVVaW50NjRGaWVsZCgpLmNsZWFyKCk7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyRmllbGQoKS5jbGVhcigpOwogICAgICBpbnRlcm5hbEdldE11dGFibGVVaW50MzJGaWVsZCgpLmNsZWFyKCk7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUJvb2xGaWVsZCgpLmNsZWFyKCk7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ0ZpZWxkKCkuY2xlYXIoKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQnl0ZXNGaWVsZCgpLmNsZWFyKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuTWFwV2VsbEtub3duVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5NYXBXZWxsS25vd25UeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzIGJ1aWxkKCkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuTWFwV2VsbEtub3duVHlwZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuTWFwV2VsbEtub3duVHlwZXModGhpcyk7CiAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgIG9uQnVpbHQoKTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuTWFwV2VsbEtub3duVHlwZXMgcmVzdWx0KSB7CiAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5hbnlGaWVsZF8gPSBpbnRlcm5hbEdldEFueUZpZWxkKCkuYnVpbGQoQW55RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5hcGlGaWVsZF8gPSBpbnRlcm5hbEdldEFwaUZpZWxkKCkuYnVpbGQoQXBpRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5kdXJhdGlvbkZpZWxkXyA9IGludGVybmFsR2V0RHVyYXRpb25GaWVsZCgpLmJ1aWxkKER1cmF0aW9uRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5lbXB0eUZpZWxkXyA9IGludGVybmFsR2V0RW1wdHlGaWVsZCgpLmJ1aWxkKEVtcHR5RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5maWVsZE1hc2tGaWVsZF8gPSBpbnRlcm5hbEdldEZpZWxkTWFza0ZpZWxkKCkuYnVpbGQoRmllbGRNYXNrRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5zb3VyY2VDb250ZXh0RmllbGRfID0gaW50ZXJuYWxHZXRTb3VyY2VDb250ZXh0RmllbGQoKS5idWlsZChTb3VyY2VDb250ZXh0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5zdHJ1Y3RGaWVsZF8gPSBpbnRlcm5hbEdldFN0cnVjdEZpZWxkKCkuYnVpbGQoU3RydWN0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC50aW1lc3RhbXBGaWVsZF8gPSBpbnRlcm5hbEdldFRpbWVzdGFtcEZpZWxkKCkuYnVpbGQoVGltZXN0YW1wRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC50eXBlRmllbGRfID0gaW50ZXJuYWxHZXRUeXBlRmllbGQoKS5idWlsZChUeXBlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5kb3VibGVGaWVsZF8gPSBpbnRlcm5hbEdldERvdWJsZUZpZWxkKCkuYnVpbGQoRG91YmxlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5mbG9hdEZpZWxkXyA9IGludGVybmFsR2V0RmxvYXRGaWVsZCgpLmJ1aWxkKEZsb2F0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5pbnQ2NEZpZWxkXyA9IGludGVybmFsR2V0SW50NjRGaWVsZCgpLmJ1aWxkKEludDY0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC51aW50NjRGaWVsZF8gPSBpbnRlcm5hbEdldFVpbnQ2NEZpZWxkKCkuYnVpbGQoVWludDY0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5pbnQzMkZpZWxkXyA9IGludGVybmFsR2V0SW50MzJGaWVsZCgpLmJ1aWxkKEludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC51aW50MzJGaWVsZF8gPSBpbnRlcm5hbEdldFVpbnQzMkZpZWxkKCkuYnVpbGQoVWludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5ib29sRmllbGRfID0gaW50ZXJuYWxHZXRCb29sRmllbGQoKS5idWlsZChCb29sRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5zdHJpbmdGaWVsZF8gPSBpbnRlcm5hbEdldFN0cmluZ0ZpZWxkKCkuYnVpbGQoU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5ieXRlc0ZpZWxkXyA9IGludGVybmFsR2V0Qnl0ZXNGaWVsZCgpLmJ1aWxkKEJ5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzKSB7CiAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzKW90aGVyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICB9CgogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5NYXBXZWxsS25vd25UeXBlcyBvdGhlcikgewogICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQW55RmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEFueUZpZWxkKCkpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUFwaUZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRBcGlGaWVsZCgpKTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICBpbnRlcm5hbEdldE11dGFibGVEdXJhdGlvbkZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXREdXJhdGlvbkZpZWxkKCkpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUVtcHR5RmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEVtcHR5RmllbGQoKSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXNrRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZpZWxkTWFza0ZpZWxkKCkpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZVNvdXJjZUNvbnRleHRGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0U291cmNlQ29udGV4dEZpZWxkKCkpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cnVjdEZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRTdHJ1Y3RGaWVsZCgpKTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICBpbnRlcm5hbEdldE11dGFibGVUaW1lc3RhbXBGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VGltZXN0YW1wRmllbGQoKSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVHlwZUZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRUeXBlRmllbGQoKSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRG91YmxlRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldERvdWJsZUZpZWxkKCkpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUZsb2F0RmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEZsb2F0RmllbGQoKSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50NjRGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50NjRGaWVsZCgpKTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICBpbnRlcm5hbEdldE11dGFibGVVaW50NjRGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VWludDY0RmllbGQoKSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0SW50MzJGaWVsZCgpKTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICBpbnRlcm5hbEdldE11dGFibGVVaW50MzJGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VWludDMyRmllbGQoKSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQm9vbEZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRCb29sRmllbGQoKSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZ0ZpZWxkKCkpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUJ5dGVzRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEJ5dGVzRmllbGQoKSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgfQogICAgICB0cnkgewogICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55PgogICAgICAgICAgICAgIGFueUZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgQW55RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUFueUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgYW55RmllbGRfXy5nZXRLZXkoKSwgYW55RmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGk+CiAgICAgICAgICAgICAgYXBpRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBBcGlGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQXBpRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICBhcGlGaWVsZF9fLmdldEtleSgpLCBhcGlGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uPgogICAgICAgICAgICAgIGR1cmF0aW9uRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBEdXJhdGlvbkZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVEdXJhdGlvbkZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgZHVyYXRpb25GaWVsZF9fLmdldEtleSgpLCBkdXJhdGlvbkZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHk+CiAgICAgICAgICAgICAgZW1wdHlGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIEVtcHR5RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVtcHR5RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICBlbXB0eUZpZWxkX18uZ2V0S2V5KCksIGVtcHR5RmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICBjYXNlIDQyOiB7CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2s+CiAgICAgICAgICAgICAgZmllbGRNYXNrRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBGaWVsZE1hc2tGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXNrRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICBmaWVsZE1hc2tGaWVsZF9fLmdldEtleSgpLCBmaWVsZE1hc2tGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ+CiAgICAgICAgICAgICAgc291cmNlQ29udGV4dEZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgU291cmNlQ29udGV4dEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTb3VyY2VDb250ZXh0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRfXy5nZXRLZXkoKSwgc291cmNlQ29udGV4dEZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgY2FzZSA1ODogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0PgogICAgICAgICAgICAgIHN0cnVjdEZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgU3RydWN0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cnVjdEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgc3RydWN0RmllbGRfXy5nZXRLZXkoKSwgc3RydWN0RmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSA1OAogICAgICAgICAgICBjYXNlIDY2OiB7CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXA+CiAgICAgICAgICAgICAgdGltZXN0YW1wRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBUaW1lc3RhbXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVGltZXN0YW1wRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICB0aW1lc3RhbXBGaWVsZF9fLmdldEtleSgpLCB0aW1lc3RhbXBGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDY2CiAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGU+CiAgICAgICAgICAgICAgdHlwZUZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgVHlwZUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVUeXBlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICB0eXBlRmllbGRfXy5nZXRLZXkoKSwgdHlwZUZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+CiAgICAgICAgICAgICAgZG91YmxlRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBEb3VibGVGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRG91YmxlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICBkb3VibGVGaWVsZF9fLmdldEtleSgpLCBkb3VibGVGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDgyCiAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWU+CiAgICAgICAgICAgICAgZmxvYXRGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIEZsb2F0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZsb2F0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICBmbG9hdEZpZWxkX18uZ2V0S2V5KCksIGZsb2F0RmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICBjYXNlIDk4OiB7CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPgogICAgICAgICAgICAgIGludDY0RmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBJbnQ2NEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQ2NEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgaW50NjRGaWVsZF9fLmdldEtleSgpLCBpbnQ2NEZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgOTgKICAgICAgICAgICAgY2FzZSAxMDY6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlPgogICAgICAgICAgICAgIHVpbnQ2NEZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgVWludDY0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVpbnQ2NEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgdWludDY0RmllbGRfXy5nZXRLZXkoKSwgdWludDY0RmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMDYKICAgICAgICAgICAgY2FzZSAxMTQ6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWU+CiAgICAgICAgICAgICAgaW50MzJGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIEludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICBpbnQzMkZpZWxkX18uZ2V0S2V5KCksIGludDMyRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMTQKICAgICAgICAgICAgY2FzZSAxMjI6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlPgogICAgICAgICAgICAgIHVpbnQzMkZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgVWludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVpbnQzMkZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgdWludDMyRmllbGRfXy5nZXRLZXkoKSwgdWludDMyRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMjIKICAgICAgICAgICAgY2FzZSAxMzA6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZT4KICAgICAgICAgICAgICBib29sRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBCb29sRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUJvb2xGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgIGJvb2xGaWVsZF9fLmdldEtleSgpLCBib29sRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMzAKICAgICAgICAgICAgY2FzZSAxMzg6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlPgogICAgICAgICAgICAgIHN0cmluZ0ZpZWxkX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgU3RyaW5nRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgc3RyaW5nRmllbGRfXy5nZXRLZXkoKSwgc3RyaW5nRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMzgKICAgICAgICAgICAgY2FzZSAxNDY6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWU+CiAgICAgICAgICAgICAgYnl0ZXNGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIEJ5dGVzRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUJ5dGVzRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICBieXRlc0ZpZWxkX18uZ2V0S2V5KCksIGJ5dGVzRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxNDYKICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSAvLyBmaW5hbGx5CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBBbnlGaWVsZENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55PiB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYuQW55T3JCdWlsZGVyIHZhbCkgewogICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQW55KSB2YWw7IH0KICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55PiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgcmV0dXJuIEFueUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgfQogICAgfTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFueUZpZWxkQ29udmVydGVyIGFueUZpZWxkQ29udmVydGVyID0gbmV3IEFueUZpZWxkQ29udmVydGVyKCk7CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyPiBhbnlGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnksIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXI+CiAgICAgICAgaW50ZXJuYWxHZXRBbnlGaWVsZCgpIHsKICAgICAgaWYgKGFueUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGFueUZpZWxkQ29udmVydGVyKTsKICAgICAgfQogICAgICByZXR1cm4gYW55RmllbGRfOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUFueUZpZWxkKCkgewogICAgICBpZiAoYW55RmllbGRfID09IG51bGwpIHsKICAgICAgICBhbnlGaWVsZF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihhbnlGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIGFueUZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0QW55RmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QW55RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQW55Jmd0OyBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNBbnlGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBbnlGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRBbnlGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueT4gZ2V0QW55RmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRBbnlGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQW55Jmd0OyBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55PiBnZXRBbnlGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QW55RmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkFueSZndDsgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkFueSBnZXRBbnlGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQW55IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUFueUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBhbnlGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQW55Jmd0OyBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGdldEFueUZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlQW55RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBhbnlGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBbnlGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICBpbnRlcm5hbEdldE11dGFibGVBbnlGaWVsZCgpLmNsZWFyKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQW55Jmd0OyBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlQW55RmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQW55RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55PgogICAgICAgIGdldE11dGFibGVBbnlGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlQW55RmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5BbnkmZ3Q7IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBwdXRBbnlGaWVsZCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlKSB7CgogICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUFueUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQW55Jmd0OyBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsQW55RmllbGQoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Bbnk+IHZhbHVlcykgewogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55PiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQW55RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkFueSZndDsgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyIHB1dEFueUZpZWxkQnVpbGRlcklmQWJzZW50KAogICAgICAgIGludCBrZXkpIHsKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVBbnlGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkubmV3QnVpbGRlcigpOwogICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICB9CiAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuQW55KSB7CiAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYuQW55KSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyKSBlbnRyeTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBBcGlGaWVsZENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpPiB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQXBpIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYuQXBpT3JCdWlsZGVyIHZhbCkgewogICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQXBpKSB2YWw7IH0KICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgcmV0dXJuIEFwaUZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgfQogICAgfTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFwaUZpZWxkQ29udmVydGVyIGFwaUZpZWxkQ29udmVydGVyID0gbmV3IEFwaUZpZWxkQ29udmVydGVyKCk7CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5CdWlsZGVyPiBhcGlGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGksIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLkJ1aWxkZXI+CiAgICAgICAgaW50ZXJuYWxHZXRBcGlGaWVsZCgpIHsKICAgICAgaWYgKGFwaUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGFwaUZpZWxkQ29udmVydGVyKTsKICAgICAgfQogICAgICByZXR1cm4gYXBpRmllbGRfOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUFwaUZpZWxkKCkgewogICAgICBpZiAoYXBpRmllbGRfID09IG51bGwpIHsKICAgICAgICBhcGlGaWVsZF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihhcGlGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIGFwaUZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0QXBpRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QXBpRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQXBpJmd0OyBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNBcGlGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBcGlGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRBcGlGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaT4gZ2V0QXBpRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRBcGlGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQXBpJmd0OyBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpPiBnZXRBcGlGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QXBpRmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkFwaSZndDsgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSBnZXRBcGlGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQXBpIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUFwaUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBhcGlGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQXBpJmd0OyBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQXBpIGdldEFwaUZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlQXBpRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBhcGlGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBcGlGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICBpbnRlcm5hbEdldE11dGFibGVBcGlGaWVsZCgpLmNsZWFyKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQXBpJmd0OyBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlQXBpRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQXBpRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpPgogICAgICAgIGdldE11dGFibGVBcGlGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlQXBpRmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5BcGkmZ3Q7IGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBwdXRBcGlGaWVsZCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQXBpIHZhbHVlKSB7CgogICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUFwaUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQXBpJmd0OyBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsQXBpRmllbGQoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGk+IHZhbHVlcykgewogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQXBpRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkFwaSZndDsgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5CdWlsZGVyIHB1dEFwaUZpZWxkQnVpbGRlcklmQWJzZW50KAogICAgICAgIGludCBrZXkpIHsKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVBcGlGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkubmV3QnVpbGRlcigpOwogICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICB9CiAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuQXBpKSB7CiAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYuQXBpKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5CdWlsZGVyKSBlbnRyeTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBEdXJhdGlvbkZpZWxkQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uPiB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbk9yQnVpbGRlciB2YWwpIHsKICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbikgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24pIHZhbDsgfQogICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24uQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgcmV0dXJuIER1cmF0aW9uRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICB9CiAgICB9OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRHVyYXRpb25GaWVsZENvbnZlcnRlciBkdXJhdGlvbkZpZWxkQ29udmVydGVyID0gbmV3IER1cmF0aW9uRmllbGRDb252ZXJ0ZXIoKTsKCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLkJ1aWxkZXI+IGR1cmF0aW9uRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbk9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0RHVyYXRpb25GaWVsZCgpIHsKICAgICAgaWYgKGR1cmF0aW9uRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZHVyYXRpb25GaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgcmV0dXJuIGR1cmF0aW9uRmllbGRfOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbk9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUR1cmF0aW9uRmllbGQoKSB7CiAgICAgIGlmIChkdXJhdGlvbkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgZHVyYXRpb25GaWVsZF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihkdXJhdGlvbkZpZWxkQ29udmVydGVyKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZHVyYXRpb25GaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldER1cmF0aW9uRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RHVyYXRpb25GaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiZndDsgZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNEdXJhdGlvbkZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldER1cmF0aW9uRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RHVyYXRpb25GaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uPiBnZXREdXJhdGlvbkZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0RHVyYXRpb25GaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24mZ3Q7IGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uPiBnZXREdXJhdGlvbkZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXREdXJhdGlvbkZpZWxkKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiZndDsgZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZ2V0RHVyYXRpb25GaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVEdXJhdGlvbkZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBkdXJhdGlvbkZpZWxkQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiZndDsgZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZ2V0RHVyYXRpb25GaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbk9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRHVyYXRpb25GaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGR1cmF0aW9uRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRHVyYXRpb25GaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICBpbnRlcm5hbEdldE11dGFibGVEdXJhdGlvbkZpZWxkKCkuY2xlYXIoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiZndDsgZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRHVyYXRpb25GaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICBpbnRlcm5hbEdldE11dGFibGVEdXJhdGlvbkZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uPgogICAgICAgIGdldE11dGFibGVEdXJhdGlvbkZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVEdXJhdGlvbkZpZWxkKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24mZ3Q7IGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHB1dER1cmF0aW9uRmllbGQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIHZhbHVlKSB7CgogICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUR1cmF0aW9uRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiZndDsgZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRHVyYXRpb25GaWVsZCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uPiB2YWx1ZXMpIHsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRHVyYXRpb25GaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24mZ3Q7IGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLkJ1aWxkZXIgcHV0RHVyYXRpb25GaWVsZEJ1aWxkZXJJZkFic2VudCgKICAgICAgICBpbnQga2V5KSB7CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25PckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVEdXJhdGlvbkZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24ubmV3QnVpbGRlcigpOwogICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICB9CiAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24pIHsKICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbikgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5CdWlsZGVyKSBlbnRyeTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBFbXB0eUZpZWxkQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5T3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PiB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eU9yQnVpbGRlciB2YWwpIHsKICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkpIHZhbDsgfQogICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgcmV0dXJuIEVtcHR5RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICB9CiAgICB9OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRW1wdHlGaWVsZENvbnZlcnRlciBlbXB0eUZpZWxkQ29udmVydGVyID0gbmV3IEVtcHR5RmllbGRDb252ZXJ0ZXIoKTsKCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5T3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LkJ1aWxkZXI+IGVtcHR5RmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eS5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0RW1wdHlGaWVsZCgpIHsKICAgICAgaWYgKGVtcHR5RmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZW1wdHlGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgcmV0dXJuIGVtcHR5RmllbGRfOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eS5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVtcHR5RmllbGQoKSB7CiAgICAgIGlmIChlbXB0eUZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgZW1wdHlGaWVsZF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihlbXB0eUZpZWxkQ29udmVydGVyKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZW1wdHlGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEVtcHR5RmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RW1wdHlGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSZndDsgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNFbXB0eUZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEVtcHR5RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RW1wdHlGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PiBnZXRFbXB0eUZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0RW1wdHlGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRW1wdHkmZ3Q7IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PiBnZXRFbXB0eUZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbXB0eUZpZWxkKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSZndDsgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgZ2V0RW1wdHlGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5T3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVFbXB0eUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBlbXB0eUZpZWxkQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSZndDsgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgZ2V0RW1wdHlGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRW1wdHlGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGVtcHR5RmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRW1wdHlGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICBpbnRlcm5hbEdldE11dGFibGVFbXB0eUZpZWxkKCkuY2xlYXIoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSZndDsgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRW1wdHlGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICBpbnRlcm5hbEdldE11dGFibGVFbXB0eUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PgogICAgICAgIGdldE11dGFibGVFbXB0eUZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVFbXB0eUZpZWxkKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRW1wdHkmZ3Q7IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHB1dEVtcHR5RmllbGQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IHZhbHVlKSB7CgogICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUVtcHR5RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSZndDsgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRW1wdHlGaWVsZCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PiB2YWx1ZXMpIHsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW1wdHlGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRW1wdHkmZ3Q7IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LkJ1aWxkZXIgcHV0RW1wdHlGaWVsZEJ1aWxkZXJJZkFic2VudCgKICAgICAgICBpbnQga2V5KSB7CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHlPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVFbXB0eUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5T3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkubmV3QnVpbGRlcigpOwogICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICB9CiAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkpIHsKICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eS5CdWlsZGVyKSBlbnRyeTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBGaWVsZE1hc2tGaWVsZENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrPiB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrT3JCdWlsZGVyIHZhbCkgewogICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaykgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrKSB2YWw7IH0KICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgcmV0dXJuIEZpZWxkTWFza0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgfQogICAgfTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZpZWxkTWFza0ZpZWxkQ29udmVydGVyIGZpZWxkTWFza0ZpZWxkQ29udmVydGVyID0gbmV3IEZpZWxkTWFza0ZpZWxkQ29udmVydGVyKCk7CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5CdWlsZGVyPiBmaWVsZE1hc2tGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza09yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2ssIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLkJ1aWxkZXI+CiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZE1hc2tGaWVsZCgpIHsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGZpZWxkTWFza0ZpZWxkQ29udmVydGVyKTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXNrRmllbGRfOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFza0ZpZWxkKCkgewogICAgICBpZiAoZmllbGRNYXNrRmllbGRfID09IG51bGwpIHsKICAgICAgICBmaWVsZE1hc2tGaWVsZF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmaWVsZE1hc2tGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIGZpZWxkTWFza0ZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXNrRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXNrRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrJmd0OyBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRmllbGRNYXNrRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmllbGRNYXNrRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmllbGRNYXNrRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2s+IGdldEZpZWxkTWFza0ZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXNrRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayZndDsgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2s+IGdldEZpZWxkTWFza0ZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRGaWVsZE1hc2tGaWVsZCgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrJmd0OyBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBnZXRGaWVsZE1hc2tGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFza0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBmaWVsZE1hc2tGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrJmd0OyBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBnZXRGaWVsZE1hc2tGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFza0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXNrRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXNrRmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRmllbGRNYXNrRmllbGQoKS5jbGVhcigpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayZndDsgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hc2tGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hc2tGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2s+CiAgICAgICAgZ2V0TXV0YWJsZUZpZWxkTWFza0ZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVGaWVsZE1hc2tGaWVsZCgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayZndDsgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBwdXRGaWVsZE1hc2tGaWVsZCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIHZhbHVlKSB7CgogICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFza0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrJmd0OyBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEZpZWxkTWFza0ZpZWxkKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrPiB2YWx1ZXMpIHsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaz4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFza0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2smZ3Q7IGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLkJ1aWxkZXIgcHV0RmllbGRNYXNrRmllbGRCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgaW50IGtleSkgewogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza09yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZpZWxkTWFza0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza09yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5uZXdCdWlsZGVyKCk7CiAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgIH0KICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2spIHsKICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2spIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLkJ1aWxkZXIpIGVudHJ5OwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFNvdXJjZUNvbnRleHRGaWVsZENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ+IHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dE9yQnVpbGRlciB2YWwpIHsKICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0KSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0KSB2YWw7IH0KICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICByZXR1cm4gU291cmNlQ29udGV4dEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgfQogICAgfTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFNvdXJjZUNvbnRleHRGaWVsZENvbnZlcnRlciBzb3VyY2VDb250ZXh0RmllbGRDb252ZXJ0ZXIgPSBuZXcgU291cmNlQ29udGV4dEZpZWxkQ29udmVydGVyKCk7CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5CdWlsZGVyPiBzb3VyY2VDb250ZXh0RmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0U291cmNlQ29udGV4dEZpZWxkKCkgewogICAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KHNvdXJjZUNvbnRleHRGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgcmV0dXJuIHNvdXJjZUNvbnRleHRGaWVsZF87CiAgICB9CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHRPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LkJ1aWxkZXI+CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU291cmNlQ29udGV4dEZpZWxkKCkgewogICAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KHNvdXJjZUNvbnRleHRGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHNvdXJjZUNvbnRleHRGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFNvdXJjZUNvbnRleHRGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTb3VyY2VDb250ZXh0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCZndDsgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTb3VyY2VDb250ZXh0RmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0U291cmNlQ29udGV4dEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFNvdXJjZUNvbnRleHRGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ+IGdldFNvdXJjZUNvbnRleHRGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldFNvdXJjZUNvbnRleHRGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCZndDsgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dD4gZ2V0U291cmNlQ29udGV4dEZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTb3VyY2VDb250ZXh0RmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQmZ3Q7IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgZ2V0U291cmNlQ29udGV4dEZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVTb3VyY2VDb250ZXh0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IHNvdXJjZUNvbnRleHRGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCZndDsgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBnZXRTb3VyY2VDb250ZXh0RmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlU291cmNlQ29udGV4dEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gc291cmNlQ29udGV4dEZpZWxkQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICBwdWJsaWMgQnVpbGRlciBjbGVhclNvdXJjZUNvbnRleHRGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICBpbnRlcm5hbEdldE11dGFibGVTb3VyY2VDb250ZXh0RmllbGQoKS5jbGVhcigpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQmZ3Q7IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVNvdXJjZUNvbnRleHRGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICBpbnRlcm5hbEdldE11dGFibGVTb3VyY2VDb250ZXh0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dD4KICAgICAgICBnZXRNdXRhYmxlU291cmNlQ29udGV4dEZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTb3VyY2VDb250ZXh0RmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0Jmd0OyBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBwdXRTb3VyY2VDb250ZXh0RmllbGQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgdmFsdWUpIHsKCiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU291cmNlQ29udGV4dEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCZndDsgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsU291cmNlQ29udGV4dEZpZWxkKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dD4gdmFsdWVzKSB7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0PiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU291cmNlQ29udGV4dEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0Jmd0OyBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LkJ1aWxkZXIgcHV0U291cmNlQ29udGV4dEZpZWxkQnVpbGRlcklmQWJzZW50KAogICAgICAgIGludCBrZXkpIHsKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlU291cmNlQ29udGV4dEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHRPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0Lm5ld0J1aWxkZXIoKTsKICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgfQogICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQpIHsKICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0KSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuQnVpbGRlcikgZW50cnk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU3RydWN0RmllbGRDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0T3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdD4gewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdE9yQnVpbGRlciB2YWwpIHsKICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCkgdmFsOyB9CiAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdD4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgIHJldHVybiBTdHJ1Y3RGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgIH0KICAgIH07CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJ1Y3RGaWVsZENvbnZlcnRlciBzdHJ1Y3RGaWVsZENvbnZlcnRlciA9IG5ldyBTdHJ1Y3RGaWVsZENvbnZlcnRlcigpOwoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0T3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuQnVpbGRlcj4gc3RydWN0RmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0LCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0U3RydWN0RmllbGQoKSB7CiAgICAgIGlmIChzdHJ1Y3RGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihzdHJ1Y3RGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgcmV0dXJuIHN0cnVjdEZpZWxkXzsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0T3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuQnVpbGRlcj4KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJ1Y3RGaWVsZCgpIHsKICAgICAgaWYgKHN0cnVjdEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgc3RydWN0RmllbGRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oc3RydWN0RmllbGRDb252ZXJ0ZXIpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBzdHJ1Y3RGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFN0cnVjdEZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cnVjdEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCZndDsgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RydWN0RmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RydWN0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RydWN0RmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Q+IGdldFN0cnVjdEZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0U3RydWN0RmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCZndDsgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdD4gZ2V0U3RydWN0RmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cnVjdEZpZWxkKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QmZ3Q7IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QgZ2V0U3RydWN0RmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0T3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVTdHJ1Y3RGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gc3RydWN0RmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCZndDsgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBnZXRTdHJ1Y3RGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZVN0cnVjdEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gc3RydWN0RmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RydWN0RmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RydWN0RmllbGQoKS5jbGVhcigpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCZndDsgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVN0cnVjdEZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cnVjdEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdD4KICAgICAgICBnZXRNdXRhYmxlU3RydWN0RmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVN0cnVjdEZpZWxkKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU3RydWN0Jmd0OyBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0U3RydWN0RmllbGQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCB2YWx1ZSkgewoKICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJ1Y3RGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCZndDsgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFN0cnVjdEZpZWxkKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0PiB2YWx1ZXMpIHsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdD4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cnVjdEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QmZ3Q7IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuQnVpbGRlciBwdXRTdHJ1Y3RGaWVsZEJ1aWxkZXJJZkFic2VudCgKICAgICAgICBpbnQga2V5KSB7CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0T3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlU3RydWN0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0T3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0Lm5ld0J1aWxkZXIoKTsKICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgfQogICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCkgewogICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuQnVpbGRlcikgZW50cnk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVGltZXN0YW1wRmllbGRDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcD4gewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcE9yQnVpbGRlciB2YWwpIHsKICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXApIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCkgdmFsOyB9CiAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcD4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgIHJldHVybiBUaW1lc3RhbXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgIH0KICAgIH07CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUaW1lc3RhbXBGaWVsZENvbnZlcnRlciB0aW1lc3RhbXBGaWVsZENvbnZlcnRlciA9IG5ldyBUaW1lc3RhbXBGaWVsZENvbnZlcnRlcigpOwoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuQnVpbGRlcj4gdGltZXN0YW1wRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0VGltZXN0YW1wRmllbGQoKSB7CiAgICAgIGlmICh0aW1lc3RhbXBGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8Pih0aW1lc3RhbXBGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgcmV0dXJuIHRpbWVzdGFtcEZpZWxkXzsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuQnVpbGRlcj4KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVUaW1lc3RhbXBGaWVsZCgpIHsKICAgICAgaWYgKHRpbWVzdGFtcEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgdGltZXN0YW1wRmllbGRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4odGltZXN0YW1wRmllbGRDb252ZXJ0ZXIpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aW1lc3RhbXBGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFRpbWVzdGFtcEZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFRpbWVzdGFtcEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCZndDsgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVGltZXN0YW1wRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0VGltZXN0YW1wRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VGltZXN0YW1wRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXA+IGdldFRpbWVzdGFtcEZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0VGltZXN0YW1wRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCZndDsgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcD4gZ2V0VGltZXN0YW1wRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFRpbWVzdGFtcEZpZWxkKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAmZ3Q7IHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgZ2V0VGltZXN0YW1wRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVUaW1lc3RhbXBGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gdGltZXN0YW1wRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCZndDsgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBnZXRUaW1lc3RhbXBGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZVRpbWVzdGFtcEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdGltZXN0YW1wRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVGltZXN0YW1wRmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVGltZXN0YW1wRmllbGQoKS5jbGVhcigpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCZndDsgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVRpbWVzdGFtcEZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGludGVybmFsR2V0TXV0YWJsZVRpbWVzdGFtcEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcD4KICAgICAgICBnZXRNdXRhYmxlVGltZXN0YW1wRmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVRpbWVzdGFtcEZpZWxkKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wJmd0OyB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0VGltZXN0YW1wRmllbGQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB2YWx1ZSkgewoKICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICBpbnRlcm5hbEdldE11dGFibGVUaW1lc3RhbXBGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCZndDsgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFRpbWVzdGFtcEZpZWxkKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wPiB2YWx1ZXMpIHsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcD4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZVRpbWVzdGFtcEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAmZ3Q7IHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuQnVpbGRlciBwdXRUaW1lc3RhbXBGaWVsZEJ1aWxkZXJJZkFic2VudCgKICAgICAgICBpbnQga2V5KSB7CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlVGltZXN0YW1wRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLm5ld0J1aWxkZXIoKTsKICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgfQogICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCkgewogICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuQnVpbGRlcikgZW50cnk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVHlwZUZpZWxkQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZT4gewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlT3JCdWlsZGVyIHZhbCkgewogICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUpIHZhbDsgfQogICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYuVHlwZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgIHJldHVybiBUeXBlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICB9CiAgICB9OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVHlwZUZpZWxkQ29udmVydGVyIHR5cGVGaWVsZENvbnZlcnRlciA9IG5ldyBUeXBlRmllbGRDb252ZXJ0ZXIoKTsKCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLkJ1aWxkZXI+IHR5cGVGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLkJ1aWxkZXI+CiAgICAgICAgaW50ZXJuYWxHZXRUeXBlRmllbGQoKSB7CiAgICAgIGlmICh0eXBlRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4odHlwZUZpZWxkQ29udmVydGVyKTsKICAgICAgfQogICAgICByZXR1cm4gdHlwZUZpZWxkXzsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUuQnVpbGRlcj4KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVUeXBlRmllbGQoKSB7CiAgICAgIGlmICh0eXBlRmllbGRfID09IG51bGwpIHsKICAgICAgICB0eXBlRmllbGRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4odHlwZUZpZWxkQ29udmVydGVyKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdHlwZUZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0VHlwZUZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFR5cGVGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5UeXBlJmd0OyB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVHlwZUZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldFR5cGVGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRUeXBlRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlPiBnZXRUeXBlRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRUeXBlRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlR5cGUmZ3Q7IHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZT4gZ2V0VHlwZUZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRUeXBlRmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlR5cGUmZ3Q7IHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuVHlwZSBnZXRUeXBlRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZVR5cGVGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gdHlwZUZpZWxkQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5UeXBlJmd0OyB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUgZ2V0VHlwZUZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZVR5cGVGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHR5cGVGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJUeXBlRmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVHlwZUZpZWxkKCkuY2xlYXIoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5UeXBlJmd0OyB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVR5cGVGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICBpbnRlcm5hbEdldE11dGFibGVUeXBlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZT4KICAgICAgICBnZXRNdXRhYmxlVHlwZUZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVUeXBlRmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5UeXBlJmd0OyB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHB1dFR5cGVGaWVsZCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZSB2YWx1ZSkgewoKICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICBpbnRlcm5hbEdldE11dGFibGVUeXBlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5UeXBlJmd0OyB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFR5cGVGaWVsZCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGU+IHZhbHVlcykgewogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZVR5cGVGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVHlwZSZndDsgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLkJ1aWxkZXIgcHV0VHlwZUZpZWxkQnVpbGRlcklmQWJzZW50KAogICAgICAgIGludCBrZXkpIHsKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlVHlwZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLm5ld0J1aWxkZXIoKTsKICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgfQogICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUpIHsKICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUuQnVpbGRlcikgZW50cnk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRG91YmxlRmllbGRDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+IHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlT3JCdWlsZGVyIHZhbCkgewogICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSkgdmFsOyB9CiAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICByZXR1cm4gRG91YmxlRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICB9CiAgICB9OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRG91YmxlRmllbGRDb252ZXJ0ZXIgZG91YmxlRmllbGRDb252ZXJ0ZXIgPSBuZXcgRG91YmxlRmllbGRDb252ZXJ0ZXIoKTsKCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLkJ1aWxkZXI+IGRvdWJsZUZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuQnVpbGRlcj4KICAgICAgICBpbnRlcm5hbEdldERvdWJsZUZpZWxkKCkgewogICAgICBpZiAoZG91YmxlRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZG91YmxlRmllbGRDb252ZXJ0ZXIpOwogICAgICB9CiAgICAgIHJldHVybiBkb3VibGVGaWVsZF87CiAgICB9CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLkJ1aWxkZXI+CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRG91YmxlRmllbGQoKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIGRvdWJsZUZpZWxkXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGRvdWJsZUZpZWxkQ29udmVydGVyKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZG91YmxlRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXREb3VibGVGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXREb3VibGVGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSZndDsgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0RvdWJsZUZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldERvdWJsZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldERvdWJsZUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+IGdldERvdWJsZUZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0RG91YmxlRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlJmd0OyBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlPiBnZXREb3VibGVGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RG91YmxlRmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlJmd0OyBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGdldERvdWJsZUZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZURvdWJsZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBkb3VibGVGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUmZ3Q7IGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZ2V0RG91YmxlRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZURvdWJsZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZG91YmxlRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRG91YmxlRmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRG91YmxlRmllbGQoKS5jbGVhcigpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlJmd0OyBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZURvdWJsZUZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGludGVybmFsR2V0TXV0YWJsZURvdWJsZUZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlPgogICAgICAgIGdldE11dGFibGVEb3VibGVGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRG91YmxlRmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSZndDsgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBwdXREb3VibGVGaWVsZCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgdmFsdWUpIHsKCiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRG91YmxlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSZndDsgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxEb3VibGVGaWVsZCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlPiB2YWx1ZXMpIHsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRG91YmxlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlJmd0OyBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLkJ1aWxkZXIgcHV0RG91YmxlRmllbGRCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgaW50IGtleSkgewogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRG91YmxlRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgIH0KICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSkgewogICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLkJ1aWxkZXIpIGVudHJ5OwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEZsb2F0RmllbGRDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlPiB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWVPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSkgdmFsOyB9CiAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgcmV0dXJuIEZsb2F0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICB9CiAgICB9OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRmxvYXRGaWVsZENvbnZlcnRlciBmbG9hdEZpZWxkQ29udmVydGVyID0gbmV3IEZsb2F0RmllbGRDb252ZXJ0ZXIoKTsKCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLkJ1aWxkZXI+IGZsb2F0RmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0RmxvYXRGaWVsZCgpIHsKICAgICAgaWYgKGZsb2F0RmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oZmxvYXRGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgcmV0dXJuIGZsb2F0RmllbGRfOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUZsb2F0RmllbGQoKSB7CiAgICAgIGlmIChmbG9hdEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgZmxvYXRGaWVsZF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihmbG9hdEZpZWxkQ29udmVydGVyKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZmxvYXRGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEZsb2F0RmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmxvYXRGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlJmd0OyBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNGbG9hdEZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEZsb2F0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0RmxvYXRGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWU+IGdldEZsb2F0RmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRGbG9hdEZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlJmd0OyBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZT4gZ2V0RmxvYXRGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RmxvYXRGaWVsZCgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSZndDsgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZ2V0RmxvYXRGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlRmxvYXRGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gZmxvYXRGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSZndDsgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZ2V0RmxvYXRGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVGbG9hdEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gZmxvYXRGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGbG9hdEZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUZsb2F0RmllbGQoKS5jbGVhcigpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUmZ3Q7IGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGbG9hdEZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGludGVybmFsR2V0TXV0YWJsZUZsb2F0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZT4KICAgICAgICBnZXRNdXRhYmxlRmxvYXRGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRmxvYXRGaWVsZCgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUmZ3Q7IGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBwdXRGbG9hdEZpZWxkKAogICAgICAgIGludCBrZXksCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIHZhbHVlKSB7CgogICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUZsb2F0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlJmd0OyBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRmxvYXRGaWVsZCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWU+IHZhbHVlcykgewogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUZsb2F0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUmZ3Q7IGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLkJ1aWxkZXIgcHV0RmxvYXRGaWVsZEJ1aWxkZXJJZkFic2VudCgKICAgICAgICBpbnQga2V5KSB7CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUZsb2F0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUubmV3QnVpbGRlcigpOwogICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICB9CiAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSkgewogICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5CdWlsZGVyKSBlbnRyeTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnQ2NEZpZWxkQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZT4gewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyIHZhbCkgewogICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUpIHZhbDsgfQogICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgIHJldHVybiBJbnQ2NEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgfQogICAgfTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEludDY0RmllbGRDb252ZXJ0ZXIgaW50NjRGaWVsZENvbnZlcnRlciA9IG5ldyBJbnQ2NEZpZWxkQ29udmVydGVyKCk7CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5CdWlsZGVyPiBpbnQ2NEZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuQnVpbGRlcj4KICAgICAgICBpbnRlcm5hbEdldEludDY0RmllbGQoKSB7CiAgICAgIGlmIChpbnQ2NEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGludDY0RmllbGRDb252ZXJ0ZXIpOwogICAgICB9CiAgICAgIHJldHVybiBpbnQ2NEZpZWxkXzsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuQnVpbGRlcj4KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQ2NEZpZWxkKCkgewogICAgICBpZiAoaW50NjRGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIGludDY0RmllbGRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oaW50NjRGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIGludDY0RmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRJbnQ2NEZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDY0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSZndDsgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW50NjRGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbnQ2NEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEludDY0RmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPiBnZXRJbnQ2NEZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0SW50NjRGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSZndDsgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWU+IGdldEludDY0RmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDY0RmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUmZ3Q7IGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGdldEludDY0RmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUludDY0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGludDY0RmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUmZ3Q7IGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGdldEludDY0RmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlSW50NjRGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDY0RmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50NjRGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQ2NEZpZWxkKCkuY2xlYXIoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlJmd0OyBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlSW50NjRGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQ2NEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWU+CiAgICAgICAgZ2V0TXV0YWJsZUludDY0RmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUludDY0RmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlJmd0OyBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0SW50NjRGaWVsZCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSB2YWx1ZSkgewoKICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQ2NEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSZndDsgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEludDY0RmllbGQoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPiB2YWx1ZXMpIHsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWU+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgfQogICAgICBpbnRlcm5hbEdldE11dGFibGVJbnQ2NEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlJmd0OyBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5CdWlsZGVyIHB1dEludDY0RmllbGRCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgaW50IGtleSkgewogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWVPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVJbnQ2NEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLm5ld0J1aWxkZXIoKTsKICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgfQogICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUpIHsKICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuQnVpbGRlcikgZW50cnk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVWludDY0RmllbGRDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWU+IHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlT3JCdWlsZGVyIHZhbCkgewogICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSkgdmFsOyB9CiAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWU+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICByZXR1cm4gVWludDY0RmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICB9CiAgICB9OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVWludDY0RmllbGRDb252ZXJ0ZXIgdWludDY0RmllbGRDb252ZXJ0ZXIgPSBuZXcgVWludDY0RmllbGRDb252ZXJ0ZXIoKTsKCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLkJ1aWxkZXI+IHVpbnQ2NEZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuQnVpbGRlcj4KICAgICAgICBpbnRlcm5hbEdldFVpbnQ2NEZpZWxkKCkgewogICAgICBpZiAodWludDY0RmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4odWludDY0RmllbGRDb252ZXJ0ZXIpOwogICAgICB9CiAgICAgIHJldHVybiB1aW50NjRGaWVsZF87CiAgICB9CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLkJ1aWxkZXI+CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVWludDY0RmllbGQoKSB7CiAgICAgIGlmICh1aW50NjRGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHVpbnQ2NEZpZWxkXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KHVpbnQ2NEZpZWxkQ29udmVydGVyKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdWludDY0RmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRVaW50NjRGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVaW50NjRGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSZndDsgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1VpbnQ2NEZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVpbnQ2NEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVpbnQ2NEZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWU+IGdldFVpbnQ2NEZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0VWludDY0RmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlJmd0OyB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlPiBnZXRVaW50NjRGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0VWludDY0RmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlJmd0OyB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIGdldFVpbnQ2NEZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZVVpbnQ2NEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyB1aW50NjRGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUmZ3Q7IHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgZ2V0VWludDY0RmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZVVpbnQ2NEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdWludDY0RmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVWludDY0RmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVWludDY0RmllbGQoKS5jbGVhcigpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlJmd0OyB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVVpbnQ2NEZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGludGVybmFsR2V0TXV0YWJsZVVpbnQ2NEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlPgogICAgICAgIGdldE11dGFibGVVaW50NjRGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVWludDY0RmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSZndDsgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBwdXRVaW50NjRGaWVsZCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdmFsdWUpIHsKCiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVWludDY0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSZndDsgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxVaW50NjRGaWVsZCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlPiB2YWx1ZXMpIHsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVWludDY0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlJmd0OyB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLkJ1aWxkZXIgcHV0VWludDY0RmllbGRCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgaW50IGtleSkgewogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlVWludDY0RmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgIH0KICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSkgewogICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLkJ1aWxkZXIpIGVudHJ5OwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyRmllbGRDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlPiB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBidWlsZChjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWVPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSkgdmFsOyB9CiAgICAgICAgcmV0dXJuICgoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgcmV0dXJuIEludDMyRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICB9CiAgICB9OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgSW50MzJGaWVsZENvbnZlcnRlciBpbnQzMkZpZWxkQ29udmVydGVyID0gbmV3IEludDMyRmllbGRDb252ZXJ0ZXIoKTsKCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLkJ1aWxkZXI+IGludDMyRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0SW50MzJGaWVsZCgpIHsKICAgICAgaWYgKGludDMyRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oaW50MzJGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyRmllbGRfOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgaW50MzJGaWVsZF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihpbnQzMkZpZWxkQ29udmVydGVyKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gaW50MzJGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEludDMyRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlJmd0OyBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbnQzMkZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEludDMyRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWU+IGdldEludDMyRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMkZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlJmd0OyBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZT4gZ2V0SW50MzJGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0SW50MzJGaWVsZCgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSZndDsgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgZ2V0SW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gaW50MzJGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSZndDsgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgZ2V0SW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVJbnQzMkZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gaW50MzJGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMkZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyRmllbGQoKS5jbGVhcigpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUmZ3Q7IGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJbnQzMkZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZT4KICAgICAgICBnZXRNdXRhYmxlSW50MzJGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlSW50MzJGaWVsZCgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUmZ3Q7IGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBwdXRJbnQzMkZpZWxkKAogICAgICAgIGludCBrZXksCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIHZhbHVlKSB7CgogICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlJmd0OyBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW50MzJGaWVsZCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWU+IHZhbHVlcykgewogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZUludDMyRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUmZ3Q7IGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLkJ1aWxkZXIgcHV0SW50MzJGaWVsZEJ1aWxkZXJJZkFic2VudCgKICAgICAgICBpbnQga2V5KSB7CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZUludDMyRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUubmV3QnVpbGRlcigpOwogICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICB9CiAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSkgewogICAgICAgIGVudHJ5ID0gKChjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5CdWlsZGVyKSBlbnRyeTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBVaW50MzJGaWVsZENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZT4gewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGJ1aWxkKGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWVPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlKSB2YWw7IH0KICAgICAgICByZXR1cm4gKChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgIHJldHVybiBVaW50MzJGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgIH0KICAgIH07CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBVaW50MzJGaWVsZENvbnZlcnRlciB1aW50MzJGaWVsZENvbnZlcnRlciA9IG5ldyBVaW50MzJGaWVsZENvbnZlcnRlcigpOwoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlcj4gdWludDMyRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0VWludDMyRmllbGQoKSB7CiAgICAgIGlmICh1aW50MzJGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8Pih1aW50MzJGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgcmV0dXJuIHVpbnQzMkZpZWxkXzsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlcj4KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVaW50MzJGaWVsZCgpIHsKICAgICAgaWYgKHVpbnQzMkZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgdWludDMyRmllbGRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4odWludDMyRmllbGRDb252ZXJ0ZXIpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB1aW50MzJGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFVpbnQzMkZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVpbnQzMkZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlJmd0OyB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVWludDMyRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0VWludDMyRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VWludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZT4gZ2V0VWludDMyRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRVaW50MzJGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUmZ3Q7IHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+IGdldFVpbnQzMkZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVaW50MzJGaWVsZCgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUmZ3Q7IHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgZ2V0VWludDMyRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlVWludDMyRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IHVpbnQzMkZpZWxkQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSZndDsgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBnZXRVaW50MzJGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlVWludDMyRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiB1aW50MzJGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVaW50MzJGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICBpbnRlcm5hbEdldE11dGFibGVVaW50MzJGaWVsZCgpLmNsZWFyKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUmZ3Q7IHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVWludDMyRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVWludDMyRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+CiAgICAgICAgZ2V0TXV0YWJsZVVpbnQzMkZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVVaW50MzJGaWVsZCgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlJmd0OyB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHB1dFVpbnQzMkZpZWxkKAogICAgICAgIGludCBrZXksCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB2YWx1ZSkgewoKICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICBpbnRlcm5hbEdldE11dGFibGVVaW50MzJGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlJmd0OyB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFVpbnQzMkZpZWxkKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+IHZhbHVlcykgewogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgfQogICAgICBpbnRlcm5hbEdldE11dGFibGVVaW50MzJGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUmZ3Q7IHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlciBwdXRVaW50MzJGaWVsZEJ1aWxkZXJJZkFic2VudCgKICAgICAgICBpbnQga2V5KSB7CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWVPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVVaW50MzJGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLm5ld0J1aWxkZXIoKTsKICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgfQogICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlKSB7CiAgICAgICAgZW50cnkgPSAoKGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlcikgZW50cnk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQm9vbEZpZWxkQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWU+IHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlKSB7IHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUpIHZhbDsgfQogICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWU+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICByZXR1cm4gQm9vbEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgfQogICAgfTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEJvb2xGaWVsZENvbnZlcnRlciBib29sRmllbGRDb252ZXJ0ZXIgPSBuZXcgQm9vbEZpZWxkQ29udmVydGVyKCk7CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5CdWlsZGVyPiBib29sRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0Qm9vbEZpZWxkKCkgewogICAgICBpZiAoYm9vbEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGJvb2xGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgcmV0dXJuIGJvb2xGaWVsZF87CiAgICB9CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLkJ1aWxkZXI+CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQm9vbEZpZWxkKCkgewogICAgICBpZiAoYm9vbEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgYm9vbEZpZWxkXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGJvb2xGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIGJvb2xGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEJvb2xGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRCb29sRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlJmd0OyBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0Jvb2xGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRCb29sRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0Qm9vbEZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlPiBnZXRCb29sRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRCb29sRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSZndDsgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlPiBnZXRCb29sRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEJvb2xGaWVsZCgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlJmd0OyBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgZ2V0Qm9vbEZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlQm9vbEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBib29sRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSZndDsgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGdldEJvb2xGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUJvb2xGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGJvb2xGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgfQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJCb29sRmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA4MDAwKTsKICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQm9vbEZpZWxkKCkuY2xlYXIoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUmZ3Q7IGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUJvb2xGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICBpbnRlcm5hbEdldE11dGFibGVCb29sRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlPgogICAgICAgIGdldE11dGFibGVCb29sRmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUJvb2xGaWVsZCgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSZndDsgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0Qm9vbEZpZWxkKAogICAgICAgIGludCBrZXksCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgdmFsdWUpIHsKCiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQm9vbEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlJmd0OyBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxCb29sRmllbGQoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWU+IHZhbHVlcykgewogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQm9vbEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUmZ3Q7IGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5CdWlsZGVyIHB1dEJvb2xGaWVsZEJ1aWxkZXJJZkFic2VudCgKICAgICAgICBpbnQga2V5KSB7CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlQm9vbEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgZW50cnkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgIH0KICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUpIHsKICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLkJ1aWxkZXIpIGVudHJ5OwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFN0cmluZ0ZpZWxkQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlPiB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSkgeyByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUpIHZhbDsgfQogICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgcmV0dXJuIFN0cmluZ0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgfQogICAgfTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZ0ZpZWxkQ29udmVydGVyIHN0cmluZ0ZpZWxkQ29udmVydGVyID0gbmV3IFN0cmluZ0ZpZWxkQ29udmVydGVyKCk7CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyPiBzdHJpbmdGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLkJ1aWxkZXI+CiAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdGaWVsZCgpIHsKICAgICAgaWYgKHN0cmluZ0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KHN0cmluZ0ZpZWxkQ29udmVydGVyKTsKICAgICAgfQogICAgICByZXR1cm4gc3RyaW5nRmllbGRfOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyPgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ0ZpZWxkKCkgewogICAgICBpZiAoc3RyaW5nRmllbGRfID09IG51bGwpIHsKICAgICAgICBzdHJpbmdGaWVsZF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihzdHJpbmdGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHN0cmluZ0ZpZWxkXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUmZ3Q7IHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTdHJpbmdGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlPiBnZXRTdHJpbmdGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldFN0cmluZ0ZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSZndDsgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZT4gZ2V0U3RyaW5nRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ0ZpZWxkKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSZndDsgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBnZXRTdHJpbmdGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gc3RyaW5nRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlJmd0OyBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGdldFN0cmluZ0ZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHN0cmluZ0ZpZWxkQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZ0ZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAxMDAwMCk7CiAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ0ZpZWxkKCkuY2xlYXIoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSZndDsgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVTdHJpbmdGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZT4KICAgICAgICBnZXRNdXRhYmxlU3RyaW5nRmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ0ZpZWxkKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUmZ3Q7IHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0U3RyaW5nRmllbGQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHZhbHVlKSB7CgogICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUmZ3Q7IHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsU3RyaW5nRmllbGQoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZT4gdmFsdWVzKSB7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSZndDsgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyIHB1dFN0cmluZ0ZpZWxkQnVpbGRlcklmQWJzZW50KAogICAgICAgIGludCBrZXkpIHsKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZVN0cmluZ0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICBlbnRyeSA9IGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUubmV3QnVpbGRlcigpOwogICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICB9CiAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUpIHsKICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyKSBlbnRyeTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBCeXRlc0ZpZWxkQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWVPckJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZT4gewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnVpbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyIHZhbCkgewogICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUpIHsgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUpIHZhbDsgfQogICAgICAgIHJldHVybiAoKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgIHJldHVybiBCeXRlc0ZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgfQogICAgfTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEJ5dGVzRmllbGRDb252ZXJ0ZXIgYnl0ZXNGaWVsZENvbnZlcnRlciA9IG5ldyBCeXRlc0ZpZWxkQ29udmVydGVyKCk7CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5CdWlsZGVyPiBieXRlc0ZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuQnVpbGRlcj4KICAgICAgICBpbnRlcm5hbEdldEJ5dGVzRmllbGQoKSB7CiAgICAgIGlmIChieXRlc0ZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KGJ5dGVzRmllbGRDb252ZXJ0ZXIpOwogICAgICB9CiAgICAgIHJldHVybiBieXRlc0ZpZWxkXzsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZU9yQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuQnVpbGRlcj4KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVCeXRlc0ZpZWxkKCkgewogICAgICBpZiAoYnl0ZXNGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIGJ5dGVzRmllbGRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4oYnl0ZXNGaWVsZENvbnZlcnRlcik7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIGJ5dGVzRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRCeXRlc0ZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEJ5dGVzRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSZndDsgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQnl0ZXNGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRCeXRlc0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEJ5dGVzRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlPiBnZXRCeXRlc0ZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0Qnl0ZXNGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSZndDsgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWU+IGdldEJ5dGVzRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEJ5dGVzRmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUmZ3Q7IGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGdldEJ5dGVzRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUJ5dGVzRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IGJ5dGVzRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUmZ3Q7IGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGdldEJ5dGVzRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlQnl0ZXNGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGJ5dGVzRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQnl0ZXNGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICBpbnRlcm5hbEdldE11dGFibGVCeXRlc0ZpZWxkKCkuY2xlYXIoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlJmd0OyBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlQnl0ZXNGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICBpbnRlcm5hbEdldE11dGFibGVCeXRlc0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWU+CiAgICAgICAgZ2V0TXV0YWJsZUJ5dGVzRmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUJ5dGVzRmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlJmd0OyBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcHV0Qnl0ZXNGaWVsZCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSB2YWx1ZSkgewoKICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICBpbnRlcm5hbEdldE11dGFibGVCeXRlc0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSZndDsgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEJ5dGVzRmllbGQoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlPiB2YWx1ZXMpIHsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWU+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgfQogICAgICBpbnRlcm5hbEdldE11dGFibGVCeXRlc0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlJmd0OyBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5CdWlsZGVyIHB1dEJ5dGVzRmllbGRCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgaW50IGtleSkgewogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWVPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVCeXRlc0ZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWVPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgIGVudHJ5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLm5ld0J1aWxkZXIoKTsKICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgfQogICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUpIHsKICAgICAgICBlbnRyeSA9ICgoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuQnVpbGRlcikgZW50cnk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgIH0KCgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTWFwV2VsbEtub3duVHlwZXMpCiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTWFwV2VsbEtub3duVHlwZXMpCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgc3RhdGljIHsKICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk1hcFdlbGxLbm93blR5cGVzKCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5NYXBXZWxsS25vd25UeXBlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1hcFdlbGxLbm93blR5cGVzPgogICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNYXBXZWxsS25vd25UeXBlcz4oKSB7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgTWFwV2VsbEtub3duVHlwZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICB0cnkgewogICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICB9CiAgfTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNYXBXZWxsS25vd25UeXBlcz4gcGFyc2VyKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWFwV2VsbEtub3duVHlwZXM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICByZXR1cm4gUEFSU0VSOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuTWFwV2VsbEtub3duVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogIH0KCn0KClBLAwQKAAAAAAAAACEAEMpaYVVJAABVSQAAOAAAAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdC9NYXBXZWxsS25vd25UeXBlc09yQnVpbGRlci5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfd2VsbF9rbm93bl90eXBlcy5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0OwoKcHVibGljIGludGVyZmFjZSBNYXBXZWxsS25vd25UeXBlc09yQnVpbGRlciBleHRlbmRzCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuTWFwV2VsbEtub3duVHlwZXMpCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQW55Jmd0OyBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgKi8KICBpbnQgZ2V0QW55RmllbGRDb3VudCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5BbnkmZ3Q7IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAqLwogIGJvb2xlYW4gY29udGFpbnNBbnlGaWVsZCgKICAgICAgaW50IGtleSk7CiAgLyoqCiAgICogVXNlIHtAbGluayAjZ2V0QW55RmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueT4KICBnZXRBbnlGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5BbnkmZ3Q7IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55PgogIGdldEFueUZpZWxkTWFwKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkFueSZndDsgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICovCiAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkgZ2V0QW55RmllbGRPckRlZmF1bHQoCiAgICAgIGludCBrZXksCiAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQW55IGRlZmF1bHRWYWx1ZSk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkFueSZndDsgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkgZ2V0QW55RmllbGRPclRocm93KAogICAgICBpbnQga2V5KTsKCiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkFwaSZndDsgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICovCiAgaW50IGdldEFwaUZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQXBpJmd0OyBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgKi8KICBib29sZWFuIGNvbnRhaW5zQXBpRmllbGQoCiAgICAgIGludCBrZXkpOwogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldEFwaUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICovCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGk+CiAgZ2V0QXBpRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQXBpJmd0OyBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaT4KICBnZXRBcGlGaWVsZE1hcCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5BcGkmZ3Q7IGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAqLwogIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQXBpIGdldEFwaUZpZWxkT3JEZWZhdWx0KAogICAgICBpbnQga2V5LAogICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSBkZWZhdWx0VmFsdWUpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5BcGkmZ3Q7IGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuQXBpIGdldEFwaUZpZWxkT3JUaHJvdygKICAgICAgaW50IGtleSk7CgogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiZndDsgZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgKi8KICBpbnQgZ2V0RHVyYXRpb25GaWVsZENvdW50KCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uJmd0OyBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAqLwogIGJvb2xlYW4gY29udGFpbnNEdXJhdGlvbkZpZWxkKAogICAgICBpbnQga2V5KTsKICAvKioKICAgKiBVc2Uge0BsaW5rICNnZXREdXJhdGlvbkZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICovCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbj4KICBnZXREdXJhdGlvbkZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uJmd0OyBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24+CiAgZ2V0RHVyYXRpb25GaWVsZE1hcCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiZndDsgZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgKi8KICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGdldER1cmF0aW9uRmllbGRPckRlZmF1bHQoCiAgICAgIGludCBrZXksCiAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZGVmYXVsdFZhbHVlKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24mZ3Q7IGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBnZXREdXJhdGlvbkZpZWxkT3JUaHJvdygKICAgICAgaW50IGtleSk7CgogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSZndDsgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgKi8KICBpbnQgZ2V0RW1wdHlGaWVsZENvdW50KCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkVtcHR5Jmd0OyBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAqLwogIGJvb2xlYW4gY29udGFpbnNFbXB0eUZpZWxkKAogICAgICBpbnQga2V5KTsKICAvKioKICAgKiBVc2Uge0BsaW5rICNnZXRFbXB0eUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICovCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eT4KICBnZXRFbXB0eUZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkVtcHR5Jmd0OyBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHk+CiAgZ2V0RW1wdHlGaWVsZE1hcCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSZndDsgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgKi8KICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGdldEVtcHR5RmllbGRPckRlZmF1bHQoCiAgICAgIGludCBrZXksCiAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgZGVmYXVsdFZhbHVlKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRW1wdHkmZ3Q7IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBnZXRFbXB0eUZpZWxkT3JUaHJvdygKICAgICAgaW50IGtleSk7CgogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2smZ3Q7IGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgKi8KICBpbnQgZ2V0RmllbGRNYXNrRmllbGRDb3VudCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2smZ3Q7IGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgKi8KICBib29sZWFuIGNvbnRhaW5zRmllbGRNYXNrRmllbGQoCiAgICAgIGludCBrZXkpOwogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldEZpZWxkTWFza0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICovCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2s+CiAgZ2V0RmllbGRNYXNrRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrJmd0OyBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2s+CiAgZ2V0RmllbGRNYXNrRmllbGRNYXAoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrJmd0OyBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICovCiAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZ2V0RmllbGRNYXNrRmllbGRPckRlZmF1bHQoCiAgICAgIGludCBrZXksCiAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGRlZmF1bHRWYWx1ZSk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayZndDsgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGdldEZpZWxkTWFza0ZpZWxkT3JUaHJvdygKICAgICAgaW50IGtleSk7CgogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0Jmd0OyBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAqLwogIGludCBnZXRTb3VyY2VDb250ZXh0RmllbGRDb3VudCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0Jmd0OyBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAqLwogIGJvb2xlYW4gY29udGFpbnNTb3VyY2VDb250ZXh0RmllbGQoCiAgICAgIGludCBrZXkpOwogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldFNvdXJjZUNvbnRleHRGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dD4KICBnZXRTb3VyY2VDb250ZXh0RmllbGQoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCZndDsgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ+CiAgZ2V0U291cmNlQ29udGV4dEZpZWxkTWFwKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQmZ3Q7IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICovCiAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IGdldFNvdXJjZUNvbnRleHRGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IGRlZmF1bHRWYWx1ZSk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQmZ3Q7IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IGdldFNvdXJjZUNvbnRleHRGaWVsZE9yVGhyb3coCiAgICAgIGludCBrZXkpOwoKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU3RydWN0Jmd0OyBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgKi8KICBpbnQgZ2V0U3RydWN0RmllbGRDb3VudCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QmZ3Q7IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAqLwogIGJvb2xlYW4gY29udGFpbnNTdHJ1Y3RGaWVsZCgKICAgICAgaW50IGtleSk7CiAgLyoqCiAgICogVXNlIHtAbGluayAjZ2V0U3RydWN0RmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdD4KICBnZXRTdHJ1Y3RGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QmZ3Q7IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0PgogIGdldFN0cnVjdEZpZWxkTWFwKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCZndDsgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICovCiAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QgZ2V0U3RydWN0RmllbGRPckRlZmF1bHQoCiAgICAgIGludCBrZXksCiAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IGRlZmF1bHRWYWx1ZSk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCZndDsgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QgZ2V0U3RydWN0RmllbGRPclRocm93KAogICAgICBpbnQga2V5KTsKCiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCZndDsgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICovCiAgaW50IGdldFRpbWVzdGFtcEZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wJmd0OyB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgKi8KICBib29sZWFuIGNvbnRhaW5zVGltZXN0YW1wRmllbGQoCiAgICAgIGludCBrZXkpOwogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldFRpbWVzdGFtcEZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICovCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXA+CiAgZ2V0VGltZXN0YW1wRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wJmd0OyB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcD4KICBnZXRUaW1lc3RhbXBGaWVsZE1hcCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAmZ3Q7IHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAqLwogIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIGdldFRpbWVzdGFtcEZpZWxkT3JEZWZhdWx0KAogICAgICBpbnQga2V5LAogICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBkZWZhdWx0VmFsdWUpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAmZ3Q7IHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIGdldFRpbWVzdGFtcEZpZWxkT3JUaHJvdygKICAgICAgaW50IGtleSk7CgogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5UeXBlJmd0OyB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICovCiAgaW50IGdldFR5cGVGaWVsZENvdW50KCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlR5cGUmZ3Q7IHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgKi8KICBib29sZWFuIGNvbnRhaW5zVHlwZUZpZWxkKAogICAgICBpbnQga2V5KTsKICAvKioKICAgKiBVc2Uge0BsaW5rICNnZXRUeXBlRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGU+CiAgZ2V0VHlwZUZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlR5cGUmZ3Q7IHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGU+CiAgZ2V0VHlwZUZpZWxkTWFwKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlR5cGUmZ3Q7IHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgKi8KICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUgZ2V0VHlwZUZpZWxkT3JEZWZhdWx0KAogICAgICBpbnQga2V5LAogICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUgZGVmYXVsdFZhbHVlKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVHlwZSZndDsgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZSBnZXRUeXBlRmllbGRPclRocm93KAogICAgICBpbnQga2V5KTsKCiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlJmd0OyBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICovCiAgaW50IGdldERvdWJsZUZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUmZ3Q7IGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgKi8KICBib29sZWFuIGNvbnRhaW5zRG91YmxlRmllbGQoCiAgICAgIGludCBrZXkpOwogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldERvdWJsZUZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICovCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZT4KICBnZXREb3VibGVGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSZndDsgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+CiAgZ2V0RG91YmxlRmllbGRNYXAoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUmZ3Q7IGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgKi8KICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGdldERvdWJsZUZpZWxkT3JEZWZhdWx0KAogICAgICBpbnQga2V5LAogICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRlZmF1bHRWYWx1ZSk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlJmd0OyBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBnZXREb3VibGVGaWVsZE9yVGhyb3coCiAgICAgIGludCBrZXkpOwoKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSZndDsgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICovCiAgaW50IGdldEZsb2F0RmllbGRDb3VudCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlJmd0OyBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgKi8KICBib29sZWFuIGNvbnRhaW5zRmxvYXRGaWVsZCgKICAgICAgaW50IGtleSk7CiAgLyoqCiAgICogVXNlIHtAbGluayAjZ2V0RmxvYXRGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZT4KICBnZXRGbG9hdEZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUmZ3Q7IGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZT4KICBnZXRGbG9hdEZpZWxkTWFwKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUmZ3Q7IGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAqLwogIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBnZXRGbG9hdEZpZWxkT3JEZWZhdWx0KAogICAgICBpbnQga2V5LAogICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZGVmYXVsdFZhbHVlKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSZndDsgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGdldEZsb2F0RmllbGRPclRocm93KAogICAgICBpbnQga2V5KTsKCiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUmZ3Q7IGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAqLwogIGludCBnZXRJbnQ2NEZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSZndDsgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICovCiAgYm9vbGVhbiBjb250YWluc0ludDY0RmllbGQoCiAgICAgIGludCBrZXkpOwogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldEludDY0RmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWU+CiAgZ2V0SW50NjRGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlJmd0OyBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWU+CiAgZ2V0SW50NjRGaWVsZE1hcCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlJmd0OyBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgKi8KICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgZ2V0SW50NjRGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGRlZmF1bHRWYWx1ZSk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUmZ3Q7IGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBnZXRJbnQ2NEZpZWxkT3JUaHJvdygKICAgICAgaW50IGtleSk7CgogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSZndDsgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqLwogIGludCBnZXRVaW50NjRGaWVsZENvdW50KCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlJmd0OyB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICovCiAgYm9vbGVhbiBjb250YWluc1VpbnQ2NEZpZWxkKAogICAgICBpbnQga2V5KTsKICAvKioKICAgKiBVc2Uge0BsaW5rICNnZXRVaW50NjRGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWU+CiAgZ2V0VWludDY0RmllbGQoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUmZ3Q7IHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlPgogIGdldFVpbnQ2NEZpZWxkTWFwKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlJmd0OyB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICovCiAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBnZXRVaW50NjRGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBkZWZhdWx0VmFsdWUpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSZndDsgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgZ2V0VWludDY0RmllbGRPclRocm93KAogICAgICBpbnQga2V5KTsKCiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUmZ3Q7IGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAqLwogIGludCBnZXRJbnQzMkZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSZndDsgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICovCiAgYm9vbGVhbiBjb250YWluc0ludDMyRmllbGQoCiAgICAgIGludCBrZXkpOwogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldEludDMyRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWU+CiAgZ2V0SW50MzJGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlJmd0OyBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWU+CiAgZ2V0SW50MzJGaWVsZE1hcCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlJmd0OyBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgKi8KICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgZ2V0SW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGRlZmF1bHRWYWx1ZSk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUmZ3Q7IGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBnZXRJbnQzMkZpZWxkT3JUaHJvdygKICAgICAgaW50IGtleSk7CgogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSZndDsgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAqLwogIGludCBnZXRVaW50MzJGaWVsZENvdW50KCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlJmd0OyB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICovCiAgYm9vbGVhbiBjb250YWluc1VpbnQzMkZpZWxkKAogICAgICBpbnQga2V5KTsKICAvKioKICAgKiBVc2Uge0BsaW5rICNnZXRVaW50MzJGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+CiAgZ2V0VWludDMyRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUmZ3Q7IHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlPgogIGdldFVpbnQzMkZpZWxkTWFwKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlJmd0OyB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICovCiAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBnZXRVaW50MzJGaWVsZE9yRGVmYXVsdCgKICAgICAgaW50IGtleSwKICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBkZWZhdWx0VmFsdWUpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSZndDsgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgZ2V0VWludDMyRmllbGRPclRocm93KAogICAgICBpbnQga2V5KTsKCiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSZndDsgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBpbnQgZ2V0Qm9vbEZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlJmd0OyBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAqLwogIGJvb2xlYW4gY29udGFpbnNCb29sRmllbGQoCiAgICAgIGludCBrZXkpOwogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldEJvb2xGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlPgogIGdldEJvb2xGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUmZ3Q7IGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWU+CiAgZ2V0Qm9vbEZpZWxkTWFwKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSZndDsgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBnZXRCb29sRmllbGRPckRlZmF1bHQoCiAgICAgIGludCBrZXksCiAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGRlZmF1bHRWYWx1ZSk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSZndDsgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBnZXRCb29sRmllbGRPclRocm93KAogICAgICBpbnQga2V5KTsKCiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlJmd0OyBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICovCiAgaW50IGdldFN0cmluZ0ZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUmZ3Q7IHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgKi8KICBib29sZWFuIGNvbnRhaW5zU3RyaW5nRmllbGQoCiAgICAgIGludCBrZXkpOwogIC8qKgogICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ0ZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICovCiAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZT4KICBnZXRTdHJpbmdGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSZndDsgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWU+CiAgZ2V0U3RyaW5nRmllbGRNYXAoKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUmZ3Q7IHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgKi8KICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGdldFN0cmluZ0ZpZWxkT3JEZWZhdWx0KAogICAgICBpbnQga2V5LAogICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGRlZmF1bHRWYWx1ZSk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlJmd0OyBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBnZXRTdHJpbmdGaWVsZE9yVGhyb3coCiAgICAgIGludCBrZXkpOwoKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSZndDsgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICovCiAgaW50IGdldEJ5dGVzRmllbGRDb3VudCgpOwogIC8qKgogICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlJmd0OyBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgKi8KICBib29sZWFuIGNvbnRhaW5zQnl0ZXNGaWVsZCgKICAgICAgaW50IGtleSk7CiAgLyoqCiAgICogVXNlIHtAbGluayAjZ2V0Qnl0ZXNGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZT4KICBnZXRCeXRlc0ZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUmZ3Q7IGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZT4KICBnZXRCeXRlc0ZpZWxkTWFwKCk7CiAgLyoqCiAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAuZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUmZ3Q7IGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAqLwogIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBnZXRCeXRlc0ZpZWxkT3JEZWZhdWx0KAogICAgICBpbnQga2V5LAogICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgZGVmYXVsdFZhbHVlKTsKICAvKioKICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSZndDsgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGdldEJ5dGVzRmllbGRPclRocm93KAogICAgICBpbnQga2V5KTsKfQpQSwMECgAAAAAAAAAhAIU2VGswKgIAMCoCADEAAABjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3QvT25lb2ZXZWxsS25vd25UeXBlcy5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfd2VsbF9rbm93bl90eXBlcy5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0OwoKLyoqCiAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXN9CiAqLwpwdWJsaWMgZmluYWwgY2xhc3MgT25lb2ZXZWxsS25vd25UeXBlcyBleHRlbmRzCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMpCiAgICBPbmVvZldlbGxLbm93blR5cGVzT3JCdWlsZGVyIHsKcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgLy8gVXNlIE9uZW9mV2VsbEtub3duVHlwZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICBwcml2YXRlIE9uZW9mV2VsbEtub3duVHlwZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICBzdXBlcihidWlsZGVyKTsKICB9CiAgcHJpdmF0ZSBPbmVvZldlbGxLbm93blR5cGVzKCkgewogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICByZXR1cm4gbmV3IE9uZW9mV2VsbEtub3duVHlwZXMoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0V2VsbEtub3duVHlwZXMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09uZW9mV2VsbEtub3duVHlwZXNfZGVzY3JpcHRvcjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbmVvZldlbGxLbm93blR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuT25lb2ZXZWxsS25vd25UeXBlcy5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgfQoKICBwcml2YXRlIGludCBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBvbmVvZkZpZWxkXzsKICBwdWJsaWMgZW51bSBPbmVvZkZpZWxkQ2FzZQogICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZS5JbnRlcm5hbE9uZU9mRW51bSB7CiAgICBBTllfRklFTEQoMSksCiAgICBBUElfRklFTEQoMiksCiAgICBEVVJBVElPTl9GSUVMRCgzKSwKICAgIEVNUFRZX0ZJRUxEKDQpLAogICAgRklFTERfTUFTS19GSUVMRCg1KSwKICAgIFNPVVJDRV9DT05URVhUX0ZJRUxEKDYpLAogICAgU1RSVUNUX0ZJRUxEKDcpLAogICAgVElNRVNUQU1QX0ZJRUxEKDgpLAogICAgVFlQRV9GSUVMRCg5KSwKICAgIERPVUJMRV9GSUVMRCgxMCksCiAgICBGTE9BVF9GSUVMRCgxMSksCiAgICBJTlQ2NF9GSUVMRCgxMiksCiAgICBVSU5UNjRfRklFTEQoMTMpLAogICAgSU5UMzJfRklFTEQoMTQpLAogICAgVUlOVDMyX0ZJRUxEKDE1KSwKICAgIEJPT0xfRklFTEQoMTYpLAogICAgU1RSSU5HX0ZJRUxEKDE3KSwKICAgIEJZVEVTX0ZJRUxEKDE4KSwKICAgIE9ORU9GRklFTERfTk9UX1NFVCgwKTsKICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwogICAgcHJpdmF0ZSBPbmVvZkZpZWxkQ2FzZShpbnQgdmFsdWUpIHsKICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWJlciBvZiB0aGUgZW51bSB0byBsb29rIGZvci4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1iZXIuCiAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgc3RhdGljIE9uZW9mRmllbGRDYXNlIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgT25lb2ZGaWVsZENhc2UgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgY2FzZSAxOiByZXR1cm4gQU5ZX0ZJRUxEOwogICAgICAgIGNhc2UgMjogcmV0dXJuIEFQSV9GSUVMRDsKICAgICAgICBjYXNlIDM6IHJldHVybiBEVVJBVElPTl9GSUVMRDsKICAgICAgICBjYXNlIDQ6IHJldHVybiBFTVBUWV9GSUVMRDsKICAgICAgICBjYXNlIDU6IHJldHVybiBGSUVMRF9NQVNLX0ZJRUxEOwogICAgICAgIGNhc2UgNjogcmV0dXJuIFNPVVJDRV9DT05URVhUX0ZJRUxEOwogICAgICAgIGNhc2UgNzogcmV0dXJuIFNUUlVDVF9GSUVMRDsKICAgICAgICBjYXNlIDg6IHJldHVybiBUSU1FU1RBTVBfRklFTEQ7CiAgICAgICAgY2FzZSA5OiByZXR1cm4gVFlQRV9GSUVMRDsKICAgICAgICBjYXNlIDEwOiByZXR1cm4gRE9VQkxFX0ZJRUxEOwogICAgICAgIGNhc2UgMTE6IHJldHVybiBGTE9BVF9GSUVMRDsKICAgICAgICBjYXNlIDEyOiByZXR1cm4gSU5UNjRfRklFTEQ7CiAgICAgICAgY2FzZSAxMzogcmV0dXJuIFVJTlQ2NF9GSUVMRDsKICAgICAgICBjYXNlIDE0OiByZXR1cm4gSU5UMzJfRklFTEQ7CiAgICAgICAgY2FzZSAxNTogcmV0dXJuIFVJTlQzMl9GSUVMRDsKICAgICAgICBjYXNlIDE2OiByZXR1cm4gQk9PTF9GSUVMRDsKICAgICAgICBjYXNlIDE3OiByZXR1cm4gU1RSSU5HX0ZJRUxEOwogICAgICAgIGNhc2UgMTg6IHJldHVybiBCWVRFU19GSUVMRDsKICAgICAgICBjYXNlIDA6IHJldHVybiBPTkVPRkZJRUxEX05PVF9TRVQ7CiAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgIH0KICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TnVtYmVyKCkgewogICAgICByZXR1cm4gdGhpcy52YWx1ZTsKICAgIH0KICB9OwoKICBwdWJsaWMgT25lb2ZGaWVsZENhc2UKICBnZXRPbmVvZkZpZWxkQ2FzZSgpIHsKICAgIHJldHVybiBPbmVvZkZpZWxkQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgb25lb2ZGaWVsZENhc2VfKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFOWV9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgYW55RmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNBbnlGaWVsZCgpIHsKICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgYW55RmllbGQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSBnZXRBbnlGaWVsZCgpIHsKICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMSkgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkFueSkgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIgZ2V0QW55RmllbGRPckJ1aWxkZXIoKSB7CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEpIHsKICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkpIG9uZW9mRmllbGRfOwogICAgfQogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQW55LmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVBJX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDI7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhcGlGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc0FwaUZpZWxkKCkgewogICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAyOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBhcGlGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQXBpIGdldEFwaUZpZWxkKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAyKSB7CiAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQXBpKSBvbmVvZkZpZWxkXzsKICAgIH0KICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaU9yQnVpbGRlciBnZXRBcGlGaWVsZE9yQnVpbGRlcigpIHsKICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMikgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSkgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVVJBVElPTl9GSUVMRF9GSUVMRF9OVU1CRVIgPSAzOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1cmF0aW9uRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNEdXJhdGlvbkZpZWxkKCkgewogICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAzOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgZHVyYXRpb25GaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZ2V0RHVyYXRpb25GaWVsZCgpIHsKICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMykgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uKSBvbmVvZkZpZWxkXzsKICAgIH0KICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyIGdldER1cmF0aW9uRmllbGRPckJ1aWxkZXIoKSB7CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDMpIHsKICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbikgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVNUFRZX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDQ7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgZW1wdHlGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc0VtcHR5RmllbGQoKSB7CiAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDQ7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBlbXB0eUZpZWxkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBnZXRFbXB0eUZpZWxkKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA0KSB7CiAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkpIG9uZW9mRmllbGRfOwogICAgfQogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHlPckJ1aWxkZXIgZ2V0RW1wdHlGaWVsZE9yQnVpbGRlcigpIHsKICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNCkgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5KSBvbmVvZkZpZWxkXzsKICAgIH0KICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTUFTS19GSUVMRF9GSUVMRF9OVU1CRVIgPSA1OwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTWFza0ZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRNYXNrRmllbGQoKSB7CiAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDU7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBmaWVsZE1hc2tGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGdldEZpZWxkTWFza0ZpZWxkKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1KSB7CiAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrKSBvbmVvZkZpZWxkXzsKICAgIH0KICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXIgZ2V0RmllbGRNYXNrRmllbGRPckJ1aWxkZXIoKSB7CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDUpIHsKICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2spIG9uZW9mRmllbGRfOwogICAgfQogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09VUkNFX0NPTlRFWFRfRklFTERfRklFTERfTlVNQkVSID0gNjsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNvdXJjZUNvbnRleHRGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc1NvdXJjZUNvbnRleHRGaWVsZCgpIHsKICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gNjsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgc291cmNlQ29udGV4dEZpZWxkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IGdldFNvdXJjZUNvbnRleHRGaWVsZCgpIHsKICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNikgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQpIG9uZW9mRmllbGRfOwogICAgfQogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHRPckJ1aWxkZXIgZ2V0U291cmNlQ29udGV4dEZpZWxkT3JCdWlsZGVyKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA2KSB7CiAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCkgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSVUNUX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDc7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJ1Y3RGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc1N0cnVjdEZpZWxkKCkgewogICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSA3OwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBzdHJ1Y3RGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IGdldFN0cnVjdEZpZWxkKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA3KSB7CiAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0KSBvbmVvZkZpZWxkXzsKICAgIH0KICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdE9yQnVpbGRlciBnZXRTdHJ1Y3RGaWVsZE9yQnVpbGRlcigpIHsKICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNykgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCkgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUSU1FU1RBTVBfRklFTERfRklFTERfTlVNQkVSID0gODsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHRpbWVzdGFtcEZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzVGltZXN0YW1wRmllbGQoKSB7CiAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDg7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHRpbWVzdGFtcEZpZWxkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgZ2V0VGltZXN0YW1wRmllbGQoKSB7CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDgpIHsKICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXApIG9uZW9mRmllbGRfOwogICAgfQogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wT3JCdWlsZGVyIGdldFRpbWVzdGFtcEZpZWxkT3JCdWlsZGVyKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA4KSB7CiAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wKSBvbmVvZkZpZWxkXzsKICAgIH0KICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfRklFTERfRklFTERfTlVNQkVSID0gOTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgdHlwZUZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzVHlwZUZpZWxkKCkgewogICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSA5OwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHR5cGVGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZSBnZXRUeXBlRmllbGQoKSB7CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDkpIHsKICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlKSBvbmVvZkZpZWxkXzsKICAgIH0KICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGVPckJ1aWxkZXIgZ2V0VHlwZUZpZWxkT3JCdWlsZGVyKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA5KSB7CiAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuVHlwZSkgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRE9VQkxFX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgZG91YmxlRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNEb3VibGVGaWVsZCgpIHsKICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTA7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGRvdWJsZUZpZWxkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBnZXREb3VibGVGaWVsZCgpIHsKICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTApIHsKICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlT3JCdWlsZGVyIGdldERvdWJsZUZpZWxkT3JCdWlsZGVyKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMCkgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlKSBvbmVvZkZpZWxkXzsKICAgIH0KICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRkxPQVRfRklFTERfRklFTERfTlVNQkVSID0gMTE7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmxvYXRGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc0Zsb2F0RmllbGQoKSB7CiAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgZmxvYXRGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBnZXRGbG9hdEZpZWxkKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMSkgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUpIG9uZW9mRmllbGRfOwogICAgfQogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlT3JCdWlsZGVyIGdldEZsb2F0RmllbGRPckJ1aWxkZXIoKSB7CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExKSB7CiAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UNjRfRklFTERfRklFTERfTlVNQkVSID0gMTI7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50NjRGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc0ludDY0RmllbGQoKSB7CiAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDEyOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgaW50NjRGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBnZXRJbnQ2NEZpZWxkKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMikgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUpIG9uZW9mRmllbGRfOwogICAgfQogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyIGdldEludDY0RmllbGRPckJ1aWxkZXIoKSB7CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEyKSB7CiAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVUlOVDY0X0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDEzOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgdWludDY0RmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNVaW50NjRGaWVsZCgpIHsKICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTM7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHVpbnQ2NEZpZWxkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBnZXRVaW50NjRGaWVsZCgpIHsKICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTMpIHsKICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlT3JCdWlsZGVyIGdldFVpbnQ2NEZpZWxkT3JCdWlsZGVyKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMykgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlKSBvbmVvZkZpZWxkXzsKICAgIH0KICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfRklFTERfRklFTERfTlVNQkVSID0gMTQ7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50MzJGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc0ludDMyRmllbGQoKSB7CiAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDE0OwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgaW50MzJGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBnZXRJbnQzMkZpZWxkKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNCkgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUpIG9uZW9mRmllbGRfOwogICAgfQogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlT3JCdWlsZGVyIGdldEludDMyRmllbGRPckJ1aWxkZXIoKSB7CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE0KSB7CiAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVUlOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE1OwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgdWludDMyRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNVaW50MzJGaWVsZCgpIHsKICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTU7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHVpbnQzMkZpZWxkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBnZXRVaW50MzJGaWVsZCgpIHsKICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTUpIHsKICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlT3JCdWlsZGVyIGdldFVpbnQzMkZpZWxkT3JCdWlsZGVyKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNSkgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlKSBvbmVvZkZpZWxkXzsKICAgIH0KICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQk9PTF9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxNjsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgYm9vbEZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzQm9vbEZpZWxkKCkgewogICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxNjsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBib29sRmllbGQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBnZXRCb29sRmllbGQoKSB7CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE2KSB7CiAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlKSBvbmVvZkZpZWxkXzsKICAgIH0KICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlT3JCdWlsZGVyIGdldEJvb2xGaWVsZE9yQnVpbGRlcigpIHsKICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTYpIHsKICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUpIG9uZW9mRmllbGRfOwogICAgfQogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE3OwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyaW5nRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNTdHJpbmdGaWVsZCgpIHsKICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTc7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHN0cmluZ0ZpZWxkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBnZXRTdHJpbmdGaWVsZCgpIHsKICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTcpIHsKICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyIGdldFN0cmluZ0ZpZWxkT3JCdWlsZGVyKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNykgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlKSBvbmVvZkZpZWxkXzsKICAgIH0KICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQllURVNfRklFTERfRklFTERfTlVNQkVSID0gMTg7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgYnl0ZXNGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc0J5dGVzRmllbGQoKSB7CiAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDE4OwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgYnl0ZXNGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBnZXRCeXRlc0ZpZWxkKCkgewogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxOCkgewogICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUpIG9uZW9mRmllbGRfOwogICAgfQogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyIGdldEJ5dGVzRmllbGRPckJ1aWxkZXIoKSB7CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE4KSB7CiAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICB9CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogIH0KCiAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEpIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCAoY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkpIG9uZW9mRmllbGRfKTsKICAgIH0KICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMikgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIsIChjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSkgb25lb2ZGaWVsZF8pOwogICAgfQogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAzKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMywgKGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24pIG9uZW9mRmllbGRfKTsKICAgIH0KICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNCkgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDQsIChjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5KSBvbmVvZkZpZWxkXyk7CiAgICB9CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDUpIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg1LCAoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2spIG9uZW9mRmllbGRfKTsKICAgIH0KICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNikgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDYsIChjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQpIG9uZW9mRmllbGRfKTsKICAgIH0KICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNykgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDcsIChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCkgb25lb2ZGaWVsZF8pOwogICAgfQogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA4KSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoOCwgKGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wKSBvbmVvZkZpZWxkXyk7CiAgICB9CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDkpIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg5LCAoY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlKSBvbmVvZkZpZWxkXyk7CiAgICB9CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEwKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTAsIChjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlKSBvbmVvZkZpZWxkXyk7CiAgICB9CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTEsIChjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUpIG9uZW9mRmllbGRfKTsKICAgIH0KICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTIpIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxMiwgKGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSkgb25lb2ZGaWVsZF8pOwogICAgfQogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMykgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEzLCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSkgb25lb2ZGaWVsZF8pOwogICAgfQogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNCkgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDE0LCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlKSBvbmVvZkZpZWxkXyk7CiAgICB9CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE1KSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTUsIChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlKSBvbmVvZkZpZWxkXyk7CiAgICB9CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE2KSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTYsIChjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSkgb25lb2ZGaWVsZF8pOwogICAgfQogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNykgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDE3LCAoY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSkgb25lb2ZGaWVsZF8pOwogICAgfQogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxOCkgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDE4LCAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlKSBvbmVvZkZpZWxkXyk7CiAgICB9CiAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICBzaXplID0gMDsKICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIChjb20uZ29vZ2xlLnByb3RvYnVmLkFueSkgb25lb2ZGaWVsZF8pOwogICAgfQogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAyKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgKGNvbS5nb29nbGUucHJvdG9idWYuQXBpKSBvbmVvZkZpZWxkXyk7CiAgICB9CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDMpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzLCAoY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbikgb25lb2ZGaWVsZF8pOwogICAgfQogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA0KSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgKGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkpIG9uZW9mRmllbGRfKTsKICAgIH0KICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIChjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaykgb25lb2ZGaWVsZF8pOwogICAgfQogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA2KSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNiwgKGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCkgb25lb2ZGaWVsZF8pOwogICAgfQogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA3KSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNywgKGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0KSBvbmVvZkZpZWxkXyk7CiAgICB9CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDgpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4LCAoY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXApIG9uZW9mRmllbGRfKTsKICAgIH0KICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gOSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDksIChjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUpIG9uZW9mRmllbGRfKTsKICAgIH0KICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTApIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgKGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUpIG9uZW9mRmllbGRfKTsKICAgIH0KICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMSwgKGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSkgb25lb2ZGaWVsZF8pOwogICAgfQogICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMikgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyLCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlKSBvbmVvZkZpZWxkXyk7CiAgICB9CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEzKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTMsIChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlKSBvbmVvZkZpZWxkXyk7CiAgICB9CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE0KSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQsIChjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUpIG9uZW9mRmllbGRfKTsKICAgIH0KICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTUpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNSwgKGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUpIG9uZW9mRmllbGRfKTsKICAgIH0KICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTYpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNiwgKGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlKSBvbmVvZkZpZWxkXyk7CiAgICB9CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE3KSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTcsIChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlKSBvbmVvZkZpZWxkXyk7CiAgICB9CiAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE4KSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgsIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUpIG9uZW9mRmllbGRfKTsKICAgIH0KICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgcmV0dXJuIHNpemU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5PbmVvZldlbGxLbm93blR5cGVzKSkgewogICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICB9CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuT25lb2ZXZWxsS25vd25UeXBlcyBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuT25lb2ZXZWxsS25vd25UeXBlcykgb2JqOwoKICAgIGlmICghZ2V0T25lb2ZGaWVsZENhc2UoKS5lcXVhbHMob3RoZXIuZ2V0T25lb2ZGaWVsZENhc2UoKSkpIHJldHVybiBmYWxzZTsKICAgIHN3aXRjaCAob25lb2ZGaWVsZENhc2VfKSB7CiAgICAgIGNhc2UgMToKICAgICAgICBpZiAoIWdldEFueUZpZWxkKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRBbnlGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDI6CiAgICAgICAgaWYgKCFnZXRBcGlGaWVsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0QXBpRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAzOgogICAgICAgIGlmICghZ2V0RHVyYXRpb25GaWVsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RHVyYXRpb25GaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDQ6CiAgICAgICAgaWYgKCFnZXRFbXB0eUZpZWxkKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRFbXB0eUZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgNToKICAgICAgICBpZiAoIWdldEZpZWxkTWFza0ZpZWxkKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZE1hc2tGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDY6CiAgICAgICAgaWYgKCFnZXRTb3VyY2VDb250ZXh0RmllbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFNvdXJjZUNvbnRleHRGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDc6CiAgICAgICAgaWYgKCFnZXRTdHJ1Y3RGaWVsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RydWN0RmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSA4OgogICAgICAgIGlmICghZ2V0VGltZXN0YW1wRmllbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFRpbWVzdGFtcEZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgOToKICAgICAgICBpZiAoIWdldFR5cGVGaWVsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0VHlwZUZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMTA6CiAgICAgICAgaWYgKCFnZXREb3VibGVGaWVsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RG91YmxlRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAxMToKICAgICAgICBpZiAoIWdldEZsb2F0RmllbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZsb2F0RmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAxMjoKICAgICAgICBpZiAoIWdldEludDY0RmllbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEludDY0RmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAxMzoKICAgICAgICBpZiAoIWdldFVpbnQ2NEZpZWxkKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRVaW50NjRGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDE0OgogICAgICAgIGlmICghZ2V0SW50MzJGaWVsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0SW50MzJGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDE1OgogICAgICAgIGlmICghZ2V0VWludDMyRmllbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFVpbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMTY6CiAgICAgICAgaWYgKCFnZXRCb29sRmllbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEJvb2xGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDE3OgogICAgICAgIGlmICghZ2V0U3RyaW5nRmllbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFN0cmluZ0ZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMTg6CiAgICAgICAgaWYgKCFnZXRCeXRlc0ZpZWxkKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRCeXRlc0ZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMDoKICAgICAgZGVmYXVsdDoKICAgIH0KICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgIH0KICAgIGludCBoYXNoID0gNDE7CiAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgIHN3aXRjaCAob25lb2ZGaWVsZENhc2VfKSB7CiAgICAgIGNhc2UgMToKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBBTllfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEFueUZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAyOgogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFQSV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QXBpRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDM6CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVSQVRJT05fRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldER1cmF0aW9uRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDQ6CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRU1QVFlfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEVtcHR5RmllbGQoKS5oYXNoQ29kZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDU6CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFTS19GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGRNYXNrRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDY6CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU09VUkNFX0NPTlRFWFRfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFNvdXJjZUNvbnRleHRGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgNzoKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFJVQ1RfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cnVjdEZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSA4OgogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFRJTUVTVEFNUF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VGltZXN0YW1wRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDk6CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVFlQRV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VHlwZUZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAxMDoKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBET1VCTEVfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldERvdWJsZUZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAxMToKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGTE9BVF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmxvYXRGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMTI6CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UNjRfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEludDY0RmllbGQoKS5oYXNoQ29kZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDEzOgogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVJTlQ2NF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VWludDY0RmllbGQoKS5oYXNoQ29kZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDE0OgogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRJbnQzMkZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAxNToKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVSU5UMzJfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFVpbnQzMkZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAxNjoKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCT09MX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCb29sRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDE3OgogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyaW5nRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDE4OgogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEJZVEVTX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCeXRlc0ZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAwOgogICAgICBkZWZhdWx0OgogICAgfQogICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgIHJldHVybiBoYXNoOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuT25lb2ZXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5PbmVvZldlbGxLbm93blR5cGVzIHBhcnNlRnJvbSgKICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuT25lb2ZXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKAogICAgICBieXRlW10gZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuT25lb2ZXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuT25lb2ZXZWxsS25vd25UeXBlcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuT25lb2ZXZWxsS25vd25UeXBlcyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5PbmVvZldlbGxLbm93blR5cGVzIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICB9CiAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMgcHJvdG90eXBlKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICB9CiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICByZXR1cm4gYnVpbGRlcjsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuT25lb2ZXZWxsS25vd25UeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5PbmVvZldlbGxLbm93blR5cGVzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuT25lb2ZXZWxsS25vd25UeXBlc09yQnVpbGRlciB7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RXZWxsS25vd25UeXBlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT25lb2ZXZWxsS25vd25UeXBlc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbmVvZldlbGxLbm93blR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5PbmVvZldlbGxLbm93blR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuT25lb2ZXZWxsS25vd25UeXBlcy5uZXdCdWlsZGVyKCkKICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICB9CgogICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgYW55RmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIGlmIChhcGlGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgaWYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgZHVyYXRpb25GaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgaWYgKHN0cnVjdEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHN0cnVjdEZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICBpZiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgdGltZXN0YW1wRmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgdHlwZUZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICBpZiAoZG91YmxlRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgZG91YmxlRmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIGlmIChmbG9hdEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIGlmIChpbnQ2NEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIGlmICh1aW50NjRGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICB1aW50NjRGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgaW50MzJGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHVpbnQzMkZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICBpZiAoYm9vbEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIGJvb2xGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgaWYgKHN0cmluZ0ZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHN0cmluZ0ZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICBpZiAoYnl0ZXNGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBieXRlc0ZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbmVvZldlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5PbmVvZldlbGxLbm93blR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuT25lb2ZXZWxsS25vd25UeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMgYnVpbGQoKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5PbmVvZldlbGxLbm93blR5cGVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICB9CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5PbmVvZldlbGxLbm93blR5cGVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5PbmVvZldlbGxLbm93blR5cGVzKHRoaXMpOwogICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICBidWlsZFBhcnRpYWxPbmVvZnMocmVzdWx0KTsKICAgICAgb25CdWlsdCgpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5PbmVvZldlbGxLbm93blR5cGVzIHJlc3VsdCkgewogICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsT25lb2ZzKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5PbmVvZldlbGxLbm93blR5cGVzIHJlc3VsdCkgewogICAgICByZXN1bHQub25lb2ZGaWVsZENhc2VfID0gb25lb2ZGaWVsZENhc2VfOwogICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSB0aGlzLm9uZW9mRmllbGRfOwogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEgJiYKICAgICAgICAgIGFueUZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IGFueUZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDIgJiYKICAgICAgICAgIGFwaUZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IGFwaUZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDMgJiYKICAgICAgICAgIGR1cmF0aW9uRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRfID0gZHVyYXRpb25GaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA0ICYmCiAgICAgICAgICBlbXB0eUZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IGVtcHR5RmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNSAmJgogICAgICAgICAgZmllbGRNYXNrRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRfID0gZmllbGRNYXNrRmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNiAmJgogICAgICAgICAgc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA3ICYmCiAgICAgICAgICBzdHJ1Y3RGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSBzdHJ1Y3RGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA4ICYmCiAgICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA5ICYmCiAgICAgICAgICB0eXBlRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRfID0gdHlwZUZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEwICYmCiAgICAgICAgICBkb3VibGVGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSBkb3VibGVGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMSAmJgogICAgICAgICAgZmxvYXRGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSBmbG9hdEZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEyICYmCiAgICAgICAgICBpbnQ2NEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IGludDY0RmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTMgJiYKICAgICAgICAgIHVpbnQ2NEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IHVpbnQ2NEZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE0ICYmCiAgICAgICAgICBpbnQzMkZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IGludDMyRmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTUgJiYKICAgICAgICAgIHVpbnQzMkZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IHVpbnQzMkZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE2ICYmCiAgICAgICAgICBib29sRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRfID0gYm9vbEZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE3ICYmCiAgICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSBzdHJpbmdGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxOCAmJgogICAgICAgICAgYnl0ZXNGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSBieXRlc0ZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMpIHsKICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuT25lb2ZXZWxsS25vd25UeXBlcylvdGhlcik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuT25lb2ZXZWxsS25vd25UeXBlcyBvdGhlcikgewogICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICBzd2l0Y2ggKG90aGVyLmdldE9uZW9mRmllbGRDYXNlKCkpIHsKICAgICAgICBjYXNlIEFOWV9GSUVMRDogewogICAgICAgICAgbWVyZ2VBbnlGaWVsZChvdGhlci5nZXRBbnlGaWVsZCgpKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIEFQSV9GSUVMRDogewogICAgICAgICAgbWVyZ2VBcGlGaWVsZChvdGhlci5nZXRBcGlGaWVsZCgpKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIERVUkFUSU9OX0ZJRUxEOiB7CiAgICAgICAgICBtZXJnZUR1cmF0aW9uRmllbGQob3RoZXIuZ2V0RHVyYXRpb25GaWVsZCgpKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIEVNUFRZX0ZJRUxEOiB7CiAgICAgICAgICBtZXJnZUVtcHR5RmllbGQob3RoZXIuZ2V0RW1wdHlGaWVsZCgpKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIEZJRUxEX01BU0tfRklFTEQ6IHsKICAgICAgICAgIG1lcmdlRmllbGRNYXNrRmllbGQob3RoZXIuZ2V0RmllbGRNYXNrRmllbGQoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBTT1VSQ0VfQ09OVEVYVF9GSUVMRDogewogICAgICAgICAgbWVyZ2VTb3VyY2VDb250ZXh0RmllbGQob3RoZXIuZ2V0U291cmNlQ29udGV4dEZpZWxkKCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgU1RSVUNUX0ZJRUxEOiB7CiAgICAgICAgICBtZXJnZVN0cnVjdEZpZWxkKG90aGVyLmdldFN0cnVjdEZpZWxkKCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgVElNRVNUQU1QX0ZJRUxEOiB7CiAgICAgICAgICBtZXJnZVRpbWVzdGFtcEZpZWxkKG90aGVyLmdldFRpbWVzdGFtcEZpZWxkKCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgVFlQRV9GSUVMRDogewogICAgICAgICAgbWVyZ2VUeXBlRmllbGQob3RoZXIuZ2V0VHlwZUZpZWxkKCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgRE9VQkxFX0ZJRUxEOiB7CiAgICAgICAgICBtZXJnZURvdWJsZUZpZWxkKG90aGVyLmdldERvdWJsZUZpZWxkKCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgRkxPQVRfRklFTEQ6IHsKICAgICAgICAgIG1lcmdlRmxvYXRGaWVsZChvdGhlci5nZXRGbG9hdEZpZWxkKCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgSU5UNjRfRklFTEQ6IHsKICAgICAgICAgIG1lcmdlSW50NjRGaWVsZChvdGhlci5nZXRJbnQ2NEZpZWxkKCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgVUlOVDY0X0ZJRUxEOiB7CiAgICAgICAgICBtZXJnZVVpbnQ2NEZpZWxkKG90aGVyLmdldFVpbnQ2NEZpZWxkKCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgSU5UMzJfRklFTEQ6IHsKICAgICAgICAgIG1lcmdlSW50MzJGaWVsZChvdGhlci5nZXRJbnQzMkZpZWxkKCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgVUlOVDMyX0ZJRUxEOiB7CiAgICAgICAgICBtZXJnZVVpbnQzMkZpZWxkKG90aGVyLmdldFVpbnQzMkZpZWxkKCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgQk9PTF9GSUVMRDogewogICAgICAgICAgbWVyZ2VCb29sRmllbGQob3RoZXIuZ2V0Qm9vbEZpZWxkKCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgU1RSSU5HX0ZJRUxEOiB7CiAgICAgICAgICBtZXJnZVN0cmluZ0ZpZWxkKG90aGVyLmdldFN0cmluZ0ZpZWxkKCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgQllURVNfRklFTEQ6IHsKICAgICAgICAgIG1lcmdlQnl0ZXNGaWVsZChvdGhlci5nZXRCeXRlc0ZpZWxkKCkpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgT05FT0ZGSUVMRF9OT1RfU0VUOiB7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgfQogICAgICB0cnkgewogICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBnZXRBbnlGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldEFwaUZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMjsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0RHVyYXRpb25GaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDM7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldEVtcHR5RmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA0OwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBnZXRGaWVsZE1hc2tGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDU7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSA0MgogICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldFNvdXJjZUNvbnRleHRGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDY7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSA1MAogICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldFN0cnVjdEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gNzsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDU4CiAgICAgICAgICAgIGNhc2UgNjY6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0VGltZXN0YW1wRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA4OwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNjYKICAgICAgICAgICAgY2FzZSA3NDogewogICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBnZXRUeXBlRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA5OwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBnZXREb3VibGVGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDEwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgY2FzZSA5MDogewogICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBnZXRGbG9hdEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTE7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICBjYXNlIDk4OiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldEludDY0RmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMjsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDk4CiAgICAgICAgICAgIGNhc2UgMTA2OiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldFVpbnQ2NEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTM7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMDYKICAgICAgICAgICAgY2FzZSAxMTQ6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0SW50MzJGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE0OwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMTE0CiAgICAgICAgICAgIGNhc2UgMTIyOiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldFVpbnQzMkZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTU7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMjIKICAgICAgICAgICAgY2FzZSAxMzA6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0Qm9vbEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTY7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMzAKICAgICAgICAgICAgY2FzZSAxMzg6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0U3RyaW5nRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNzsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDEzOAogICAgICAgICAgICBjYXNlIDE0NjogewogICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBnZXRCeXRlc0ZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTg7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxNDYKICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSAvLyBmaW5hbGx5CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgcHJpdmF0ZSBpbnQgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBvbmVvZkZpZWxkXzsKICAgIHB1YmxpYyBPbmVvZkZpZWxkQ2FzZQogICAgICAgIGdldE9uZW9mRmllbGRDYXNlKCkgewogICAgICByZXR1cm4gT25lb2ZGaWVsZENhc2UuZm9yTnVtYmVyKAogICAgICAgICAgb25lb2ZGaWVsZENhc2VfKTsKICAgIH0KCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mRmllbGQoKSB7CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4gYW55RmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGFueUZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQW55RmllbGQoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhbnlGaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGdldEFueUZpZWxkKCkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxKSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQW55KSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQW55LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMSkgewogICAgICAgICAgcmV0dXJuIGFueUZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldEFueUZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlKSB7CiAgICAgIGlmIChhbnlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYW55RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldEFueUZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChhbnlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBvbmVvZkZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGFueUZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUFueUZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlKSB7CiAgICAgIGlmIChhbnlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEgJiYKICAgICAgICAgICAgb25lb2ZGaWVsZF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkubmV3QnVpbGRlcigoY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkpIG9uZW9mRmllbGRfKQogICAgICAgICAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEpIHsKICAgICAgICAgIGFueUZpZWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYW55RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckFueUZpZWxkKCkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxKSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMSkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgYW55RmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIgZ2V0QW55RmllbGRCdWlsZGVyKCkgewogICAgICByZXR1cm4gZ2V0QW55RmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIgZ2V0QW55RmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmICgob25lb2ZGaWVsZENhc2VfID09IDEpICYmIChhbnlGaWVsZEJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgcmV0dXJuIGFueUZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMSkgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkFueSkgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0QW55RmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChhbnlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoIShvbmVvZkZpZWxkQ2FzZV8gPT0gMSkpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICAgIGFueUZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnksIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55T3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkFueSkgb25lb2ZGaWVsZF8sCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBhbnlGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXI+IGFwaUZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhcGlGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0FwaUZpZWxkKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDI7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYXBpRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSBnZXRBcGlGaWVsZCgpIHsKICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMikgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSkgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDIpIHsKICAgICAgICAgIHJldHVybiBhcGlGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRBcGlGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSB2YWx1ZSkgewogICAgICBpZiAoYXBpRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGFwaUZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMjsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRBcGlGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoYXBpRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDI7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VBcGlGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSB2YWx1ZSkgewogICAgICBpZiAoYXBpRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAyICYmCiAgICAgICAgICAgIG9uZW9mRmllbGRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuQXBpLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQXBpLm5ld0J1aWxkZXIoKGNvbS5nb29nbGUucHJvdG9idWYuQXBpKSBvbmVvZkZpZWxkXykKICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAyKSB7CiAgICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGFwaUZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDI7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBcGlGaWVsZCgpIHsKICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMikgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDIpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGFwaUZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5CdWlsZGVyIGdldEFwaUZpZWxkQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGdldEFwaUZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQXBpT3JCdWlsZGVyIGdldEFwaUZpZWxkT3JCdWlsZGVyKCkgewogICAgICBpZiAoKG9uZW9mRmllbGRDYXNlXyA9PSAyKSAmJiAoYXBpRmllbGRCdWlsZGVyXyAhPSBudWxsKSkgewogICAgICAgIHJldHVybiBhcGlGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDIpIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXI+IAogICAgICAgIGdldEFwaUZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoYXBpRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCEob25lb2ZGaWVsZENhc2VfID09IDIpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQXBpLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkpIG9uZW9mRmllbGRfLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDI7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gYXBpRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyPiBkdXJhdGlvbkZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVyYXRpb25GaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0R1cmF0aW9uRmllbGQoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVyYXRpb25GaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZ2V0RHVyYXRpb25GaWVsZCgpIHsKICAgICAgaWYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAzKSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24pIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDMpIHsKICAgICAgICAgIHJldHVybiBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldER1cmF0aW9uRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiB2YWx1ZSkgewogICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZHVyYXRpb25GaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDM7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldER1cmF0aW9uRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBvbmVvZkZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGR1cmF0aW9uRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAzOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUR1cmF0aW9uRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiB2YWx1ZSkgewogICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDMgJiYKICAgICAgICAgICAgb25lb2ZGaWVsZF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLm5ld0J1aWxkZXIoKGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24pIG9uZW9mRmllbGRfKQogICAgICAgICAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDMpIHsKICAgICAgICAgIGR1cmF0aW9uRmllbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDM7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRHVyYXRpb25GaWVsZCgpIHsKICAgICAgaWYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAzKSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMykgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZHVyYXRpb25GaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24uQnVpbGRlciBnZXREdXJhdGlvbkZpZWxkQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGdldER1cmF0aW9uRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25PckJ1aWxkZXIgZ2V0RHVyYXRpb25GaWVsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKChvbmVvZkZpZWxkQ2FzZV8gPT0gMykgJiYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXyAhPSBudWxsKSkgewogICAgICAgIHJldHVybiBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMykgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uKSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyPiAKICAgICAgICBnZXREdXJhdGlvbkZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoIShvbmVvZkZpZWxkQ2FzZV8gPT0gMykpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgICAgZHVyYXRpb25GaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24sIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24uQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbk9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbikgb25lb2ZGaWVsZF8sCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMzsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBkdXJhdGlvbkZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHksIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eU9yQnVpbGRlcj4gZW1wdHlGaWVsZEJ1aWxkZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGVtcHR5RmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNFbXB0eUZpZWxkKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDQ7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGVtcHR5RmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGdldEVtcHR5RmllbGQoKSB7CiAgICAgIGlmIChlbXB0eUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNCkgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5KSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA0KSB7CiAgICAgICAgICByZXR1cm4gZW1wdHlGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRFbXB0eUZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgdmFsdWUpIHsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGVtcHR5RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA0OwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRFbXB0eUZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBlbXB0eUZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gNDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VFbXB0eUZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgdmFsdWUpIHsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA0ICYmCiAgICAgICAgICAgIG9uZW9mRmllbGRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eS5uZXdCdWlsZGVyKChjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5KSBvbmVvZkZpZWxkXykKICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA0KSB7CiAgICAgICAgICBlbXB0eUZpZWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA0OwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckVtcHR5RmllbGQoKSB7CiAgICAgIGlmIChlbXB0eUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNCkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDQpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGVtcHR5RmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LkJ1aWxkZXIgZ2V0RW1wdHlGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRFbXB0eUZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5T3JCdWlsZGVyIGdldEVtcHR5RmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmICgob25lb2ZGaWVsZENhc2VfID09IDQpICYmIChlbXB0eUZpZWxkQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICByZXR1cm4gZW1wdHlGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDQpIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSkgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHksIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0RW1wdHlGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCEob25lb2ZGaWVsZENhc2VfID09IDQpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICAgIGVtcHR5RmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHlPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkpIG9uZW9mRmllbGRfLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDQ7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZW1wdHlGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaywgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2suQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXI+IGZpZWxkTWFza0ZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRNYXNrRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZE1hc2tGaWVsZCgpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSA1OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE1hc2tGaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGdldEZpZWxkTWFza0ZpZWxkKCkgewogICAgICBpZiAoZmllbGRNYXNrRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1KSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrKSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNSkgewogICAgICAgICAgcmV0dXJuIGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2suZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZE1hc2tGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayB2YWx1ZSkgewogICAgICBpZiAoZmllbGRNYXNrRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gNTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRNYXNrRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2suQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIG9uZW9mRmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmllbGRNYXNrRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA1OwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZpZWxkTWFza0ZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIHZhbHVlKSB7CiAgICAgIGlmIChmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDUgJiYKICAgICAgICAgICAgb25lb2ZGaWVsZF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2suZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2submV3QnVpbGRlcigoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2spIG9uZW9mRmllbGRfKQogICAgICAgICAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDUpIHsKICAgICAgICAgIGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmllbGRNYXNrRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gNTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE1hc2tGaWVsZCgpIHsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNSkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDUpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2suQnVpbGRlciBnZXRGaWVsZE1hc2tGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRGaWVsZE1hc2tGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXIgZ2V0RmllbGRNYXNrRmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmICgob25lb2ZGaWVsZENhc2VfID09IDUpICYmIChmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNSkgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaykgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaywgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2suQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXI+IAogICAgICAgIGdldEZpZWxkTWFza0ZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoZmllbGRNYXNrRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCEob25lb2ZGaWVsZENhc2VfID09IDUpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgICBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2spIG9uZW9mRmllbGRfLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDU7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZmllbGRNYXNrRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyPiBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNvdXJjZUNvbnRleHRGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1NvdXJjZUNvbnRleHRGaWVsZCgpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSA2OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHNvdXJjZUNvbnRleHRGaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBnZXRTb3VyY2VDb250ZXh0RmllbGQoKSB7CiAgICAgIGlmIChzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA2KSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCkgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA2KSB7CiAgICAgICAgICByZXR1cm4gc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRTb3VyY2VDb250ZXh0RmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHZhbHVlKSB7CiAgICAgIGlmIChzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDY7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0U291cmNlQ29udGV4dEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIG9uZW9mRmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gNjsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVNvdXJjZUNvbnRleHRGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgdmFsdWUpIHsKICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDYgJiYKICAgICAgICAgICAgb25lb2ZGaWVsZF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5uZXdCdWlsZGVyKChjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQpIG9uZW9mRmllbGRfKQogICAgICAgICAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDYpIHsKICAgICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA2OwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU291cmNlQ29udGV4dEZpZWxkKCkgewogICAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNikgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDYpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LkJ1aWxkZXIgZ2V0U291cmNlQ29udGV4dEZpZWxkQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGdldFNvdXJjZUNvbnRleHRGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHRPckJ1aWxkZXIgZ2V0U291cmNlQ29udGV4dEZpZWxkT3JCdWlsZGVyKCkgewogICAgICBpZiAoKG9uZW9mRmllbGRDYXNlXyA9PSA2KSAmJiAoc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICByZXR1cm4gc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNikgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyPiAKICAgICAgICBnZXRTb3VyY2VDb250ZXh0RmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCEob25lb2ZGaWVsZENhc2VfID09IDYpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQpIG9uZW9mRmllbGRfLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDY7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0LCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdE9yQnVpbGRlcj4gc3RydWN0RmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cnVjdEZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RydWN0RmllbGQoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gNzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHJ1Y3RGaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IGdldFN0cnVjdEZpZWxkKCkgewogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA3KSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0KSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNykgewogICAgICAgICAgcmV0dXJuIHN0cnVjdEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cnVjdEZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IHZhbHVlKSB7CiAgICAgIGlmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RydWN0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA3OwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cnVjdEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBvbmVvZkZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHN0cnVjdEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gNzsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVN0cnVjdEZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IHZhbHVlKSB7CiAgICAgIGlmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDcgJiYKICAgICAgICAgICAgb25lb2ZGaWVsZF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QubmV3QnVpbGRlcigoY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QpIG9uZW9mRmllbGRfKQogICAgICAgICAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDcpIHsKICAgICAgICAgIHN0cnVjdEZpZWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3RydWN0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gNzsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cnVjdEZpZWxkKCkgewogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA3KSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNykgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgc3RydWN0RmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0LkJ1aWxkZXIgZ2V0U3RydWN0RmllbGRCdWlsZGVyKCkgewogICAgICByZXR1cm4gZ2V0U3RydWN0RmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RPckJ1aWxkZXIgZ2V0U3RydWN0RmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmICgob25lb2ZGaWVsZENhc2VfID09IDcpICYmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgcmV0dXJuIHN0cnVjdEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNykgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCkgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0LCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdE9yQnVpbGRlcj4gCiAgICAgICAgZ2V0U3RydWN0RmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoIShvbmVvZkZpZWxkQ2FzZV8gPT0gNykpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICAgIHN0cnVjdEZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0T3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCkgb25lb2ZGaWVsZF8sCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gNzsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBzdHJ1Y3RGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBPckJ1aWxkZXI+IHRpbWVzdGFtcEZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB0aW1lc3RhbXBGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1RpbWVzdGFtcEZpZWxkKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDg7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdGltZXN0YW1wRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBnZXRUaW1lc3RhbXBGaWVsZCgpIHsKICAgICAgaWYgKHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gOCkgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCkgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDgpIHsKICAgICAgICAgIHJldHVybiB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRUaW1lc3RhbXBGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB2YWx1ZSkgewogICAgICBpZiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gODsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRUaW1lc3RhbXBGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDg7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VUaW1lc3RhbXBGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB2YWx1ZSkgewogICAgICBpZiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA4ICYmCiAgICAgICAgICAgIG9uZW9mRmllbGRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLm5ld0J1aWxkZXIoKGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wKSBvbmVvZkZpZWxkXykKICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA4KSB7CiAgICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDg7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJUaW1lc3RhbXBGaWVsZCgpIHsKICAgICAgaWYgKHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gOCkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDgpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5CdWlsZGVyIGdldFRpbWVzdGFtcEZpZWxkQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGdldFRpbWVzdGFtcEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wT3JCdWlsZGVyIGdldFRpbWVzdGFtcEZpZWxkT3JCdWlsZGVyKCkgewogICAgICBpZiAoKG9uZW9mRmllbGRDYXNlXyA9PSA4KSAmJiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyAhPSBudWxsKSkgewogICAgICAgIHJldHVybiB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDgpIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXApIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBPckJ1aWxkZXI+IAogICAgICAgIGdldFRpbWVzdGFtcEZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCEob25lb2ZGaWVsZENhc2VfID09IDgpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcE9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXApIG9uZW9mRmllbGRfLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDg7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGltZXN0YW1wRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlT3JCdWlsZGVyPiB0eXBlRmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdHlwZUZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzVHlwZUZpZWxkKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSB0eXBlRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUgZ2V0VHlwZUZpZWxkKCkgewogICAgICBpZiAodHlwZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gOSkgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gOSkgewogICAgICAgICAgcmV0dXJuIHR5cGVGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRUeXBlRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHZhbHVlKSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHR5cGVGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRUeXBlRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0eXBlRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA5OwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VUeXBlRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHZhbHVlKSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA5ICYmCiAgICAgICAgICAgIG9uZW9mRmllbGRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuVHlwZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUubmV3QnVpbGRlcigoY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlKSBvbmVvZkZpZWxkXykKICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA5KSB7CiAgICAgICAgICB0eXBlRmllbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0eXBlRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gOTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVHlwZUZpZWxkKCkgewogICAgICBpZiAodHlwZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gOSkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDkpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHR5cGVGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUuQnVpbGRlciBnZXRUeXBlRmllbGRCdWlsZGVyKCkgewogICAgICByZXR1cm4gZ2V0VHlwZUZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlT3JCdWlsZGVyIGdldFR5cGVGaWVsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKChvbmVvZkZpZWxkQ2FzZV8gPT0gOSkgJiYgKHR5cGVGaWVsZEJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgcmV0dXJuIHR5cGVGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDkpIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlKSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlT3JCdWlsZGVyPiAKICAgICAgICBnZXRUeXBlRmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCEob25lb2ZGaWVsZENhc2VfID09IDkpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuVHlwZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgICAgdHlwZUZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUpIG9uZW9mRmllbGRfLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDk7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdHlwZUZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZU9yQnVpbGRlcj4gZG91YmxlRmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRvdWJsZUZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRG91YmxlRmllbGQoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTA7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZG91YmxlRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGdldERvdWJsZUZpZWxkKCkgewogICAgICBpZiAoZG91YmxlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMCkgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlKSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMCkgewogICAgICAgICAgcmV0dXJuIGRvdWJsZUZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0RG91YmxlRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoZG91YmxlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGRvdWJsZUZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTA7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0RG91YmxlRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoZG91YmxlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkb3VibGVGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDEwOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRG91YmxlRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoZG91YmxlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMCAmJgogICAgICAgICAgICBvbmVvZkZpZWxkXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUubmV3QnVpbGRlcigoY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSkgb25lb2ZGaWVsZF8pCiAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTApIHsKICAgICAgICAgIGRvdWJsZUZpZWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZG91YmxlRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTA7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEb3VibGVGaWVsZCgpIHsKICAgICAgaWYgKGRvdWJsZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTApIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMCkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZG91YmxlRmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuQnVpbGRlciBnZXREb3VibGVGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXREb3VibGVGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlT3JCdWlsZGVyIGdldERvdWJsZUZpZWxkT3JCdWlsZGVyKCkgewogICAgICBpZiAoKG9uZW9mRmllbGRDYXNlXyA9PSAxMCkgJiYgKGRvdWJsZUZpZWxkQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICByZXR1cm4gZG91YmxlRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMCkgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlKSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWVPckJ1aWxkZXI+IAogICAgICAgIGdldERvdWJsZUZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoZG91YmxlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCEob25lb2ZGaWVsZENhc2VfID09IDEwKSkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgICBkb3VibGVGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSkgb25lb2ZGaWVsZF8sCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZG91YmxlRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlT3JCdWlsZGVyPiBmbG9hdEZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmxvYXRGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0Zsb2F0RmllbGQoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTE7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZsb2F0RmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZ2V0RmxvYXRGaWVsZCgpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMSkgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEpIHsKICAgICAgICAgIHJldHVybiBmbG9hdEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0RmxvYXRGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0RmxvYXRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBmbG9hdEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTE7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRmxvYXRGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMSAmJgogICAgICAgICAgICBvbmVvZkZpZWxkXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLm5ld0J1aWxkZXIoKGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSkgb25lb2ZGaWVsZF8pCiAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEpIHsKICAgICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmbG9hdEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZsb2F0RmllbGQoKSB7CiAgICAgIGlmIChmbG9hdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMSkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZmxvYXRGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5CdWlsZGVyIGdldEZsb2F0RmllbGRCdWlsZGVyKCkgewogICAgICByZXR1cm4gZ2V0RmxvYXRGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlT3JCdWlsZGVyIGdldEZsb2F0RmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmICgob25lb2ZGaWVsZENhc2VfID09IDExKSAmJiAoZmxvYXRGaWVsZEJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgcmV0dXJuIGZsb2F0RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMSkgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0RmxvYXRGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCEob25lb2ZGaWVsZENhc2VfID09IDExKSkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSkgb25lb2ZGaWVsZF8sCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTE7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZmxvYXRGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWVPckJ1aWxkZXI+IGludDY0RmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnQ2NEZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzSW50NjRGaWVsZCgpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMjsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50NjRGaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBnZXRJbnQ2NEZpZWxkKCkgewogICAgICBpZiAoaW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEyKSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMikgewogICAgICAgICAgcmV0dXJuIGludDY0RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRJbnQ2NEZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoaW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaW50NjRGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDEyOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRJbnQ2NEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoaW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBvbmVvZkZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMjsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VJbnQ2NEZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoaW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEyICYmCiAgICAgICAgICAgIG9uZW9mRmllbGRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUubmV3QnVpbGRlcigoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlKSBvbmVvZkZpZWxkXykKICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMikgewogICAgICAgICAgaW50NjRGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTI7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50NjRGaWVsZCgpIHsKICAgICAgaWYgKGludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMikgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEyKSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBpbnQ2NEZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLkJ1aWxkZXIgZ2V0SW50NjRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRJbnQ2NEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWVPckJ1aWxkZXIgZ2V0SW50NjRGaWVsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKChvbmVvZkZpZWxkQ2FzZV8gPT0gMTIpICYmIChpbnQ2NEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICByZXR1cm4gaW50NjRGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDEyKSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyPiAKICAgICAgICBnZXRJbnQ2NEZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoaW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoIShvbmVvZkZpZWxkQ2FzZV8gPT0gMTIpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgICAgaW50NjRGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlKSBvbmVvZkZpZWxkXywKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMjsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBpbnQ2NEZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZU9yQnVpbGRlcj4gdWludDY0RmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHVpbnQ2NEZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzVWludDY0RmllbGQoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdWludDY0RmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIGdldFVpbnQ2NEZpZWxkKCkgewogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMykgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlKSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMykgewogICAgICAgICAgcmV0dXJuIHVpbnQ2NEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0VWludDY0RmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHVpbnQ2NEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTM7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0VWludDY0RmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB1aW50NjRGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDEzOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlVWludDY0RmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMyAmJgogICAgICAgICAgICBvbmVvZkZpZWxkXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUubmV3QnVpbGRlcigoY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSkgb25lb2ZGaWVsZF8pCiAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTMpIHsKICAgICAgICAgIHVpbnQ2NEZpZWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdWludDY0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTM7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVaW50NjRGaWVsZCgpIHsKICAgICAgaWYgKHVpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTMpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMykgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgdWludDY0RmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuQnVpbGRlciBnZXRVaW50NjRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRVaW50NjRGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlT3JCdWlsZGVyIGdldFVpbnQ2NEZpZWxkT3JCdWlsZGVyKCkgewogICAgICBpZiAoKG9uZW9mRmllbGRDYXNlXyA9PSAxMykgJiYgKHVpbnQ2NEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICByZXR1cm4gdWludDY0RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMykgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlKSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXI+IAogICAgICAgIGdldFVpbnQ2NEZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCEob25lb2ZGaWVsZENhc2VfID09IDEzKSkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgICB1aW50NjRGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSkgb25lb2ZGaWVsZF8sCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTM7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdWludDY0RmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlT3JCdWlsZGVyPiBpbnQzMkZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50MzJGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ludDMyRmllbGQoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTQ7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGludDMyRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgZ2V0SW50MzJGaWVsZCgpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNCkgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTQpIHsKICAgICAgICAgIHJldHVybiBpbnQzMkZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0SW50MzJGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDMyRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNDsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0SW50MzJGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpbnQzMkZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTQ7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlSW50MzJGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNCAmJgogICAgICAgICAgICBvbmVvZkZpZWxkXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLm5ld0J1aWxkZXIoKGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSkgb25lb2ZGaWVsZF8pCiAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTQpIHsKICAgICAgICAgIGludDMyRmllbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpbnQzMkZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE0OwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludDMyRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTQpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNCkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgaW50MzJGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5CdWlsZGVyIGdldEludDMyRmllbGRCdWlsZGVyKCkgewogICAgICByZXR1cm4gZ2V0SW50MzJGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlT3JCdWlsZGVyIGdldEludDMyRmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmICgob25lb2ZGaWVsZENhc2VfID09IDE0KSAmJiAoaW50MzJGaWVsZEJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgcmV0dXJuIGludDMyRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNCkgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0SW50MzJGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCEob25lb2ZGaWVsZENhc2VfID09IDE0KSkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICAgIGludDMyRmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSkgb25lb2ZGaWVsZF8sCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTQ7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gaW50MzJGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWVPckJ1aWxkZXI+IHVpbnQzMkZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB1aW50MzJGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1VpbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDE1OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHVpbnQzMkZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBnZXRVaW50MzJGaWVsZCgpIHsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTUpIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTUpIHsKICAgICAgICAgIHJldHVybiB1aW50MzJGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFVpbnQzMkZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB1aW50MzJGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE1OwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFVpbnQzMkZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIG9uZW9mRmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdWludDMyRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVVpbnQzMkZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTUgJiYKICAgICAgICAgICAgb25lb2ZGaWVsZF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLm5ld0J1aWxkZXIoKGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUpIG9uZW9mRmllbGRfKQogICAgICAgICAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE1KSB7CiAgICAgICAgICB1aW50MzJGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHVpbnQzMkZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE1OwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVWludDMyRmllbGQoKSB7CiAgICAgIGlmICh1aW50MzJGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE1KSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTUpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHVpbnQzMkZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLkJ1aWxkZXIgZ2V0VWludDMyRmllbGRCdWlsZGVyKCkgewogICAgICByZXR1cm4gZ2V0VWludDMyRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZU9yQnVpbGRlciBnZXRVaW50MzJGaWVsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKChvbmVvZkZpZWxkQ2FzZV8gPT0gMTUpICYmICh1aW50MzJGaWVsZEJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgcmV0dXJuIHVpbnQzMkZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTUpIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlT3JCdWlsZGVyPiAKICAgICAgICBnZXRVaW50MzJGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICghKG9uZW9mRmllbGRDYXNlXyA9PSAxNSkpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgICAgdWludDMyRmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUpIG9uZW9mRmllbGRfLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE1OwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHVpbnQzMkZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlcj4gYm9vbEZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJvb2xGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0Jvb2xGaWVsZCgpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxNjsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJvb2xGaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGdldEJvb2xGaWVsZCgpIHsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE2KSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlKSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTYpIHsKICAgICAgICAgIHJldHVybiBib29sRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRCb29sRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTY7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRCb29sRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBvbmVvZkZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGJvb2xGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE2OwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VCb29sRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE2ICYmCiAgICAgICAgICAgIG9uZW9mRmllbGRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLm5ld0J1aWxkZXIoKGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlKSBvbmVvZkZpZWxkXykKICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNikgewogICAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE2OwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJCb29sRmllbGQoKSB7CiAgICAgIGlmIChib29sRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNikgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE2KSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBib29sRmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuQnVpbGRlciBnZXRCb29sRmllbGRCdWlsZGVyKCkgewogICAgICByZXR1cm4gZ2V0Qm9vbEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVPckJ1aWxkZXIgZ2V0Qm9vbEZpZWxkT3JCdWlsZGVyKCkgewogICAgICBpZiAoKG9uZW9mRmllbGRDYXNlXyA9PSAxNikgJiYgKGJvb2xGaWVsZEJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgcmV0dXJuIGJvb2xGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE2KSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlKSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVPckJ1aWxkZXI+IAogICAgICAgIGdldEJvb2xGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoIShvbmVvZkZpZWxkQ2FzZV8gPT0gMTYpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgICBib29sRmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlKSBvbmVvZkZpZWxkXywKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNjsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBib29sRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyPiBzdHJpbmdGaWVsZEJ1aWxkZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyaW5nRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHJpbmdGaWVsZCgpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxNzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmdGaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgZ2V0U3RyaW5nRmllbGQoKSB7CiAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE3KSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE3KSB7CiAgICAgICAgICByZXR1cm4gc3RyaW5nRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHJpbmdGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RyaW5nRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNzsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHJpbmdGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBvbmVvZkZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHN0cmluZ0ZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTc7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VTdHJpbmdGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE3ICYmCiAgICAgICAgICAgIG9uZW9mRmllbGRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5uZXdCdWlsZGVyKChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlKSBvbmVvZkZpZWxkXykKICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNykgewogICAgICAgICAgc3RyaW5nRmllbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNzsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZ0ZpZWxkKCkgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxNykgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE3KSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyIGdldFN0cmluZ0ZpZWxkQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGdldFN0cmluZ0ZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWVPckJ1aWxkZXIgZ2V0U3RyaW5nRmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmICgob25lb2ZGaWVsZENhc2VfID09IDE3KSAmJiAoc3RyaW5nRmllbGRCdWlsZGVyXyAhPSBudWxsKSkgewogICAgICAgIHJldHVybiBzdHJpbmdGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE3KSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0U3RyaW5nRmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoIShvbmVvZkZpZWxkQ2FzZV8gPT0gMTcpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICAgIHN0cmluZ0ZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlKSBvbmVvZkZpZWxkXywKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxNzsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBzdHJpbmdGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWVPckJ1aWxkZXI+IGJ5dGVzRmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBieXRlc0ZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQnl0ZXNGaWVsZCgpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxODsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXNGaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBnZXRCeXRlc0ZpZWxkKCkgewogICAgICBpZiAoYnl0ZXNGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE4KSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxOCkgewogICAgICAgICAgcmV0dXJuIGJ5dGVzRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRCeXRlc0ZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoYnl0ZXNGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnl0ZXNGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDE4OwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRCeXRlc0ZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoYnl0ZXNGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBvbmVvZkZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxODsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VCeXRlc0ZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoYnl0ZXNGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE4ICYmCiAgICAgICAgICAgIG9uZW9mRmllbGRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUubmV3QnVpbGRlcigoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlKSBvbmVvZkZpZWxkXykKICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxOCkgewogICAgICAgICAgYnl0ZXNGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTg7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQnl0ZXNGaWVsZCgpIHsKICAgICAgaWYgKGJ5dGVzRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxOCkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE4KSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBieXRlc0ZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLkJ1aWxkZXIgZ2V0Qnl0ZXNGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRCeXRlc0ZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWVPckJ1aWxkZXIgZ2V0Qnl0ZXNGaWVsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKChvbmVvZkZpZWxkQ2FzZV8gPT0gMTgpICYmIChieXRlc0ZpZWxkQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICByZXR1cm4gYnl0ZXNGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDE4KSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSkgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyPiAKICAgICAgICBnZXRCeXRlc0ZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoYnl0ZXNGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoIShvbmVvZkZpZWxkQ2FzZV8gPT0gMTgpKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgICAgYnl0ZXNGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlKSBvbmVvZkZpZWxkXywKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxODsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBieXRlc0ZpZWxkQnVpbGRlcl87CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgIH0KCgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuT25lb2ZXZWxsS25vd25UeXBlcykKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5PbmVvZldlbGxLbm93blR5cGVzKQogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5PbmVvZldlbGxLbm93blR5cGVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgc3RhdGljIHsKICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPbmVvZldlbGxLbm93blR5cGVzPgogICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxPbmVvZldlbGxLbm93blR5cGVzPigpIHsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBPbmVvZldlbGxLbm93blR5cGVzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgdHJ5IHsKICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9CiAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgfQogIH07CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T25lb2ZXZWxsS25vd25UeXBlcz4gcGFyc2VyKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T25lb2ZXZWxsS25vd25UeXBlcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgIHJldHVybiBQQVJTRVI7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5PbmVvZldlbGxLbm93blR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICB9Cgp9CgpQSwMECgAAAAAAAAAhAJQeWqueIQAAniEAADoAAABjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3QvT25lb2ZXZWxsS25vd25UeXBlc09yQnVpbGRlci5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfd2VsbF9rbm93bl90eXBlcy5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0OwoKcHVibGljIGludGVyZmFjZSBPbmVvZldlbGxLbm93blR5cGVzT3JCdWlsZGVyIGV4dGVuZHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5PbmVvZldlbGxLbm93blR5cGVzKQogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhbnlGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNBbnlGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGFueUZpZWxkLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGdldEFueUZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIgZ2V0QW55RmllbGRPckJ1aWxkZXIoKTsKCiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhcGlGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNBcGlGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGFwaUZpZWxkLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuQXBpIGdldEFwaUZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXIgZ2V0QXBpRmllbGRPckJ1aWxkZXIoKTsKCiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVyYXRpb25GaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNEdXJhdGlvbkZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGR1cmF0aW9uRmllbGQuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBnZXREdXJhdGlvbkZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25PckJ1aWxkZXIgZ2V0RHVyYXRpb25GaWVsZE9yQnVpbGRlcigpOwoKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBlbXB0eUZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc0VtcHR5RmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgZW1wdHlGaWVsZC4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGdldEVtcHR5RmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eU9yQnVpbGRlciBnZXRFbXB0eUZpZWxkT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTWFza0ZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc0ZpZWxkTWFza0ZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGZpZWxkTWFza0ZpZWxkLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGdldEZpZWxkTWFza0ZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrT3JCdWlsZGVyIGdldEZpZWxkTWFza0ZpZWxkT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgc291cmNlQ29udGV4dEZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc1NvdXJjZUNvbnRleHRGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHNvdXJjZUNvbnRleHRGaWVsZC4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgZ2V0U291cmNlQ29udGV4dEZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyIGdldFNvdXJjZUNvbnRleHRGaWVsZE9yQnVpbGRlcigpOwoKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cnVjdEZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc1N0cnVjdEZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgc3RydWN0RmllbGQuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QgZ2V0U3RydWN0RmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdE9yQnVpbGRlciBnZXRTdHJ1Y3RGaWVsZE9yQnVpbGRlcigpOwoKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHRpbWVzdGFtcEZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc1RpbWVzdGFtcEZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgdGltZXN0YW1wRmllbGQuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgZ2V0VGltZXN0YW1wRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcE9yQnVpbGRlciBnZXRUaW1lc3RhbXBGaWVsZE9yQnVpbGRlcigpOwoKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgdHlwZUZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc1R5cGVGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgdHlwZUZpZWxkLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZSBnZXRUeXBlRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZU9yQnVpbGRlciBnZXRUeXBlRmllbGRPckJ1aWxkZXIoKTsKCiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkb3VibGVGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNEb3VibGVGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGRvdWJsZUZpZWxkLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZ2V0RG91YmxlRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlT3JCdWlsZGVyIGdldERvdWJsZUZpZWxkT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZsb2F0RmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzRmxvYXRGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBmbG9hdEZpZWxkLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBnZXRGbG9hdEZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZU9yQnVpbGRlciBnZXRGbG9hdEZpZWxkT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludDY0RmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzSW50NjRGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBpbnQ2NEZpZWxkLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBnZXRJbnQ2NEZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZU9yQnVpbGRlciBnZXRJbnQ2NEZpZWxkT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgdWludDY0RmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzVWludDY0RmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSB1aW50NjRGaWVsZC4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIGdldFVpbnQ2NEZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZU9yQnVpbGRlciBnZXRVaW50NjRGaWVsZE9yQnVpbGRlcigpOwoKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnQzMkZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc0ludDMyRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgaW50MzJGaWVsZC4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgZ2V0SW50MzJGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWVPckJ1aWxkZXIgZ2V0SW50MzJGaWVsZE9yQnVpbGRlcigpOwoKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHVpbnQzMkZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc1VpbnQzMkZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgdWludDMyRmllbGQuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBnZXRVaW50MzJGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWVPckJ1aWxkZXIgZ2V0VWludDMyRmllbGRPckJ1aWxkZXIoKTsKCiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJvb2xGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNCb29sRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGJvb2xGaWVsZC4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBnZXRCb29sRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlT3JCdWlsZGVyIGdldEJvb2xGaWVsZE9yQnVpbGRlcigpOwoKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cmluZ0ZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc1N0cmluZ0ZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgc3RyaW5nRmllbGQuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBnZXRTdHJpbmdGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWVPckJ1aWxkZXIgZ2V0U3RyaW5nRmllbGRPckJ1aWxkZXIoKTsKCiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgYnl0ZXNGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNCeXRlc0ZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGJ5dGVzRmllbGQuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGdldEJ5dGVzRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyIGdldEJ5dGVzRmllbGRPckJ1aWxkZXIoKTsKCiAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0Lk9uZW9mV2VsbEtub3duVHlwZXMuT25lb2ZGaWVsZENhc2UgZ2V0T25lb2ZGaWVsZENhc2UoKTsKfQpQSwMECgAAAAAAAAAhAN+6z2AylQMAMpUDADQAAABjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3QvUmVwZWF0ZWRXZWxsS25vd25UeXBlcy5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfd2VsbF9rbm93bl90eXBlcy5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0OwoKLyoqCiAqIDxwcmU+CiAqIEEgcmVwZWF0ZWQgZmllbGQgZm9yIGVhY2ggd2VsbC1rbm93biB0eXBlLgogKiA8L3ByZT4KICoKICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuUmVwZWF0ZWRXZWxsS25vd25UeXBlc30KICovCnB1YmxpYyBmaW5hbCBjbGFzcyBSZXBlYXRlZFdlbGxLbm93blR5cGVzIGV4dGVuZHMKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuUmVwZWF0ZWRXZWxsS25vd25UeXBlcykKICAgIFJlcGVhdGVkV2VsbEtub3duVHlwZXNPckJ1aWxkZXIgewpwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAvLyBVc2UgUmVwZWF0ZWRXZWxsS25vd25UeXBlcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogIHByaXZhdGUgUmVwZWF0ZWRXZWxsS25vd25UeXBlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgIHN1cGVyKGJ1aWxkZXIpOwogIH0KICBwcml2YXRlIFJlcGVhdGVkV2VsbEtub3duVHlwZXMoKSB7CiAgICBhbnlGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICBhcGlGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICBkdXJhdGlvbkZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIGVtcHR5RmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgZmllbGRNYXNrRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgc291cmNlQ29udGV4dEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIHN0cnVjdEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIHRpbWVzdGFtcEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIHR5cGVGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICBkb3VibGVGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICBmbG9hdEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIGludDY0RmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgdWludDY0RmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgaW50MzJGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB1aW50MzJGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICBib29sRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgc3RyaW5nRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgYnl0ZXNGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgIHJldHVybiBuZXcgUmVwZWF0ZWRXZWxsS25vd25UeXBlcygpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RXZWxsS25vd25UeXBlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmVwZWF0ZWRXZWxsS25vd25UeXBlc19kZXNjcmlwdG9yOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0V2VsbEtub3duVHlwZXMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkV2VsbEtub3duVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuUmVwZWF0ZWRXZWxsS25vd25UeXBlcy5CdWlsZGVyLmNsYXNzKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFOWV9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxOwogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5Bbnk+IGFueUZpZWxkXzsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQW55PiBnZXRBbnlGaWVsZExpc3QoKSB7CiAgICByZXR1cm4gYW55RmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4gCiAgICAgIGdldEFueUZpZWxkT3JCdWlsZGVyTGlzdCgpIHsKICAgIHJldHVybiBhbnlGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldEFueUZpZWxkQ291bnQoKSB7CiAgICByZXR1cm4gYW55RmllbGRfLnNpemUoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSBnZXRBbnlGaWVsZChpbnQgaW5kZXgpIHsKICAgIHJldHVybiBhbnlGaWVsZF8uZ2V0KGluZGV4KTsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlciBnZXRBbnlGaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KSB7CiAgICByZXR1cm4gYW55RmllbGRfLmdldChpbmRleCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBUElfRklFTERfRklFTERfTlVNQkVSID0gMjsKICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQXBpPiBhcGlGaWVsZF87CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkFwaT4gZ2V0QXBpRmllbGRMaXN0KCkgewogICAgcmV0dXJuIGFwaUZpZWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXI+IAogICAgICBnZXRBcGlGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gYXBpRmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRBcGlGaWVsZENvdW50KCkgewogICAgcmV0dXJuIGFwaUZpZWxkXy5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkgZ2V0QXBpRmllbGQoaW50IGluZGV4KSB7CiAgICByZXR1cm4gYXBpRmllbGRfLmdldChpbmRleCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXIgZ2V0QXBpRmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCkgewogICAgcmV0dXJuIGFwaUZpZWxkXy5nZXQoaW5kZXgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVSQVRJT05fRklFTERfRklFTERfTlVNQkVSID0gMzsKICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24+IGR1cmF0aW9uRmllbGRfOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24+IGdldER1cmF0aW9uRmllbGRMaXN0KCkgewogICAgcmV0dXJuIGR1cmF0aW9uRmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbk9yQnVpbGRlcj4gCiAgICAgIGdldER1cmF0aW9uRmllbGRPckJ1aWxkZXJMaXN0KCkgewogICAgcmV0dXJuIGR1cmF0aW9uRmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgZ2V0RHVyYXRpb25GaWVsZENvdW50KCkgewogICAgcmV0dXJuIGR1cmF0aW9uRmllbGRfLnNpemUoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBnZXREdXJhdGlvbkZpZWxkKGludCBpbmRleCkgewogICAgcmV0dXJuIGR1cmF0aW9uRmllbGRfLmdldChpbmRleCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25PckJ1aWxkZXIgZ2V0RHVyYXRpb25GaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KSB7CiAgICByZXR1cm4gZHVyYXRpb25GaWVsZF8uZ2V0KGluZGV4KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVNUFRZX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDQ7CiAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PiBlbXB0eUZpZWxkXzsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PiBnZXRFbXB0eUZpZWxkTGlzdCgpIHsKICAgIHJldHVybiBlbXB0eUZpZWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHlPckJ1aWxkZXI+IAogICAgICBnZXRFbXB0eUZpZWxkT3JCdWlsZGVyTGlzdCgpIHsKICAgIHJldHVybiBlbXB0eUZpZWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldEVtcHR5RmllbGRDb3VudCgpIHsKICAgIHJldHVybiBlbXB0eUZpZWxkXy5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgZ2V0RW1wdHlGaWVsZChpbnQgaW5kZXgpIHsKICAgIHJldHVybiBlbXB0eUZpZWxkXy5nZXQoaW5kZXgpOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5T3JCdWlsZGVyIGdldEVtcHR5RmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCkgewogICAgcmV0dXJuIGVtcHR5RmllbGRfLmdldChpbmRleCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9NQVNLX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDU7CiAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaz4gZmllbGRNYXNrRmllbGRfOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrPiBnZXRGaWVsZE1hc2tGaWVsZExpc3QoKSB7CiAgICByZXR1cm4gZmllbGRNYXNrRmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXI+IAogICAgICBnZXRGaWVsZE1hc2tGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gZmllbGRNYXNrRmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgZ2V0RmllbGRNYXNrRmllbGRDb3VudCgpIHsKICAgIHJldHVybiBmaWVsZE1hc2tGaWVsZF8uc2l6ZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBnZXRGaWVsZE1hc2tGaWVsZChpbnQgaW5kZXgpIHsKICAgIHJldHVybiBmaWVsZE1hc2tGaWVsZF8uZ2V0KGluZGV4KTsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXIgZ2V0RmllbGRNYXNrRmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCkgewogICAgcmV0dXJuIGZpZWxkTWFza0ZpZWxkXy5nZXQoaW5kZXgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09VUkNFX0NPTlRFWFRfRklFTERfRklFTERfTlVNQkVSID0gNjsKICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dD4gc291cmNlQ29udGV4dEZpZWxkXzsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dD4gZ2V0U291cmNlQ29udGV4dEZpZWxkTGlzdCgpIHsKICAgIHJldHVybiBzb3VyY2VDb250ZXh0RmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHRPckJ1aWxkZXI+IAogICAgICBnZXRTb3VyY2VDb250ZXh0RmllbGRPckJ1aWxkZXJMaXN0KCkgewogICAgcmV0dXJuIHNvdXJjZUNvbnRleHRGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldFNvdXJjZUNvbnRleHRGaWVsZENvdW50KCkgewogICAgcmV0dXJuIHNvdXJjZUNvbnRleHRGaWVsZF8uc2l6ZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBnZXRTb3VyY2VDb250ZXh0RmllbGQoaW50IGluZGV4KSB7CiAgICByZXR1cm4gc291cmNlQ29udGV4dEZpZWxkXy5nZXQoaW5kZXgpOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dE9yQnVpbGRlciBnZXRTb3VyY2VDb250ZXh0RmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCkgewogICAgcmV0dXJuIHNvdXJjZUNvbnRleHRGaWVsZF8uZ2V0KGluZGV4KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUlVDVF9GSUVMRF9GSUVMRF9OVU1CRVIgPSA3OwogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Q+IHN0cnVjdEZpZWxkXzsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0PiBnZXRTdHJ1Y3RGaWVsZExpc3QoKSB7CiAgICByZXR1cm4gc3RydWN0RmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdE9yQnVpbGRlcj4gCiAgICAgIGdldFN0cnVjdEZpZWxkT3JCdWlsZGVyTGlzdCgpIHsKICAgIHJldHVybiBzdHJ1Y3RGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldFN0cnVjdEZpZWxkQ291bnQoKSB7CiAgICByZXR1cm4gc3RydWN0RmllbGRfLnNpemUoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBnZXRTdHJ1Y3RGaWVsZChpbnQgaW5kZXgpIHsKICAgIHJldHVybiBzdHJ1Y3RGaWVsZF8uZ2V0KGluZGV4KTsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdE9yQnVpbGRlciBnZXRTdHJ1Y3RGaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KSB7CiAgICByZXR1cm4gc3RydWN0RmllbGRfLmdldChpbmRleCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUSU1FU1RBTVBfRklFTERfRklFTERfTlVNQkVSID0gODsKICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wPiB0aW1lc3RhbXBGaWVsZF87CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcD4gZ2V0VGltZXN0YW1wRmllbGRMaXN0KCkgewogICAgcmV0dXJuIHRpbWVzdGFtcEZpZWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBPckJ1aWxkZXI+IAogICAgICBnZXRUaW1lc3RhbXBGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gdGltZXN0YW1wRmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRUaW1lc3RhbXBGaWVsZENvdW50KCkgewogICAgcmV0dXJuIHRpbWVzdGFtcEZpZWxkXy5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgZ2V0VGltZXN0YW1wRmllbGQoaW50IGluZGV4KSB7CiAgICByZXR1cm4gdGltZXN0YW1wRmllbGRfLmdldChpbmRleCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBPckJ1aWxkZXIgZ2V0VGltZXN0YW1wRmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCkgewogICAgcmV0dXJuIHRpbWVzdGFtcEZpZWxkXy5nZXQoaW5kZXgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9GSUVMRF9GSUVMRF9OVU1CRVIgPSA5OwogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlPiB0eXBlRmllbGRfOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGU+IGdldFR5cGVGaWVsZExpc3QoKSB7CiAgICByZXR1cm4gdHlwZUZpZWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGVPckJ1aWxkZXI+IAogICAgICBnZXRUeXBlRmllbGRPckJ1aWxkZXJMaXN0KCkgewogICAgcmV0dXJuIHR5cGVGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgZ2V0VHlwZUZpZWxkQ291bnQoKSB7CiAgICByZXR1cm4gdHlwZUZpZWxkXy5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUgZ2V0VHlwZUZpZWxkKGludCBpbmRleCkgewogICAgcmV0dXJuIHR5cGVGaWVsZF8uZ2V0KGluZGV4KTsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZU9yQnVpbGRlciBnZXRUeXBlRmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCkgewogICAgcmV0dXJuIHR5cGVGaWVsZF8uZ2V0KGluZGV4KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERPVUJMRV9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDsKICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+IGRvdWJsZUZpZWxkXzsKICAvKioKICAgKiA8cHJlPgogICAqIFRoZXNlIGRvbid0IGFjdHVhbGx5IG1ha2UgYSBsb3Qgb2Ygc2Vuc2UsIGJ1dCB0aGV5J3JlIG5vdCBwcm9oaWJpdGVkLi4uCiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+IGdldERvdWJsZUZpZWxkTGlzdCgpIHsKICAgIHJldHVybiBkb3VibGVGaWVsZF87CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVGhlc2UgZG9uJ3QgYWN0dWFsbHkgbWFrZSBhIGxvdCBvZiBzZW5zZSwgYnV0IHRoZXkncmUgbm90IHByb2hpYml0ZWQuLi4KICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWVPckJ1aWxkZXI+IAogICAgICBnZXREb3VibGVGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gZG91YmxlRmllbGRfOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRoZXNlIGRvbid0IGFjdHVhbGx5IG1ha2UgYSBsb3Qgb2Ygc2Vuc2UsIGJ1dCB0aGV5J3JlIG5vdCBwcm9oaWJpdGVkLi4uCiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXREb3VibGVGaWVsZENvdW50KCkgewogICAgcmV0dXJuIGRvdWJsZUZpZWxkXy5zaXplKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVGhlc2UgZG9uJ3QgYWN0dWFsbHkgbWFrZSBhIGxvdCBvZiBzZW5zZSwgYnV0IHRoZXkncmUgbm90IHByb2hpYml0ZWQuLi4KICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBnZXREb3VibGVGaWVsZChpbnQgaW5kZXgpIHsKICAgIHJldHVybiBkb3VibGVGaWVsZF8uZ2V0KGluZGV4KTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUaGVzZSBkb24ndCBhY3R1YWxseSBtYWtlIGEgbG90IG9mIHNlbnNlLCBidXQgdGhleSdyZSBub3QgcHJvaGliaXRlZC4uLgogICAqIDwvcHJlPgogICAqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlT3JCdWlsZGVyIGdldERvdWJsZUZpZWxkT3JCdWlsZGVyKAogICAgICBpbnQgaW5kZXgpIHsKICAgIHJldHVybiBkb3VibGVGaWVsZF8uZ2V0KGluZGV4KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZMT0FUX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDExOwogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlPiBmbG9hdEZpZWxkXzsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWU+IGdldEZsb2F0RmllbGRMaXN0KCkgewogICAgcmV0dXJuIGZsb2F0RmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlT3JCdWlsZGVyPiAKICAgICAgZ2V0RmxvYXRGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gZmxvYXRGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRGbG9hdEZpZWxkQ291bnQoKSB7CiAgICByZXR1cm4gZmxvYXRGaWVsZF8uc2l6ZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZ2V0RmxvYXRGaWVsZChpbnQgaW5kZXgpIHsKICAgIHJldHVybiBmbG9hdEZpZWxkXy5nZXQoaW5kZXgpOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWVPckJ1aWxkZXIgZ2V0RmxvYXRGaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KSB7CiAgICByZXR1cm4gZmxvYXRGaWVsZF8uZ2V0KGluZGV4KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDY0X0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDEyOwogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPiBpbnQ2NEZpZWxkXzsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWU+IGdldEludDY0RmllbGRMaXN0KCkgewogICAgcmV0dXJuIGludDY0RmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyPiAKICAgICAgZ2V0SW50NjRGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gaW50NjRGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRJbnQ2NEZpZWxkQ291bnQoKSB7CiAgICByZXR1cm4gaW50NjRGaWVsZF8uc2l6ZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgZ2V0SW50NjRGaWVsZChpbnQgaW5kZXgpIHsKICAgIHJldHVybiBpbnQ2NEZpZWxkXy5nZXQoaW5kZXgpOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWVPckJ1aWxkZXIgZ2V0SW50NjRGaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KSB7CiAgICByZXR1cm4gaW50NjRGaWVsZF8uZ2V0KGluZGV4KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVJTlQ2NF9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxMzsKICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWU+IHVpbnQ2NEZpZWxkXzsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWU+IGdldFVpbnQ2NEZpZWxkTGlzdCgpIHsKICAgIHJldHVybiB1aW50NjRGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXI+IAogICAgICBnZXRVaW50NjRGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gdWludDY0RmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRVaW50NjRGaWVsZENvdW50KCkgewogICAgcmV0dXJuIHVpbnQ2NEZpZWxkXy5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBnZXRVaW50NjRGaWVsZChpbnQgaW5kZXgpIHsKICAgIHJldHVybiB1aW50NjRGaWVsZF8uZ2V0KGluZGV4KTsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlT3JCdWlsZGVyIGdldFVpbnQ2NEZpZWxkT3JCdWlsZGVyKAogICAgICBpbnQgaW5kZXgpIHsKICAgIHJldHVybiB1aW50NjRGaWVsZF8uZ2V0KGluZGV4KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE0OwogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlPiBpbnQzMkZpZWxkXzsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWU+IGdldEludDMyRmllbGRMaXN0KCkgewogICAgcmV0dXJuIGludDMyRmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlT3JCdWlsZGVyPiAKICAgICAgZ2V0SW50MzJGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gaW50MzJGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRJbnQzMkZpZWxkQ291bnQoKSB7CiAgICByZXR1cm4gaW50MzJGaWVsZF8uc2l6ZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgZ2V0SW50MzJGaWVsZChpbnQgaW5kZXgpIHsKICAgIHJldHVybiBpbnQzMkZpZWxkXy5nZXQoaW5kZXgpOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWVPckJ1aWxkZXIgZ2V0SW50MzJGaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KSB7CiAgICByZXR1cm4gaW50MzJGaWVsZF8uZ2V0KGluZGV4KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVJTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxNTsKICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+IHVpbnQzMkZpZWxkXzsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+IGdldFVpbnQzMkZpZWxkTGlzdCgpIHsKICAgIHJldHVybiB1aW50MzJGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWVPckJ1aWxkZXI+IAogICAgICBnZXRVaW50MzJGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gdWludDMyRmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRVaW50MzJGaWVsZENvdW50KCkgewogICAgcmV0dXJuIHVpbnQzMkZpZWxkXy5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSBnZXRVaW50MzJGaWVsZChpbnQgaW5kZXgpIHsKICAgIHJldHVybiB1aW50MzJGaWVsZF8uZ2V0KGluZGV4KTsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlT3JCdWlsZGVyIGdldFVpbnQzMkZpZWxkT3JCdWlsZGVyKAogICAgICBpbnQgaW5kZXgpIHsKICAgIHJldHVybiB1aW50MzJGaWVsZF8uZ2V0KGluZGV4KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJPT0xfRklFTERfRklFTERfTlVNQkVSID0gMTY7CiAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZT4gYm9vbEZpZWxkXzsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWU+IGdldEJvb2xGaWVsZExpc3QoKSB7CiAgICByZXR1cm4gYm9vbEZpZWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlcj4gCiAgICAgIGdldEJvb2xGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gYm9vbEZpZWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRCb29sRmllbGRDb3VudCgpIHsKICAgIHJldHVybiBib29sRmllbGRfLnNpemUoKTsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGdldEJvb2xGaWVsZChpbnQgaW5kZXgpIHsKICAgIHJldHVybiBib29sRmllbGRfLmdldChpbmRleCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlciBnZXRCb29sRmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCkgewogICAgcmV0dXJuIGJvb2xGaWVsZF8uZ2V0KGluZGV4KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklOR19GSUVMRF9GSUVMRF9OVU1CRVIgPSAxNzsKICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWU+IHN0cmluZ0ZpZWxkXzsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWU+IGdldFN0cmluZ0ZpZWxkTGlzdCgpIHsKICAgIHJldHVybiBzdHJpbmdGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWVPckJ1aWxkZXI+IAogICAgICBnZXRTdHJpbmdGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gc3RyaW5nRmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRTdHJpbmdGaWVsZENvdW50KCkgewogICAgcmV0dXJuIHN0cmluZ0ZpZWxkXy5zaXplKCk7CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBnZXRTdHJpbmdGaWVsZChpbnQgaW5kZXgpIHsKICAgIHJldHVybiBzdHJpbmdGaWVsZF8uZ2V0KGluZGV4KTsKICB9CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyIGdldFN0cmluZ0ZpZWxkT3JCdWlsZGVyKAogICAgICBpbnQgaW5kZXgpIHsKICAgIHJldHVybiBzdHJpbmdGaWVsZF8uZ2V0KGluZGV4KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJZVEVTX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE4OwogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlPiBieXRlc0ZpZWxkXzsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWU+IGdldEJ5dGVzRmllbGRMaXN0KCkgewogICAgcmV0dXJuIGJ5dGVzRmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyPiAKICAgICAgZ2V0Qnl0ZXNGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICByZXR1cm4gYnl0ZXNGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRCeXRlc0ZpZWxkQ291bnQoKSB7CiAgICByZXR1cm4gYnl0ZXNGaWVsZF8uc2l6ZSgpOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgZ2V0Qnl0ZXNGaWVsZChpbnQgaW5kZXgpIHsKICAgIHJldHVybiBieXRlc0ZpZWxkXy5nZXQoaW5kZXgpOwogIH0KICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWVPckJ1aWxkZXIgZ2V0Qnl0ZXNGaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KSB7CiAgICByZXR1cm4gYnl0ZXNGaWVsZF8uZ2V0KGluZGV4KTsKICB9CgogIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhbnlGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBhbnlGaWVsZF8uZ2V0KGkpKTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYXBpRmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMiwgYXBpRmllbGRfLmdldChpKSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGR1cmF0aW9uRmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMywgZHVyYXRpb25GaWVsZF8uZ2V0KGkpKTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZW1wdHlGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg0LCBlbXB0eUZpZWxkXy5nZXQoaSkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZE1hc2tGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg1LCBmaWVsZE1hc2tGaWVsZF8uZ2V0KGkpKTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc291cmNlQ29udGV4dEZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDYsIHNvdXJjZUNvbnRleHRGaWVsZF8uZ2V0KGkpKTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3RydWN0RmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNywgc3RydWN0RmllbGRfLmdldChpKSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHRpbWVzdGFtcEZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDgsIHRpbWVzdGFtcEZpZWxkXy5nZXQoaSkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0eXBlRmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoOSwgdHlwZUZpZWxkXy5nZXQoaSkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkb3VibGVGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxMCwgZG91YmxlRmllbGRfLmdldChpKSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGZsb2F0RmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTEsIGZsb2F0RmllbGRfLmdldChpKSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGludDY0RmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTIsIGludDY0RmllbGRfLmdldChpKSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHVpbnQ2NEZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEzLCB1aW50NjRGaWVsZF8uZ2V0KGkpKTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW50MzJGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxNCwgaW50MzJGaWVsZF8uZ2V0KGkpKTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdWludDMyRmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTUsIHVpbnQzMkZpZWxkXy5nZXQoaSkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBib29sRmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTYsIGJvb2xGaWVsZF8uZ2V0KGkpKTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3RyaW5nRmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTcsIHN0cmluZ0ZpZWxkXy5nZXQoaSkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBieXRlc0ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDE4LCBieXRlc0ZpZWxkXy5nZXQoaSkpOwogICAgfQogICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgc2l6ZSA9IDA7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGFueUZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGFueUZpZWxkXy5nZXQoaSkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhcGlGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBhcGlGaWVsZF8uZ2V0KGkpKTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZHVyYXRpb25GaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzLCBkdXJhdGlvbkZpZWxkXy5nZXQoaSkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBlbXB0eUZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQsIGVtcHR5RmllbGRfLmdldChpKSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkTWFza0ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGZpZWxkTWFza0ZpZWxkXy5nZXQoaSkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzb3VyY2VDb250ZXh0RmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNiwgc291cmNlQ29udGV4dEZpZWxkXy5nZXQoaSkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdHJ1Y3RGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3LCBzdHJ1Y3RGaWVsZF8uZ2V0KGkpKTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGltZXN0YW1wRmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOCwgdGltZXN0YW1wRmllbGRfLmdldChpKSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHR5cGVGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5LCB0eXBlRmllbGRfLmdldChpKSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGRvdWJsZUZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwLCBkb3VibGVGaWVsZF8uZ2V0KGkpKTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmxvYXRGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMSwgZmxvYXRGaWVsZF8uZ2V0KGkpKTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaW50NjRGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMiwgaW50NjRGaWVsZF8uZ2V0KGkpKTsKICAgIH0KICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdWludDY0RmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTMsIHVpbnQ2NEZpZWxkXy5nZXQoaSkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnQzMkZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE0LCBpbnQzMkZpZWxkXy5nZXQoaSkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1aW50MzJGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNSwgdWludDMyRmllbGRfLmdldChpKSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGJvb2xGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNiwgYm9vbEZpZWxkXy5nZXQoaSkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzdHJpbmdGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNywgc3RyaW5nRmllbGRfLmdldChpKSk7CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGJ5dGVzRmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgsIGJ5dGVzRmllbGRfLmdldChpKSk7CiAgICB9CiAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgIHJldHVybiBzaXplOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuUmVwZWF0ZWRXZWxsS25vd25UeXBlcykpIHsKICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgfQogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMpIG9iajsKCiAgICBpZiAoIWdldEFueUZpZWxkTGlzdCgpCiAgICAgICAgLmVxdWFscyhvdGhlci5nZXRBbnlGaWVsZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgIGlmICghZ2V0QXBpRmllbGRMaXN0KCkKICAgICAgICAuZXF1YWxzKG90aGVyLmdldEFwaUZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFnZXREdXJhdGlvbkZpZWxkTGlzdCgpCiAgICAgICAgLmVxdWFscyhvdGhlci5nZXREdXJhdGlvbkZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFnZXRFbXB0eUZpZWxkTGlzdCgpCiAgICAgICAgLmVxdWFscyhvdGhlci5nZXRFbXB0eUZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFnZXRGaWVsZE1hc2tGaWVsZExpc3QoKQogICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRNYXNrRmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoIWdldFNvdXJjZUNvbnRleHRGaWVsZExpc3QoKQogICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U291cmNlQ29udGV4dEZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFnZXRTdHJ1Y3RGaWVsZExpc3QoKQogICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RydWN0RmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoIWdldFRpbWVzdGFtcEZpZWxkTGlzdCgpCiAgICAgICAgLmVxdWFscyhvdGhlci5nZXRUaW1lc3RhbXBGaWVsZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgIGlmICghZ2V0VHlwZUZpZWxkTGlzdCgpCiAgICAgICAgLmVxdWFscyhvdGhlci5nZXRUeXBlRmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoIWdldERvdWJsZUZpZWxkTGlzdCgpCiAgICAgICAgLmVxdWFscyhvdGhlci5nZXREb3VibGVGaWVsZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgIGlmICghZ2V0RmxvYXRGaWVsZExpc3QoKQogICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmxvYXRGaWVsZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgIGlmICghZ2V0SW50NjRGaWVsZExpc3QoKQogICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0SW50NjRGaWVsZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgIGlmICghZ2V0VWludDY0RmllbGRMaXN0KCkKICAgICAgICAuZXF1YWxzKG90aGVyLmdldFVpbnQ2NEZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFnZXRJbnQzMkZpZWxkTGlzdCgpCiAgICAgICAgLmVxdWFscyhvdGhlci5nZXRJbnQzMkZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFnZXRVaW50MzJGaWVsZExpc3QoKQogICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0VWludDMyRmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoIWdldEJvb2xGaWVsZExpc3QoKQogICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Qm9vbEZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFnZXRTdHJpbmdGaWVsZExpc3QoKQogICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyaW5nRmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoIWdldEJ5dGVzRmllbGRMaXN0KCkKICAgICAgICAuZXF1YWxzKG90aGVyLmdldEJ5dGVzRmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICB9CiAgICBpbnQgaGFzaCA9IDQxOwogICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICBpZiAoZ2V0QW55RmllbGRDb3VudCgpID4gMCkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBBTllfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBbnlGaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGdldEFwaUZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQVBJX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QXBpRmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGlmIChnZXREdXJhdGlvbkZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVSQVRJT05fRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREdXJhdGlvbkZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoZ2V0RW1wdHlGaWVsZENvdW50KCkgPiAwKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEVNUFRZX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RW1wdHlGaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGdldEZpZWxkTWFza0ZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTERfTUFTS19GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkTWFza0ZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoZ2V0U291cmNlQ29udGV4dEZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU09VUkNFX0NPTlRFWFRfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTb3VyY2VDb250ZXh0RmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGlmIChnZXRTdHJ1Y3RGaWVsZENvdW50KCkgPiAwKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUlVDVF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cnVjdEZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoZ2V0VGltZXN0YW1wRmllbGRDb3VudCgpID4gMCkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBUSU1FU1RBTVBfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRUaW1lc3RhbXBGaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGdldFR5cGVGaWVsZENvdW50KCkgPiAwKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFRZUEVfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRUeXBlRmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGlmIChnZXREb3VibGVGaWVsZENvdW50KCkgPiAwKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERPVUJMRV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldERvdWJsZUZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoZ2V0RmxvYXRGaWVsZENvdW50KCkgPiAwKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZMT0FUX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmxvYXRGaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGdldEludDY0RmllbGRDb3VudCgpID4gMCkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQ2NF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEludDY0RmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGlmIChnZXRVaW50NjRGaWVsZENvdW50KCkgPiAwKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVJTlQ2NF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFVpbnQ2NEZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoZ2V0SW50MzJGaWVsZENvdW50KCkgPiAwKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0SW50MzJGaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGdldFVpbnQzMkZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVUlOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VWludDMyRmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGlmIChnZXRCb29sRmllbGRDb3VudCgpID4gMCkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCT09MX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Qm9vbEZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoZ2V0U3RyaW5nRmllbGRDb3VudCgpID4gMCkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFJJTkdfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHJpbmdGaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGdldEJ5dGVzRmllbGRDb3VudCgpID4gMCkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCWVRFU19GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEJ5dGVzRmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICByZXR1cm4gaGFzaDsKICB9CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKAogICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuUmVwZWF0ZWRXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzIHBhcnNlRnJvbSgKICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKAogICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuUmVwZWF0ZWRXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzIHByb3RvdHlwZSkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgfQogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgcmV0dXJuIGJ1aWxkZXI7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogQSByZXBlYXRlZCBmaWVsZCBmb3IgZWFjaCB3ZWxsLWtub3duIHR5cGUuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzT3JCdWlsZGVyIHsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SZXBlYXRlZFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0V2VsbEtub3duVHlwZXMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkV2VsbEtub3duVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuUmVwZWF0ZWRXZWxsS25vd25UeXBlcy5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzLm5ld0J1aWxkZXIoKQogICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgIH0KCiAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgc3VwZXIocGFyZW50KTsKCiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgIGlmIChhbnlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBhbnlGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYW55RmllbGRfID0gbnVsbDsKICAgICAgICBhbnlGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICBpZiAoYXBpRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgYXBpRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGFwaUZpZWxkXyA9IG51bGw7CiAgICAgICAgYXBpRmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgaWYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZHVyYXRpb25GaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZHVyYXRpb25GaWVsZF8gPSBudWxsOwogICAgICAgIGR1cmF0aW9uRmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW1wdHlGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZW1wdHlGaWVsZF8gPSBudWxsOwogICAgICAgIGVtcHR5RmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGZpZWxkTWFza0ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBmaWVsZE1hc2tGaWVsZF8gPSBudWxsOwogICAgICAgIGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgIGlmIChzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRfID0gbnVsbDsKICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgaWYgKHN0cnVjdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHN0cnVjdEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdHJ1Y3RGaWVsZF8gPSBudWxsOwogICAgICAgIHN0cnVjdEZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgIGlmICh0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICB0aW1lc3RhbXBGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGltZXN0YW1wRmllbGRfID0gbnVsbDsKICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICBpZiAodHlwZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHR5cGVGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdHlwZUZpZWxkXyA9IG51bGw7CiAgICAgICAgdHlwZUZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBkb3VibGVGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZG91YmxlRmllbGRfID0gbnVsbDsKICAgICAgICBkb3VibGVGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICBpZiAoZmxvYXRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBmbG9hdEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBmbG9hdEZpZWxkXyA9IG51bGw7CiAgICAgICAgZmxvYXRGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICBpZiAoaW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpbnQ2NEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpbnQ2NEZpZWxkXyA9IG51bGw7CiAgICAgICAgaW50NjRGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgdWludDY0RmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHVpbnQ2NEZpZWxkXyA9IG51bGw7CiAgICAgICAgdWludDY0RmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaW50MzJGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaW50MzJGaWVsZF8gPSBudWxsOwogICAgICAgIGludDMyRmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHVpbnQzMkZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB1aW50MzJGaWVsZF8gPSBudWxsOwogICAgICAgIHVpbnQzMkZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgIGlmIChib29sRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgYm9vbEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBib29sRmllbGRfID0gbnVsbDsKICAgICAgICBib29sRmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA4MDAwKTsKICAgICAgaWYgKHN0cmluZ0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHN0cmluZ0ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdHJpbmdGaWVsZF8gPSBudWxsOwogICAgICAgIHN0cmluZ0ZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAxMDAwMCk7CiAgICAgIGlmIChieXRlc0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGJ5dGVzRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ5dGVzRmllbGRfID0gbnVsbDsKICAgICAgICBieXRlc0ZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SZXBlYXRlZFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuUmVwZWF0ZWRXZWxsS25vd25UeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMgYnVpbGQoKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICB9CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzKHRoaXMpOwogICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICBvbkJ1aWx0KCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzIHJlc3VsdCkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBhbnlGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChhbnlGaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYW55RmllbGRfID0gYW55RmllbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJlc3VsdC5hbnlGaWVsZF8gPSBhbnlGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgIH0KICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgYXBpRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoYXBpRmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmFwaUZpZWxkXyA9IGFwaUZpZWxkXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXN1bHQuYXBpRmllbGRfID0gYXBpRmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICB9CiAgICAgIGlmIChkdXJhdGlvbkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgZHVyYXRpb25GaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChkdXJhdGlvbkZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5kdXJhdGlvbkZpZWxkXyA9IGR1cmF0aW9uRmllbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJlc3VsdC5kdXJhdGlvbkZpZWxkXyA9IGR1cmF0aW9uRmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICB9CiAgICAgIGlmIChlbXB0eUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgZW1wdHlGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChlbXB0eUZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5lbXB0eUZpZWxkXyA9IGVtcHR5RmllbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJlc3VsdC5lbXB0eUZpZWxkXyA9IGVtcHR5RmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICB9CiAgICAgIGlmIChmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIGZpZWxkTWFza0ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkTWFza0ZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5maWVsZE1hc2tGaWVsZF8gPSBmaWVsZE1hc2tGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmVzdWx0LmZpZWxkTWFza0ZpZWxkXyA9IGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgc291cmNlQ29udGV4dEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHNvdXJjZUNvbnRleHRGaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIH0KICAgICAgICByZXN1bHQuc291cmNlQ29udGV4dEZpZWxkXyA9IHNvdXJjZUNvbnRleHRGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmVzdWx0LnNvdXJjZUNvbnRleHRGaWVsZF8gPSBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICB9CiAgICAgIGlmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHN0cnVjdEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHN0cnVjdEZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5zdHJ1Y3RGaWVsZF8gPSBzdHJ1Y3RGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmVzdWx0LnN0cnVjdEZpZWxkXyA9IHN0cnVjdEZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgICBpZiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICB0aW1lc3RhbXBGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCh0aW1lc3RhbXBGaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIH0KICAgICAgICByZXN1bHQudGltZXN0YW1wRmllbGRfID0gdGltZXN0YW1wRmllbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJlc3VsdC50aW1lc3RhbXBGaWVsZF8gPSB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgIH0KICAgICAgaWYgKHR5cGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHR5cGVGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCh0eXBlRmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnR5cGVGaWVsZF8gPSB0eXBlRmllbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJlc3VsdC50eXBlRmllbGRfID0gdHlwZUZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgICBpZiAoZG91YmxlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICBkb3VibGVGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChkb3VibGVGaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQuZG91YmxlRmllbGRfID0gZG91YmxlRmllbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJlc3VsdC5kb3VibGVGaWVsZF8gPSBkb3VibGVGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgIH0KICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICBmbG9hdEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZsb2F0RmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmZsb2F0RmllbGRfID0gZmxvYXRGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmVzdWx0LmZsb2F0RmllbGRfID0gZmxvYXRGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgIH0KICAgICAgaWYgKGludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICBpbnQ2NEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGludDY0RmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwODAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmludDY0RmllbGRfID0gaW50NjRGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmVzdWx0LmludDY0RmllbGRfID0gaW50NjRGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgIH0KICAgICAgaWYgKHVpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgdWludDY0RmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QodWludDY0RmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnVpbnQ2NEZpZWxkXyA9IHVpbnQ2NEZpZWxkXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXN1bHQudWludDY0RmllbGRfID0gdWludDY0RmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICB9CiAgICAgIGlmIChpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgaW50MzJGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChpbnQzMkZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5pbnQzMkZpZWxkXyA9IGludDMyRmllbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJlc3VsdC5pbnQzMkZpZWxkXyA9IGludDMyRmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICB9CiAgICAgIGlmICh1aW50MzJGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHVpbnQzMkZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHVpbnQzMkZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC51aW50MzJGaWVsZF8gPSB1aW50MzJGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmVzdWx0LnVpbnQzMkZpZWxkXyA9IHVpbnQzMkZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgICBpZiAoYm9vbEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgYm9vbEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGJvb2xGaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDgwMDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYm9vbEZpZWxkXyA9IGJvb2xGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmVzdWx0LmJvb2xGaWVsZF8gPSBib29sRmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICB9CiAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHN0cmluZ0ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHN0cmluZ0ZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5zdHJpbmdGaWVsZF8gPSBzdHJpbmdGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmVzdWx0LnN0cmluZ0ZpZWxkXyA9IHN0cmluZ0ZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgICBpZiAoYnl0ZXNGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIGJ5dGVzRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoYnl0ZXNGaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYnl0ZXNGaWVsZF8gPSBieXRlc0ZpZWxkXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXN1bHQuYnl0ZXNGaWVsZF8gPSBieXRlc0ZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzIHJlc3VsdCkgewogICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzKSB7CiAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMpb3RoZXIpOwogICAgICB9IGVsc2UgewogICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMgb3RoZXIpIHsKICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgaWYgKGFueUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICghb3RoZXIuYW55RmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGFueUZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgYW55RmllbGRfID0gb3RoZXIuYW55RmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVBbnlGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICBhbnlGaWVsZF8uYWRkQWxsKG90aGVyLmFueUZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKCFvdGhlci5hbnlGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoYW55RmllbGRCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgYW55RmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIGFueUZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICBhbnlGaWVsZF8gPSBvdGhlci5hbnlGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgICAgYW55RmllbGRCdWlsZGVyXyA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgIGdldEFueUZpZWxkRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYW55RmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5hbnlGaWVsZF8pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoYXBpRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCFvdGhlci5hcGlGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoYXBpRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBhcGlGaWVsZF8gPSBvdGhlci5hcGlGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUFwaUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGFwaUZpZWxkXy5hZGRBbGwob3RoZXIuYXBpRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoIW90aGVyLmFwaUZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChhcGlGaWVsZEJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgYXBpRmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgIGFwaUZpZWxkXyA9IG90aGVyLmFwaUZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgZ2V0QXBpRmllbGRGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLmFwaUZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChkdXJhdGlvbkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICghb3RoZXIuZHVyYXRpb25GaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZHVyYXRpb25GaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGR1cmF0aW9uRmllbGRfID0gb3RoZXIuZHVyYXRpb25GaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUR1cmF0aW9uRmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgZHVyYXRpb25GaWVsZF8uYWRkQWxsKG90aGVyLmR1cmF0aW9uRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoIW90aGVyLmR1cmF0aW9uRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZHVyYXRpb25GaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgZHVyYXRpb25GaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgZHVyYXRpb25GaWVsZF8gPSBvdGhlci5kdXJhdGlvbkZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgICAgICBkdXJhdGlvbkZpZWxkQnVpbGRlcl8gPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICBnZXREdXJhdGlvbkZpZWxkRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZHVyYXRpb25GaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLmR1cmF0aW9uRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCFvdGhlci5lbXB0eUZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChlbXB0eUZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZW1wdHlGaWVsZF8gPSBvdGhlci5lbXB0eUZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlRW1wdHlGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICBlbXB0eUZpZWxkXy5hZGRBbGwob3RoZXIuZW1wdHlGaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGlmICghb3RoZXIuZW1wdHlGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZW1wdHlGaWVsZEJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBlbXB0eUZpZWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICBlbXB0eUZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICBlbXB0eUZpZWxkXyA9IG90aGVyLmVtcHR5RmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgICAgIGVtcHR5RmllbGRCdWlsZGVyXyA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgIGdldEVtcHR5RmllbGRGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbXB0eUZpZWxkQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIuZW1wdHlGaWVsZF8pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoZmllbGRNYXNrRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCFvdGhlci5maWVsZE1hc2tGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZmllbGRNYXNrRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZE1hc2tGaWVsZF8gPSBvdGhlci5maWVsZE1hc2tGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkTWFza0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZpZWxkTWFza0ZpZWxkXy5hZGRBbGwob3RoZXIuZmllbGRNYXNrRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoIW90aGVyLmZpZWxkTWFza0ZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgZmllbGRNYXNrRmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgIGZpZWxkTWFza0ZpZWxkXyA9IG90aGVyLmZpZWxkTWFza0ZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgICAgICBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgZ2V0RmllbGRNYXNrRmllbGRGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLmZpZWxkTWFza0ZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCFvdGhlci5zb3VyY2VDb250ZXh0RmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZF8gPSBvdGhlci5zb3VyY2VDb250ZXh0RmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVTb3VyY2VDb250ZXh0RmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgc291cmNlQ29udGV4dEZpZWxkXy5hZGRBbGwob3RoZXIuc291cmNlQ29udGV4dEZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKCFvdGhlci5zb3VyY2VDb250ZXh0RmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgc291cmNlQ29udGV4dEZpZWxkXyA9IG90aGVyLnNvdXJjZUNvbnRleHRGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICAgICAgc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICBnZXRTb3VyY2VDb250ZXh0RmllbGRGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5zb3VyY2VDb250ZXh0RmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKHN0cnVjdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICghb3RoZXIuc3RydWN0RmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHN0cnVjdEZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgc3RydWN0RmllbGRfID0gb3RoZXIuc3RydWN0RmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVTdHJ1Y3RGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICBzdHJ1Y3RGaWVsZF8uYWRkQWxsKG90aGVyLnN0cnVjdEZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKCFvdGhlci5zdHJ1Y3RGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgc3RydWN0RmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIHN0cnVjdEZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICBzdHJ1Y3RGaWVsZF8gPSBvdGhlci5zdHJ1Y3RGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICAgICAgc3RydWN0RmllbGRCdWlsZGVyXyA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgIGdldFN0cnVjdEZpZWxkRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3RydWN0RmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5zdHJ1Y3RGaWVsZF8pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBpZiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCFvdGhlci50aW1lc3RhbXBGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAodGltZXN0YW1wRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICB0aW1lc3RhbXBGaWVsZF8gPSBvdGhlci50aW1lc3RhbXBGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVRpbWVzdGFtcEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHRpbWVzdGFtcEZpZWxkXy5hZGRBbGwob3RoZXIudGltZXN0YW1wRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoIW90aGVyLnRpbWVzdGFtcEZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmICh0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgdGltZXN0YW1wRmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgIHRpbWVzdGFtcEZpZWxkXyA9IG90aGVyLnRpbWVzdGFtcEZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgZ2V0VGltZXN0YW1wRmllbGRGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnRpbWVzdGFtcEZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCFvdGhlci50eXBlRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHR5cGVGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHR5cGVGaWVsZF8gPSBvdGhlci50eXBlRmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVUeXBlRmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgdHlwZUZpZWxkXy5hZGRBbGwob3RoZXIudHlwZUZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKCFvdGhlci50eXBlRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHR5cGVGaWVsZEJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICB0eXBlRmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIHR5cGVGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgdHlwZUZpZWxkXyA9IG90aGVyLnR5cGVGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICAgICAgdHlwZUZpZWxkQnVpbGRlcl8gPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICBnZXRUeXBlRmllbGRGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0eXBlRmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci50eXBlRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGRvdWJsZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICghb3RoZXIuZG91YmxlRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGRvdWJsZUZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZG91YmxlRmllbGRfID0gb3RoZXIuZG91YmxlRmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVEb3VibGVGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICBkb3VibGVGaWVsZF8uYWRkQWxsKG90aGVyLmRvdWJsZUZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKCFvdGhlci5kb3VibGVGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZG91YmxlRmllbGRCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZG91YmxlRmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIGRvdWJsZUZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICBkb3VibGVGaWVsZF8gPSBvdGhlci5kb3VibGVGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICAgICAgZG91YmxlRmllbGRCdWlsZGVyXyA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgIGdldERvdWJsZUZpZWxkRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZG91YmxlRmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5kb3VibGVGaWVsZF8pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoZmxvYXRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoIW90aGVyLmZsb2F0RmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGZsb2F0RmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBmbG9hdEZpZWxkXyA9IG90aGVyLmZsb2F0RmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGbG9hdEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZsb2F0RmllbGRfLmFkZEFsbChvdGhlci5mbG9hdEZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKCFvdGhlci5mbG9hdEZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmbG9hdEZpZWxkQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgIGZsb2F0RmllbGRfID0gb3RoZXIuZmxvYXRGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICAgICAgZmxvYXRGaWVsZEJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgZ2V0RmxvYXRGaWVsZEZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5mbG9hdEZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICghb3RoZXIuaW50NjRGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoaW50NjRGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGludDY0RmllbGRfID0gb3RoZXIuaW50NjRGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwODAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUludDY0RmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgaW50NjRGaWVsZF8uYWRkQWxsKG90aGVyLmludDY0RmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoIW90aGVyLmludDY0RmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGludDY0RmllbGRCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaW50NjRGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgaW50NjRGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgaW50NjRGaWVsZF8gPSBvdGhlci5pbnQ2NEZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgICAgICBpbnQ2NEZpZWxkQnVpbGRlcl8gPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICBnZXRJbnQ2NEZpZWxkRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW50NjRGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLmludDY0RmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKHVpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICghb3RoZXIudWludDY0RmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHVpbnQ2NEZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgdWludDY0RmllbGRfID0gb3RoZXIudWludDY0RmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVVaW50NjRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICB1aW50NjRGaWVsZF8uYWRkQWxsKG90aGVyLnVpbnQ2NEZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKCFvdGhlci51aW50NjRGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgdWludDY0RmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIHVpbnQ2NEZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICB1aW50NjRGaWVsZF8gPSBvdGhlci51aW50NjRGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICAgICAgdWludDY0RmllbGRCdWlsZGVyXyA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgIGdldFVpbnQ2NEZpZWxkRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdWludDY0RmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci51aW50NjRGaWVsZF8pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoaW50MzJGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoIW90aGVyLmludDMyRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGludDMyRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpbnQzMkZpZWxkXyA9IG90aGVyLmludDMyRmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVJbnQzMkZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGludDMyRmllbGRfLmFkZEFsbChvdGhlci5pbnQzMkZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKCFvdGhlci5pbnQzMkZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChpbnQzMkZpZWxkQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGludDMyRmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIGludDMyRmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgIGludDMyRmllbGRfID0gb3RoZXIuaW50MzJGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICAgICAgaW50MzJGaWVsZEJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgZ2V0SW50MzJGaWVsZEZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGludDMyRmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5pbnQzMkZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmICh1aW50MzJGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoIW90aGVyLnVpbnQzMkZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmICh1aW50MzJGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHVpbnQzMkZpZWxkXyA9IG90aGVyLnVpbnQzMkZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlVWludDMyRmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgdWludDMyRmllbGRfLmFkZEFsbChvdGhlci51aW50MzJGaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGlmICghb3RoZXIudWludDMyRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHVpbnQzMkZpZWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICB1aW50MzJGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgdWludDMyRmllbGRfID0gb3RoZXIudWludDMyRmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgICAgIHVpbnQzMkZpZWxkQnVpbGRlcl8gPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICBnZXRVaW50MzJGaWVsZEZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHVpbnQzMkZpZWxkQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIudWludDMyRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoIW90aGVyLmJvb2xGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoYm9vbEZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgYm9vbEZpZWxkXyA9IG90aGVyLmJvb2xGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUJvb2xGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICBib29sRmllbGRfLmFkZEFsbChvdGhlci5ib29sRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoIW90aGVyLmJvb2xGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoYm9vbEZpZWxkQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGJvb2xGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICBib29sRmllbGRfID0gb3RoZXIuYm9vbEZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDgwMDApOwogICAgICAgICAgICBib29sRmllbGRCdWlsZGVyXyA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgIGdldEJvb2xGaWVsZEZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGJvb2xGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLmJvb2xGaWVsZF8pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCFvdGhlci5zdHJpbmdGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoc3RyaW5nRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBzdHJpbmdGaWVsZF8gPSBvdGhlci5zdHJpbmdGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVN0cmluZ0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHN0cmluZ0ZpZWxkXy5hZGRBbGwob3RoZXIuc3RyaW5nRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoIW90aGVyLnN0cmluZ0ZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgc3RyaW5nRmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgIHN0cmluZ0ZpZWxkXyA9IG90aGVyLnN0cmluZ0ZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgZ2V0U3RyaW5nRmllbGRGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnN0cmluZ0ZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChieXRlc0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICghb3RoZXIuYnl0ZXNGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoYnl0ZXNGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGJ5dGVzRmllbGRfID0gb3RoZXIuYnl0ZXNGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUJ5dGVzRmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgYnl0ZXNGaWVsZF8uYWRkQWxsKG90aGVyLmJ5dGVzRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoIW90aGVyLmJ5dGVzRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGJ5dGVzRmllbGRCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgYnl0ZXNGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgYnl0ZXNGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgYnl0ZXNGaWVsZF8gPSBvdGhlci5ieXRlc0ZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgICAgICBieXRlc0ZpZWxkQnVpbGRlcl8gPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICBnZXRCeXRlc0ZpZWxkRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYnl0ZXNGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLmJ5dGVzRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgfQogICAgICB0cnkgewogICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55IG0gPQogICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LnBhcnNlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGlmIChhbnlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGVuc3VyZUFueUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBhbnlGaWVsZF8uYWRkKG0pOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhbnlGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQXBpIG0gPQogICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLnBhcnNlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGlmIChhcGlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGVuc3VyZUFwaUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBhcGlGaWVsZF8uYWRkKG0pOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gbSA9CiAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5wYXJzZXIoKSwKICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGVuc3VyZUR1cmF0aW9uRmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGR1cmF0aW9uRmllbGRfLmFkZChtKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZHVyYXRpb25GaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgbSA9CiAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eS5wYXJzZXIoKSwKICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBpZiAoZW1wdHlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGVuc3VyZUVtcHR5RmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGVtcHR5RmllbGRfLmFkZChtKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIG0gPQogICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLnBhcnNlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGlmIChmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkTWFza0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZE1hc2tGaWVsZF8uYWRkKG0pOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBtID0KICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQucGFyc2VyKCksCiAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGVuc3VyZVNvdXJjZUNvbnRleHRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgc291cmNlQ29udGV4dEZpZWxkXy5hZGQobSk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgY2FzZSA1ODogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IG0gPQogICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0LnBhcnNlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGlmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGVuc3VyZVN0cnVjdEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBzdHJ1Y3RGaWVsZF8uYWRkKG0pOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzdHJ1Y3RGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgY2FzZSA2NjogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIG0gPQogICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLnBhcnNlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGlmICh0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGVuc3VyZVRpbWVzdGFtcEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB0aW1lc3RhbXBGaWVsZF8uYWRkKG0pOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNjYKICAgICAgICAgICAgY2FzZSA3NDogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZSBtID0KICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUucGFyc2VyKCksCiAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgaWYgKHR5cGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGVuc3VyZVR5cGVGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgdHlwZUZpZWxkXy5hZGQobSk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHR5cGVGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgbSA9CiAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5wYXJzZXIoKSwKICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBpZiAoZG91YmxlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICBlbnN1cmVEb3VibGVGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZG91YmxlRmllbGRfLmFkZChtKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZG91YmxlRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDgyCiAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgbSA9CiAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLnBhcnNlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGlmIChmbG9hdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZW5zdXJlRmxvYXRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmxvYXRGaWVsZF8uYWRkKG0pOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmbG9hdEZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICBjYXNlIDk4OiB7CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIG0gPQogICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5wYXJzZXIoKSwKICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBpZiAoaW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgIGVuc3VyZUludDY0RmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGludDY0RmllbGRfLmFkZChtKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaW50NjRGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgOTgKICAgICAgICAgICAgY2FzZSAxMDY6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIG0gPQogICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUucGFyc2VyKCksCiAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgaWYgKHVpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZW5zdXJlVWludDY0RmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHVpbnQ2NEZpZWxkXy5hZGQobSk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHVpbnQ2NEZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMDYKICAgICAgICAgICAgY2FzZSAxMTQ6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgbSA9CiAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLnBhcnNlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGlmIChpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZW5zdXJlSW50MzJGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgaW50MzJGaWVsZF8uYWRkKG0pOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpbnQzMkZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMTQKICAgICAgICAgICAgY2FzZSAxMjI6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIG0gPQogICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUucGFyc2VyKCksCiAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZW5zdXJlVWludDMyRmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHVpbnQzMkZpZWxkXy5hZGQobSk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHVpbnQzMkZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMjIKICAgICAgICAgICAgY2FzZSAxMzA6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBtID0KICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5wYXJzZXIoKSwKICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBpZiAoYm9vbEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZW5zdXJlQm9vbEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBib29sRmllbGRfLmFkZChtKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMzAKICAgICAgICAgICAgY2FzZSAxMzg6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIG0gPQogICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUucGFyc2VyKCksCiAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgaWYgKHN0cmluZ0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZW5zdXJlU3RyaW5nRmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHN0cmluZ0ZpZWxkXy5hZGQobSk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHN0cmluZ0ZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMzgKICAgICAgICAgICAgY2FzZSAxNDY6IHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgbSA9CiAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLnBhcnNlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGlmIChieXRlc0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgZW5zdXJlQnl0ZXNGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgYnl0ZXNGaWVsZF8uYWRkKG0pOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBieXRlc0ZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxNDYKICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSAvLyBmaW5hbGx5CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQW55PiBhbnlGaWVsZF8gPQogICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICBwcml2YXRlIHZvaWQgZW5zdXJlQW55RmllbGRJc011dGFibGUoKSB7CiAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBhbnlGaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkFueT4oYW55RmllbGRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnksIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55T3JCdWlsZGVyPiBhbnlGaWVsZEJ1aWxkZXJfOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkFueT4gZ2V0QW55RmllbGRMaXN0KCkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGFueUZpZWxkXyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGFueUZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGludCBnZXRBbnlGaWVsZENvdW50KCkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGFueUZpZWxkXy5zaXplKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGFueUZpZWxkQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGdldEFueUZpZWxkKGludCBpbmRleCkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGFueUZpZWxkXy5nZXQoaW5kZXgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBhbnlGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRBbnlGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlKSB7CiAgICAgIGlmIChhbnlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUFueUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgYW55RmllbGRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGFueUZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0QW55RmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlQW55RmllbGRJc011dGFibGUoKTsKICAgICAgICBhbnlGaWVsZF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYW55RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRBbnlGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZSkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVBbnlGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGFueUZpZWxkXy5hZGQodmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGFueUZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRBbnlGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlKSB7CiAgICAgIGlmIChhbnlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUFueUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgYW55RmllbGRfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGFueUZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkQW55RmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGFueUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUFueUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgYW55RmllbGRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYW55RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFueUZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGFueUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUFueUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgYW55RmllbGRfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGFueUZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsQW55RmllbGQoCiAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueT4gdmFsdWVzKSB7CiAgICAgIGlmIChhbnlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVBbnlGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBhbnlGaWVsZF8pOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGFueUZpZWxkQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQW55RmllbGQoKSB7CiAgICAgIGlmIChhbnlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBhbnlGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGFueUZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUFueUZpZWxkKGludCBpbmRleCkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlQW55RmllbGRJc011dGFibGUoKTsKICAgICAgICBhbnlGaWVsZF8ucmVtb3ZlKGluZGV4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhbnlGaWVsZEJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuQnVpbGRlciBnZXRBbnlGaWVsZEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRBbnlGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55T3JCdWlsZGVyIGdldEFueUZpZWxkT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGFueUZpZWxkXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gYW55RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4gCiAgICAgICAgIGdldEFueUZpZWxkT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgaWYgKGFueUZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiBhbnlGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGFueUZpZWxkXyk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyIGFkZEFueUZpZWxkQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGdldEFueUZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyIGFkZEFueUZpZWxkQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGdldEFueUZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuQnVpbGRlcj4gCiAgICAgICAgIGdldEFueUZpZWxkQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiBnZXRBbnlGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICB9CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXI+IAogICAgICAgIGdldEFueUZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgYW55RmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBhbnlGaWVsZF8sCiAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIGFueUZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIGFueUZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkFwaT4gYXBpRmllbGRfID0KICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUFwaUZpZWxkSXNNdXRhYmxlKCkgewogICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgYXBpRmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5BcGk+KGFwaUZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaU9yQnVpbGRlcj4gYXBpRmllbGRCdWlsZGVyXzsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5BcGk+IGdldEFwaUZpZWxkTGlzdCgpIHsKICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChhcGlGaWVsZF8pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBhcGlGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0QXBpRmllbGRDb3VudCgpIHsKICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBhcGlGaWVsZF8uc2l6ZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBhcGlGaWVsZEJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSBnZXRBcGlGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBhcGlGaWVsZF8uZ2V0KGluZGV4KTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gYXBpRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0QXBpRmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSB2YWx1ZSkgewogICAgICBpZiAoYXBpRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVBcGlGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGFwaUZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldEFwaUZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUFwaUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgYXBpRmllbGRfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGFwaUZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkQXBpRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkgdmFsdWUpIHsKICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlQXBpRmllbGRJc011dGFibGUoKTsKICAgICAgICBhcGlGaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkQXBpRmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSB2YWx1ZSkgewogICAgICBpZiAoYXBpRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVBcGlGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGFwaUZpZWxkXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFwaUZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChhcGlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVBcGlGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGFwaUZpZWxkXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGFwaUZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRBcGlGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChhcGlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVBcGlGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGFwaUZpZWxkXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEFwaUZpZWxkKAogICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGk+IHZhbHVlcykgewogICAgICBpZiAoYXBpRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlQXBpRmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgYXBpRmllbGRfKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckFwaUZpZWxkKCkgewogICAgICBpZiAoYXBpRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgYXBpRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVBcGlGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUFwaUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgYXBpRmllbGRfLnJlbW92ZShpbmRleCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYXBpRmllbGRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLkJ1aWxkZXIgZ2V0QXBpRmllbGRCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZ2V0QXBpRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaU9yQnVpbGRlciBnZXRBcGlGaWVsZE9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBhcGlGaWVsZF8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGFwaUZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXI+IAogICAgICAgICBnZXRBcGlGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICAgIGlmIChhcGlGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gYXBpRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChhcGlGaWVsZF8pOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkuQnVpbGRlciBhZGRBcGlGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRBcGlGaWVsZEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkuQnVpbGRlciBhZGRBcGlGaWVsZEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRBcGlGaWVsZEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQXBpLkJ1aWxkZXI+IAogICAgICAgICBnZXRBcGlGaWVsZEJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gZ2V0QXBpRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGksIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpT3JCdWlsZGVyPiAKICAgICAgICBnZXRBcGlGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGFwaUZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgYXBpRmllbGRfLAogICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCksCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBhcGlGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBhcGlGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbj4gZHVyYXRpb25GaWVsZF8gPQogICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICBwcml2YXRlIHZvaWQgZW5zdXJlRHVyYXRpb25GaWVsZElzTXV0YWJsZSgpIHsKICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIGR1cmF0aW9uRmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbj4oZHVyYXRpb25GaWVsZF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25PckJ1aWxkZXI+IGR1cmF0aW9uRmllbGRCdWlsZGVyXzsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24+IGdldER1cmF0aW9uRmllbGRMaXN0KCkgewogICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZHVyYXRpb25GaWVsZF8pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RHVyYXRpb25GaWVsZENvdW50KCkgewogICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gZHVyYXRpb25GaWVsZF8uc2l6ZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGdldER1cmF0aW9uRmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmIChkdXJhdGlvbkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBkdXJhdGlvbkZpZWxkXy5nZXQoaW5kZXgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXREdXJhdGlvbkZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiB2YWx1ZSkgewogICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUR1cmF0aW9uRmllbGRJc011dGFibGUoKTsKICAgICAgICBkdXJhdGlvbkZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldER1cmF0aW9uRmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChkdXJhdGlvbkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUR1cmF0aW9uRmllbGRJc011dGFibGUoKTsKICAgICAgICBkdXJhdGlvbkZpZWxkXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZER1cmF0aW9uRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiB2YWx1ZSkgewogICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUR1cmF0aW9uRmllbGRJc011dGFibGUoKTsKICAgICAgICBkdXJhdGlvbkZpZWxkXy5hZGQodmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGR1cmF0aW9uRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGREdXJhdGlvbkZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiB2YWx1ZSkgewogICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUR1cmF0aW9uRmllbGRJc011dGFibGUoKTsKICAgICAgICBkdXJhdGlvbkZpZWxkXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZER1cmF0aW9uRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVEdXJhdGlvbkZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZHVyYXRpb25GaWVsZF8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkRHVyYXRpb25GaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24uQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlRHVyYXRpb25GaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGR1cmF0aW9uRmllbGRfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGR1cmF0aW9uRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRHVyYXRpb25GaWVsZCgKICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24+IHZhbHVlcykgewogICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVEdXJhdGlvbkZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGR1cmF0aW9uRmllbGRfKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1cmF0aW9uRmllbGQoKSB7CiAgICAgIGlmIChkdXJhdGlvbkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGR1cmF0aW9uRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVEdXJhdGlvbkZpZWxkKGludCBpbmRleCkgewogICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVEdXJhdGlvbkZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZHVyYXRpb25GaWVsZF8ucmVtb3ZlKGluZGV4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkdXJhdGlvbkZpZWxkQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5CdWlsZGVyIGdldER1cmF0aW9uRmllbGRCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZ2V0RHVyYXRpb25GaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyIGdldER1cmF0aW9uRmllbGRPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIGlmIChkdXJhdGlvbkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBkdXJhdGlvbkZpZWxkXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZHVyYXRpb25GaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyPiAKICAgICAgICAgZ2V0RHVyYXRpb25GaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICAgIGlmIChkdXJhdGlvbkZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZHVyYXRpb25GaWVsZF8pOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24uQnVpbGRlciBhZGREdXJhdGlvbkZpZWxkQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGdldER1cmF0aW9uRmllbGRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24uQnVpbGRlciBhZGREdXJhdGlvbkZpZWxkQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGdldER1cmF0aW9uRmllbGRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLkJ1aWxkZXI+IAogICAgICAgICBnZXREdXJhdGlvbkZpZWxkQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiBnZXREdXJhdGlvbkZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24sIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24uQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbk9yQnVpbGRlcj4gCiAgICAgICAgZ2V0RHVyYXRpb25GaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZHVyYXRpb25GaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGR1cmF0aW9uRmllbGRfLAogICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCksCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBkdXJhdGlvbkZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIGR1cmF0aW9uRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHk+IGVtcHR5RmllbGRfID0KICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUVtcHR5RmllbGRJc011dGFibGUoKSB7CiAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBlbXB0eUZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHk+KGVtcHR5RmllbGRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5T3JCdWlsZGVyPiBlbXB0eUZpZWxkQnVpbGRlcl87CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PiBnZXRFbXB0eUZpZWxkTGlzdCgpIHsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGVtcHR5RmllbGRfKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZW1wdHlGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEVtcHR5RmllbGRDb3VudCgpIHsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGVtcHR5RmllbGRfLnNpemUoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZW1wdHlGaWVsZEJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBnZXRFbXB0eUZpZWxkKGludCBpbmRleCkgewogICAgICBpZiAoZW1wdHlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gZW1wdHlGaWVsZF8uZ2V0KGluZGV4KTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZW1wdHlGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0RW1wdHlGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgdmFsdWUpIHsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVFbXB0eUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZW1wdHlGaWVsZF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRFbXB0eUZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoZW1wdHlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVFbXB0eUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZW1wdHlGaWVsZF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRFbXB0eUZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgdmFsdWUpIHsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVFbXB0eUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZW1wdHlGaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBlbXB0eUZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkRW1wdHlGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgdmFsdWUpIHsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVFbXB0eUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZW1wdHlGaWVsZF8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRFbXB0eUZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlRW1wdHlGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGVtcHR5RmllbGRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEVtcHR5RmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChlbXB0eUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUVtcHR5RmllbGRJc011dGFibGUoKTsKICAgICAgICBlbXB0eUZpZWxkXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBlbXB0eUZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEVtcHR5RmllbGQoCiAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PiB2YWx1ZXMpIHsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlRW1wdHlGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBlbXB0eUZpZWxkXyk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJFbXB0eUZpZWxkKCkgewogICAgICBpZiAoZW1wdHlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbXB0eUZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRW1wdHlGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlRW1wdHlGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGVtcHR5RmllbGRfLnJlbW92ZShpbmRleCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuQnVpbGRlciBnZXRFbXB0eUZpZWxkQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGdldEVtcHR5RmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eU9yQnVpbGRlciBnZXRFbXB0eUZpZWxkT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICBpZiAoZW1wdHlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gZW1wdHlGaWVsZF8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGVtcHR5RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eU9yQnVpbGRlcj4gCiAgICAgICAgIGdldEVtcHR5RmllbGRPckJ1aWxkZXJMaXN0KCkgewogICAgICBpZiAoZW1wdHlGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gZW1wdHlGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGVtcHR5RmllbGRfKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LkJ1aWxkZXIgYWRkRW1wdHlGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRFbXB0eUZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LkJ1aWxkZXIgYWRkRW1wdHlGaWVsZEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRFbXB0eUZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eS5CdWlsZGVyPiAKICAgICAgICAgZ2V0RW1wdHlGaWVsZEJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gZ2V0RW1wdHlGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICB9CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHlPckJ1aWxkZXI+IAogICAgICAgIGdldEVtcHR5RmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChlbXB0eUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVtcHR5RmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHksIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBlbXB0eUZpZWxkXywKICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgZW1wdHlGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBlbXB0eUZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaz4gZmllbGRNYXNrRmllbGRfID0KICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZpZWxkTWFza0ZpZWxkSXNNdXRhYmxlKCkgewogICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgZmllbGRNYXNrRmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2s+KGZpZWxkTWFza0ZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza09yQnVpbGRlcj4gZmllbGRNYXNrRmllbGRCdWlsZGVyXzsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrPiBnZXRGaWVsZE1hc2tGaWVsZExpc3QoKSB7CiAgICAgIGlmIChmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZmllbGRNYXNrRmllbGRfKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZmllbGRNYXNrRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGaWVsZE1hc2tGaWVsZENvdW50KCkgewogICAgICBpZiAoZmllbGRNYXNrRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFza0ZpZWxkXy5zaXplKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBnZXRGaWVsZE1hc2tGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBmaWVsZE1hc2tGaWVsZF8uZ2V0KGluZGV4KTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZmllbGRNYXNrRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkTWFza0ZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgdmFsdWUpIHsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRmllbGRNYXNrRmllbGRJc011dGFibGUoKTsKICAgICAgICBmaWVsZE1hc2tGaWVsZF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmllbGRNYXNrRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRNYXNrRmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoZmllbGRNYXNrRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlRmllbGRNYXNrRmllbGRJc011dGFibGUoKTsKICAgICAgICBmaWVsZE1hc2tGaWVsZF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmllbGRNYXNrRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRNYXNrRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgdmFsdWUpIHsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRmllbGRNYXNrRmllbGRJc011dGFibGUoKTsKICAgICAgICBmaWVsZE1hc2tGaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkTWFza0ZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgdmFsdWUpIHsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRmllbGRNYXNrRmllbGRJc011dGFibGUoKTsKICAgICAgICBmaWVsZE1hc2tGaWVsZF8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmllbGRNYXNrRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGRNYXNrRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2suQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUZpZWxkTWFza0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRNYXNrRmllbGRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmllbGRNYXNrRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZE1hc2tGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVGaWVsZE1hc2tGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGZpZWxkTWFza0ZpZWxkXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGaWVsZE1hc2tGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrPiB2YWx1ZXMpIHsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUZpZWxkTWFza0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIGZpZWxkTWFza0ZpZWxkXyk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmllbGRNYXNrRmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGRNYXNrRmllbGQoKSB7CiAgICAgIGlmIChmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBmaWVsZE1hc2tGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVGaWVsZE1hc2tGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUZpZWxkTWFza0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZmllbGRNYXNrRmllbGRfLnJlbW92ZShpbmRleCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmllbGRNYXNrRmllbGRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5CdWlsZGVyIGdldEZpZWxkTWFza0ZpZWxkQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFza0ZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrT3JCdWlsZGVyIGdldEZpZWxkTWFza0ZpZWxkT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICBpZiAoZmllbGRNYXNrRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFza0ZpZWxkXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZmllbGRNYXNrRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXI+IAogICAgICAgICBnZXRGaWVsZE1hc2tGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICAgIGlmIChmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gZmllbGRNYXNrRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChmaWVsZE1hc2tGaWVsZF8pOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLkJ1aWxkZXIgYWRkRmllbGRNYXNrRmllbGRCdWlsZGVyKCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXNrRmllbGRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2suZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5CdWlsZGVyIGFkZEZpZWxkTWFza0ZpZWxkQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGdldEZpZWxkTWFza0ZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLkJ1aWxkZXI+IAogICAgICAgICBnZXRGaWVsZE1hc2tGaWVsZEJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gZ2V0RmllbGRNYXNrRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2ssIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrT3JCdWlsZGVyPiAKICAgICAgICBnZXRGaWVsZE1hc2tGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaywgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2suQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgZmllbGRNYXNrRmllbGRfLAogICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCksCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBmaWVsZE1hc2tGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0PiBzb3VyY2VDb250ZXh0RmllbGRfID0KICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVNvdXJjZUNvbnRleHRGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ+KHNvdXJjZUNvbnRleHRGaWVsZF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHRPckJ1aWxkZXI+IHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ+IGdldFNvdXJjZUNvbnRleHRGaWVsZExpc3QoKSB7CiAgICAgIGlmIChzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHNvdXJjZUNvbnRleHRGaWVsZF8pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFNvdXJjZUNvbnRleHRGaWVsZENvdW50KCkgewogICAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBzb3VyY2VDb250ZXh0RmllbGRfLnNpemUoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBnZXRTb3VyY2VDb250ZXh0RmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmIChzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHNvdXJjZUNvbnRleHRGaWVsZF8uZ2V0KGluZGV4KTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFNvdXJjZUNvbnRleHRGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCB2YWx1ZSkgewogICAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlU291cmNlQ29udGV4dEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRTb3VyY2VDb250ZXh0RmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVTb3VyY2VDb250ZXh0RmllbGRJc011dGFibGUoKTsKICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFNvdXJjZUNvbnRleHRGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgdmFsdWUpIHsKICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVNvdXJjZUNvbnRleHRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFNvdXJjZUNvbnRleHRGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCB2YWx1ZSkgewogICAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlU291cmNlQ29udGV4dEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRTb3VyY2VDb250ZXh0RmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlU291cmNlQ29udGV4dEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkU291cmNlQ29udGV4dEZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlU291cmNlQ29udGV4dEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxTb3VyY2VDb250ZXh0RmllbGQoCiAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ+IHZhbHVlcykgewogICAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVNvdXJjZUNvbnRleHRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBzb3VyY2VDb250ZXh0RmllbGRfKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTb3VyY2VDb250ZXh0RmllbGQoKSB7CiAgICAgIGlmIChzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVNvdXJjZUNvbnRleHRGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVTb3VyY2VDb250ZXh0RmllbGRJc011dGFibGUoKTsKICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRfLnJlbW92ZShpbmRleCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuQnVpbGRlciBnZXRTb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZ2V0U291cmNlQ29udGV4dEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyIGdldFNvdXJjZUNvbnRleHRGaWVsZE9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gc291cmNlQ29udGV4dEZpZWxkXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyPiAKICAgICAgICAgZ2V0U291cmNlQ29udGV4dEZpZWxkT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3Qoc291cmNlQ29udGV4dEZpZWxkXyk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuQnVpbGRlciBhZGRTb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyKCkgewogICAgICByZXR1cm4gZ2V0U291cmNlQ29udGV4dEZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LkJ1aWxkZXIgYWRkU291cmNlQ29udGV4dEZpZWxkQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGdldFNvdXJjZUNvbnRleHRGaWVsZEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuQnVpbGRlcj4gCiAgICAgICAgIGdldFNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gZ2V0U291cmNlQ29udGV4dEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dE9yQnVpbGRlcj4gCiAgICAgICAgZ2V0U291cmNlQ29udGV4dEZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZF8sCiAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0PiBzdHJ1Y3RGaWVsZF8gPQogICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICBwcml2YXRlIHZvaWQgZW5zdXJlU3RydWN0RmllbGRJc011dGFibGUoKSB7CiAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICBzdHJ1Y3RGaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdD4oc3RydWN0RmllbGRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0T3JCdWlsZGVyPiBzdHJ1Y3RGaWVsZEJ1aWxkZXJfOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdD4gZ2V0U3RydWN0RmllbGRMaXN0KCkgewogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHN0cnVjdEZpZWxkXyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHN0cnVjdEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGludCBnZXRTdHJ1Y3RGaWVsZENvdW50KCkgewogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHN0cnVjdEZpZWxkXy5zaXplKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHN0cnVjdEZpZWxkQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IGdldFN0cnVjdEZpZWxkKGludCBpbmRleCkgewogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHN0cnVjdEZpZWxkXy5nZXQoaW5kZXgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBzdHJ1Y3RGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHJ1Y3RGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IHZhbHVlKSB7CiAgICAgIGlmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVN0cnVjdEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgc3RydWN0RmllbGRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHN0cnVjdEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0U3RydWN0RmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlU3RydWN0RmllbGRJc011dGFibGUoKTsKICAgICAgICBzdHJ1Y3RGaWVsZF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RydWN0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRTdHJ1Y3RGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCB2YWx1ZSkgewogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVTdHJ1Y3RGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHN0cnVjdEZpZWxkXy5hZGQodmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHN0cnVjdEZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRTdHJ1Y3RGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IHZhbHVlKSB7CiAgICAgIGlmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVN0cnVjdEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgc3RydWN0RmllbGRfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHN0cnVjdEZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkU3RydWN0RmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKHN0cnVjdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVN0cnVjdEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgc3RydWN0RmllbGRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RydWN0RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFN0cnVjdEZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKHN0cnVjdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVN0cnVjdEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgc3RydWN0RmllbGRfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHN0cnVjdEZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsU3RydWN0RmllbGQoCiAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdD4gdmFsdWVzKSB7CiAgICAgIGlmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVTdHJ1Y3RGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBzdHJ1Y3RGaWVsZF8pOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHN0cnVjdEZpZWxkQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RydWN0RmllbGQoKSB7CiAgICAgIGlmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBzdHJ1Y3RGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHN0cnVjdEZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVN0cnVjdEZpZWxkKGludCBpbmRleCkgewogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlU3RydWN0RmllbGRJc011dGFibGUoKTsKICAgICAgICBzdHJ1Y3RGaWVsZF8ucmVtb3ZlKGluZGV4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdHJ1Y3RGaWVsZEJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuQnVpbGRlciBnZXRTdHJ1Y3RGaWVsZEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRTdHJ1Y3RGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0T3JCdWlsZGVyIGdldFN0cnVjdEZpZWxkT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHN0cnVjdEZpZWxkXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gc3RydWN0RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdE9yQnVpbGRlcj4gCiAgICAgICAgIGdldFN0cnVjdEZpZWxkT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgaWYgKHN0cnVjdEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiBzdHJ1Y3RGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHN0cnVjdEZpZWxkXyk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5CdWlsZGVyIGFkZFN0cnVjdEZpZWxkQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGdldFN0cnVjdEZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0LmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5CdWlsZGVyIGFkZFN0cnVjdEZpZWxkQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGdldFN0cnVjdEZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuQnVpbGRlcj4gCiAgICAgICAgIGdldFN0cnVjdEZpZWxkQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiBnZXRTdHJ1Y3RGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICB9CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RPckJ1aWxkZXI+IAogICAgICAgIGdldFN0cnVjdEZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgc3RydWN0RmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0LCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdE9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBzdHJ1Y3RGaWVsZF8sCiAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIHN0cnVjdEZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIHN0cnVjdEZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcD4gdGltZXN0YW1wRmllbGRfID0KICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVRpbWVzdGFtcEZpZWxkSXNNdXRhYmxlKCkgewogICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgdGltZXN0YW1wRmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXA+KHRpbWVzdGFtcEZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcE9yQnVpbGRlcj4gdGltZXN0YW1wRmllbGRCdWlsZGVyXzsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXA+IGdldFRpbWVzdGFtcEZpZWxkTGlzdCgpIHsKICAgICAgaWYgKHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCh0aW1lc3RhbXBGaWVsZF8pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0VGltZXN0YW1wRmllbGRDb3VudCgpIHsKICAgICAgaWYgKHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiB0aW1lc3RhbXBGaWVsZF8uc2l6ZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBnZXRUaW1lc3RhbXBGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgaWYgKHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiB0aW1lc3RhbXBGaWVsZF8uZ2V0KGluZGV4KTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gdGltZXN0YW1wRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0VGltZXN0YW1wRmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB2YWx1ZSkgewogICAgICBpZiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVUaW1lc3RhbXBGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHRpbWVzdGFtcEZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFRpbWVzdGFtcEZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVRpbWVzdGFtcEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgdGltZXN0YW1wRmllbGRfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkVGltZXN0YW1wRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdmFsdWUpIHsKICAgICAgaWYgKHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlVGltZXN0YW1wRmllbGRJc011dGFibGUoKTsKICAgICAgICB0aW1lc3RhbXBGaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkVGltZXN0YW1wRmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB2YWx1ZSkgewogICAgICBpZiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVUaW1lc3RhbXBGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHRpbWVzdGFtcEZpZWxkXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFRpbWVzdGFtcEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmICh0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVUaW1lc3RhbXBGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHRpbWVzdGFtcEZpZWxkXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRUaW1lc3RhbXBGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmICh0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVUaW1lc3RhbXBGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHRpbWVzdGFtcEZpZWxkXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFRpbWVzdGFtcEZpZWxkKAogICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXA+IHZhbHVlcykgewogICAgICBpZiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlVGltZXN0YW1wRmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgdGltZXN0YW1wRmllbGRfKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhclRpbWVzdGFtcEZpZWxkKCkgewogICAgICBpZiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgdGltZXN0YW1wRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVUaW1lc3RhbXBGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgaWYgKHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVRpbWVzdGFtcEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgdGltZXN0YW1wRmllbGRfLnJlbW92ZShpbmRleCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGltZXN0YW1wRmllbGRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLkJ1aWxkZXIgZ2V0VGltZXN0YW1wRmllbGRCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZ2V0VGltZXN0YW1wRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcE9yQnVpbGRlciBnZXRUaW1lc3RhbXBGaWVsZE9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgaWYgKHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiB0aW1lc3RhbXBGaWVsZF8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBPckJ1aWxkZXI+IAogICAgICAgICBnZXRUaW1lc3RhbXBGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICAgIGlmICh0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gdGltZXN0YW1wRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCh0aW1lc3RhbXBGaWVsZF8pOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuQnVpbGRlciBhZGRUaW1lc3RhbXBGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRUaW1lc3RhbXBGaWVsZEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuQnVpbGRlciBhZGRUaW1lc3RhbXBGaWVsZEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRUaW1lc3RhbXBGaWVsZEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLkJ1aWxkZXI+IAogICAgICAgICBnZXRUaW1lc3RhbXBGaWVsZEJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gZ2V0VGltZXN0YW1wRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgfQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAsIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wT3JCdWlsZGVyPiAKICAgICAgICBnZXRUaW1lc3RhbXBGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgdGltZXN0YW1wRmllbGRfLAogICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCksCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICB0aW1lc3RhbXBGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlPiB0eXBlRmllbGRfID0KICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVR5cGVGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgIHR5cGVGaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGU+KHR5cGVGaWVsZF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGVPckJ1aWxkZXI+IHR5cGVGaWVsZEJ1aWxkZXJfOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVHlwZT4gZ2V0VHlwZUZpZWxkTGlzdCgpIHsKICAgICAgaWYgKHR5cGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QodHlwZUZpZWxkXyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHR5cGVGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGludCBnZXRUeXBlRmllbGRDb3VudCgpIHsKICAgICAgaWYgKHR5cGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gdHlwZUZpZWxkXy5zaXplKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHR5cGVGaWVsZEJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZSBnZXRUeXBlRmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHR5cGVGaWVsZF8uZ2V0KGluZGV4KTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gdHlwZUZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0VHlwZUZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHZhbHVlKSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVUeXBlRmllbGRJc011dGFibGUoKTsKICAgICAgICB0eXBlRmllbGRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHR5cGVGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0VHlwZUZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlVHlwZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgdHlwZUZpZWxkXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0eXBlRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFR5cGVGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdmFsdWUpIHsKICAgICAgaWYgKHR5cGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVR5cGVGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHR5cGVGaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0eXBlRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkVHlwZUZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHZhbHVlKSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVUeXBlRmllbGRJc011dGFibGUoKTsKICAgICAgICB0eXBlRmllbGRfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHR5cGVGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkVHlwZUZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAodHlwZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVR5cGVGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHR5cGVGaWVsZF8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0eXBlRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkVHlwZUZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlVHlwZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgdHlwZUZpZWxkXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0eXBlRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFR5cGVGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZT4gdmFsdWVzKSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlVHlwZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHR5cGVGaWVsZF8pOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHR5cGVGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVHlwZUZpZWxkKCkgewogICAgICBpZiAodHlwZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHR5cGVGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHR5cGVGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVR5cGVGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgaWYgKHR5cGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVUeXBlRmllbGRJc011dGFibGUoKTsKICAgICAgICB0eXBlRmllbGRfLnJlbW92ZShpbmRleCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdHlwZUZpZWxkQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZS5CdWlsZGVyIGdldFR5cGVGaWVsZEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRUeXBlRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZU9yQnVpbGRlciBnZXRUeXBlRmllbGRPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHR5cGVGaWVsZF8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHR5cGVGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlT3JCdWlsZGVyPiAKICAgICAgICAgZ2V0VHlwZUZpZWxkT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgaWYgKHR5cGVGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gdHlwZUZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QodHlwZUZpZWxkXyk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZS5CdWlsZGVyIGFkZFR5cGVGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRUeXBlRmllbGRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZS5CdWlsZGVyIGFkZFR5cGVGaWVsZEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRUeXBlRmllbGRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUuQnVpbGRlcj4gCiAgICAgICAgIGdldFR5cGVGaWVsZEJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gZ2V0VHlwZUZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0VHlwZUZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAodHlwZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHR5cGVGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIHR5cGVGaWVsZF8sCiAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIHR5cGVGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiB0eXBlRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+IGRvdWJsZUZpZWxkXyA9CiAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIHByaXZhdGUgdm9pZCBlbnN1cmVEb3VibGVGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgIGRvdWJsZUZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWU+KGRvdWJsZUZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZU9yQnVpbGRlcj4gZG91YmxlRmllbGRCdWlsZGVyXzsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBkb24ndCBhY3R1YWxseSBtYWtlIGEgbG90IG9mIHNlbnNlLCBidXQgdGhleSdyZSBub3QgcHJvaGliaXRlZC4uLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlPiBnZXREb3VibGVGaWVsZExpc3QoKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZG91YmxlRmllbGRfKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZG91YmxlRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBkb24ndCBhY3R1YWxseSBtYWtlIGEgbG90IG9mIHNlbnNlLCBidXQgdGhleSdyZSBub3QgcHJvaGliaXRlZC4uLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0RG91YmxlRmllbGRDb3VudCgpIHsKICAgICAgaWYgKGRvdWJsZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBkb3VibGVGaWVsZF8uc2l6ZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBkb3VibGVGaWVsZEJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGRvbid0IGFjdHVhbGx5IG1ha2UgYSBsb3Qgb2Ygc2Vuc2UsIGJ1dCB0aGV5J3JlIG5vdCBwcm9oaWJpdGVkLi4uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZ2V0RG91YmxlRmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gZG91YmxlRmllbGRfLmdldChpbmRleCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGRvdWJsZUZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGRvbid0IGFjdHVhbGx5IG1ha2UgYSBsb3Qgb2Ygc2Vuc2UsIGJ1dCB0aGV5J3JlIG5vdCBwcm9oaWJpdGVkLi4uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0RG91YmxlRmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZURvdWJsZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZG91YmxlRmllbGRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGRvdWJsZUZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgZG9uJ3QgYWN0dWFsbHkgbWFrZSBhIGxvdCBvZiBzZW5zZSwgYnV0IHRoZXkncmUgbm90IHByb2hpYml0ZWQuLi4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXREb3VibGVGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGRvdWJsZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZURvdWJsZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZG91YmxlRmllbGRfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGRvdWJsZUZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgZG9uJ3QgYWN0dWFsbHkgbWFrZSBhIGxvdCBvZiBzZW5zZSwgYnV0IHRoZXkncmUgbm90IHByb2hpYml0ZWQuLi4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGREb3VibGVGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZURvdWJsZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZG91YmxlRmllbGRfLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZG91YmxlRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGRvbid0IGFjdHVhbGx5IG1ha2UgYSBsb3Qgb2Ygc2Vuc2UsIGJ1dCB0aGV5J3JlIG5vdCBwcm9oaWJpdGVkLi4uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkRG91YmxlRmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZURvdWJsZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZG91YmxlRmllbGRfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGRvdWJsZUZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgZG9uJ3QgYWN0dWFsbHkgbWFrZSBhIGxvdCBvZiBzZW5zZSwgYnV0IHRoZXkncmUgbm90IHByb2hpYml0ZWQuLi4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGREb3VibGVGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVEb3VibGVGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGRvdWJsZUZpZWxkXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGRvdWJsZUZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBkb24ndCBhY3R1YWxseSBtYWtlIGEgbG90IG9mIHNlbnNlLCBidXQgdGhleSdyZSBub3QgcHJvaGliaXRlZC4uLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZERvdWJsZUZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoZG91YmxlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlRG91YmxlRmllbGRJc011dGFibGUoKTsKICAgICAgICBkb3VibGVGaWVsZF8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZG91YmxlRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBkb24ndCBhY3R1YWxseSBtYWtlIGEgbG90IG9mIHNlbnNlLCBidXQgdGhleSdyZSBub3QgcHJvaGliaXRlZC4uLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbERvdWJsZUZpZWxkKAogICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZT4gdmFsdWVzKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVEb3VibGVGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBkb3VibGVGaWVsZF8pOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGRvdWJsZUZpZWxkQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGRvbid0IGFjdHVhbGx5IG1ha2UgYSBsb3Qgb2Ygc2Vuc2UsIGJ1dCB0aGV5J3JlIG5vdCBwcm9oaWJpdGVkLi4uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEb3VibGVGaWVsZCgpIHsKICAgICAgaWYgKGRvdWJsZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGRvdWJsZUZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZG91YmxlRmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgZG9uJ3QgYWN0dWFsbHkgbWFrZSBhIGxvdCBvZiBzZW5zZSwgYnV0IHRoZXkncmUgbm90IHByb2hpYml0ZWQuLi4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVEb3VibGVGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgaWYgKGRvdWJsZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZURvdWJsZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZG91YmxlRmllbGRfLnJlbW92ZShpbmRleCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZG91YmxlRmllbGRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgZG9uJ3QgYWN0dWFsbHkgbWFrZSBhIGxvdCBvZiBzZW5zZSwgYnV0IHRoZXkncmUgbm90IHByb2hpYml0ZWQuLi4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5CdWlsZGVyIGdldERvdWJsZUZpZWxkQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGdldERvdWJsZUZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBkb24ndCBhY3R1YWxseSBtYWtlIGEgbG90IG9mIHNlbnNlLCBidXQgdGhleSdyZSBub3QgcHJvaGliaXRlZC4uLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlT3JCdWlsZGVyIGdldERvdWJsZUZpZWxkT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICBpZiAoZG91YmxlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGRvdWJsZUZpZWxkXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZG91YmxlRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgZG9uJ3QgYWN0dWFsbHkgbWFrZSBhIGxvdCBvZiBzZW5zZSwgYnV0IHRoZXkncmUgbm90IHByb2hpYml0ZWQuLi4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWVPckJ1aWxkZXI+IAogICAgICAgICBnZXREb3VibGVGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gZG91YmxlRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChkb3VibGVGaWVsZF8pOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBkb24ndCBhY3R1YWxseSBtYWtlIGEgbG90IG9mIHNlbnNlLCBidXQgdGhleSdyZSBub3QgcHJvaGliaXRlZC4uLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLkJ1aWxkZXIgYWRkRG91YmxlRmllbGRCdWlsZGVyKCkgewogICAgICByZXR1cm4gZ2V0RG91YmxlRmllbGRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBkb24ndCBhY3R1YWxseSBtYWtlIGEgbG90IG9mIHNlbnNlLCBidXQgdGhleSdyZSBub3QgcHJvaGliaXRlZC4uLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLkJ1aWxkZXIgYWRkRG91YmxlRmllbGRCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZ2V0RG91YmxlRmllbGRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgZG9uJ3QgYWN0dWFsbHkgbWFrZSBhIGxvdCBvZiBzZW5zZSwgYnV0IHRoZXkncmUgbm90IHByb2hpYml0ZWQuLi4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5CdWlsZGVyPiAKICAgICAgICAgZ2V0RG91YmxlRmllbGRCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIGdldERvdWJsZUZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0RG91YmxlRmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBkb3VibGVGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGRvdWJsZUZpZWxkXywKICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgZG91YmxlRmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gZG91YmxlRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZT4gZmxvYXRGaWVsZF8gPQogICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmxvYXRGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgIGZsb2F0RmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlPihmbG9hdEZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZU9yQnVpbGRlcj4gZmxvYXRGaWVsZEJ1aWxkZXJfOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlPiBnZXRGbG9hdEZpZWxkTGlzdCgpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZsb2F0RmllbGRfKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZmxvYXRGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZsb2F0RmllbGRDb3VudCgpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGZsb2F0RmllbGRfLnNpemUoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZmxvYXRGaWVsZEJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGdldEZsb2F0RmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmIChmbG9hdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBmbG9hdEZpZWxkXy5nZXQoaW5kZXgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBmbG9hdEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRGbG9hdEZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChmbG9hdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRmxvYXRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGZsb2F0RmllbGRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0RmxvYXRGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoZmxvYXRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVGbG9hdEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZmxvYXRGaWVsZF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmxvYXRGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRGbG9hdEZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoZmxvYXRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUZsb2F0RmllbGRJc011dGFibGUoKTsKICAgICAgICBmbG9hdEZpZWxkXy5hZGQodmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRGbG9hdEZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChmbG9hdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlRmxvYXRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGZsb2F0RmllbGRfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkRmxvYXRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlRmxvYXRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGZsb2F0RmllbGRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmxvYXRGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZsb2F0RmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlRmxvYXRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGZsb2F0RmllbGRfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsRmxvYXRGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZT4gdmFsdWVzKSB7CiAgICAgIGlmIChmbG9hdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUZsb2F0RmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgZmxvYXRGaWVsZF8pOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmxvYXRGaWVsZCgpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZmxvYXRGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZsb2F0RmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmIChmbG9hdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUZsb2F0RmllbGRJc011dGFibGUoKTsKICAgICAgICBmbG9hdEZpZWxkXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuQnVpbGRlciBnZXRGbG9hdEZpZWxkQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGdldEZsb2F0RmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlT3JCdWlsZGVyIGdldEZsb2F0RmllbGRPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIGlmIChmbG9hdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBmbG9hdEZpZWxkXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZmxvYXRGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWVPckJ1aWxkZXI+IAogICAgICAgICBnZXRGbG9hdEZpZWxkT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGZsb2F0RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChmbG9hdEZpZWxkXyk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLkJ1aWxkZXIgYWRkRmxvYXRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRGbG9hdEZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5CdWlsZGVyIGFkZEZsb2F0RmllbGRCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZ2V0RmxvYXRGaWVsZEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLkJ1aWxkZXI+IAogICAgICAgICBnZXRGbG9hdEZpZWxkQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiBnZXRGbG9hdEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0RmxvYXRGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZmxvYXRGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGZsb2F0RmllbGRfLAogICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCksCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBmbG9hdEZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIGZsb2F0RmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZT4gaW50NjRGaWVsZF8gPQogICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICBwcml2YXRlIHZvaWQgZW5zdXJlSW50NjRGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgIGludDY0RmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPihpbnQ2NEZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZU9yQnVpbGRlcj4gaW50NjRGaWVsZEJ1aWxkZXJfOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPiBnZXRJbnQ2NEZpZWxkTGlzdCgpIHsKICAgICAgaWYgKGludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGludDY0RmllbGRfKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gaW50NjRGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEludDY0RmllbGRDb3VudCgpIHsKICAgICAgaWYgKGludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGludDY0RmllbGRfLnNpemUoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gaW50NjRGaWVsZEJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGdldEludDY0RmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmIChpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBpbnQ2NEZpZWxkXy5nZXQoaW5kZXgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBpbnQ2NEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRJbnQ2NEZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlSW50NjRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGludDY0RmllbGRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0SW50NjRGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoaW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVJbnQ2NEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgaW50NjRGaWVsZF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaW50NjRGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRJbnQ2NEZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoaW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUludDY0RmllbGRJc011dGFibGUoKTsKICAgICAgICBpbnQ2NEZpZWxkXy5hZGQodmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRJbnQ2NEZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlSW50NjRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGludDY0RmllbGRfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkSW50NjRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlSW50NjRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGludDY0RmllbGRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaW50NjRGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEludDY0RmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlSW50NjRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGludDY0RmllbGRfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsSW50NjRGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZT4gdmFsdWVzKSB7CiAgICAgIGlmIChpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUludDY0RmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgaW50NjRGaWVsZF8pOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50NjRGaWVsZCgpIHsKICAgICAgaWYgKGludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaW50NjRGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDY0RmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmIChpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUludDY0RmllbGRJc011dGFibGUoKTsKICAgICAgICBpbnQ2NEZpZWxkXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuQnVpbGRlciBnZXRJbnQ2NEZpZWxkQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGdldEludDY0RmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyIGdldEludDY0RmllbGRPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIGlmIChpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBpbnQ2NEZpZWxkXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gaW50NjRGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWVPckJ1aWxkZXI+IAogICAgICAgICBnZXRJbnQ2NEZpZWxkT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgaWYgKGludDY0RmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGludDY0RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChpbnQ2NEZpZWxkXyk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLkJ1aWxkZXIgYWRkSW50NjRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRJbnQ2NEZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5CdWlsZGVyIGFkZEludDY0RmllbGRCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZ2V0SW50NjRGaWVsZEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLkJ1aWxkZXI+IAogICAgICAgICBnZXRJbnQ2NEZpZWxkQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiBnZXRJbnQ2NEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0SW50NjRGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKGludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaW50NjRGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGludDY0RmllbGRfLAogICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCksCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBpbnQ2NEZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDY0RmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWU+IHVpbnQ2NEZpZWxkXyA9CiAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIHByaXZhdGUgdm9pZCBlbnN1cmVVaW50NjRGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgIHVpbnQ2NEZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWU+KHVpbnQ2NEZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZU9yQnVpbGRlcj4gdWludDY0RmllbGRCdWlsZGVyXzsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZT4gZ2V0VWludDY0RmllbGRMaXN0KCkgewogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHVpbnQ2NEZpZWxkXyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHVpbnQ2NEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGludCBnZXRVaW50NjRGaWVsZENvdW50KCkgewogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHVpbnQ2NEZpZWxkXy5zaXplKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHVpbnQ2NEZpZWxkQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgZ2V0VWludDY0RmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmICh1aW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gdWludDY0RmllbGRfLmdldChpbmRleCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHVpbnQ2NEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFVpbnQ2NEZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVVaW50NjRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHVpbnQ2NEZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB1aW50NjRGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFVpbnQ2NEZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlVWludDY0RmllbGRJc011dGFibGUoKTsKICAgICAgICB1aW50NjRGaWVsZF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdWludDY0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRVaW50NjRGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHZhbHVlKSB7CiAgICAgIGlmICh1aW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVVpbnQ2NEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgdWludDY0RmllbGRfLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdWludDY0RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFVpbnQ2NEZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVVaW50NjRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHVpbnQ2NEZpZWxkXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB1aW50NjRGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFVpbnQ2NEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKHVpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVVpbnQ2NEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgdWludDY0RmllbGRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdWludDY0RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFVpbnQ2NEZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlVWludDY0RmllbGRJc011dGFibGUoKTsKICAgICAgICB1aW50NjRGaWVsZF8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdWludDY0RmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxVaW50NjRGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWU+IHZhbHVlcykgewogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlVWludDY0RmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgdWludDY0RmllbGRfKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB1aW50NjRGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVpbnQ2NEZpZWxkKCkgewogICAgICBpZiAodWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgdWludDY0RmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB1aW50NjRGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVVaW50NjRGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgaWYgKHVpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVVpbnQ2NEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgdWludDY0RmllbGRfLnJlbW92ZShpbmRleCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdWludDY0RmllbGRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuQnVpbGRlciBnZXRVaW50NjRGaWVsZEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRVaW50NjRGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXIgZ2V0VWludDY0RmllbGRPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIGlmICh1aW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gdWludDY0RmllbGRfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgIHJldHVybiB1aW50NjRGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXI+IAogICAgICAgICBnZXRVaW50NjRGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICAgIGlmICh1aW50NjRGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gdWludDY0RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCh1aW50NjRGaWVsZF8pOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5CdWlsZGVyIGFkZFVpbnQ2NEZpZWxkQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGdldFVpbnQ2NEZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuQnVpbGRlciBhZGRVaW50NjRGaWVsZEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRVaW50NjRGaWVsZEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5CdWlsZGVyPiAKICAgICAgICAgZ2V0VWludDY0RmllbGRCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIGdldFVpbnQ2NEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0VWludDY0RmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmICh1aW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICB1aW50NjRGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIHVpbnQ2NEZpZWxkXywKICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgdWludDY0RmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gdWludDY0RmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZT4gaW50MzJGaWVsZF8gPQogICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICBwcml2YXRlIHZvaWQgZW5zdXJlSW50MzJGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgIGludDMyRmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlPihpbnQzMkZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZU9yQnVpbGRlcj4gaW50MzJGaWVsZEJ1aWxkZXJfOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlPiBnZXRJbnQzMkZpZWxkTGlzdCgpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGludDMyRmllbGRfKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gaW50MzJGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEludDMyRmllbGRDb3VudCgpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGludDMyRmllbGRfLnNpemUoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gaW50MzJGaWVsZEJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGdldEludDMyRmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmIChpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBpbnQzMkZpZWxkXy5nZXQoaW5kZXgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBpbnQzMkZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRJbnQzMkZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlSW50MzJGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGludDMyRmllbGRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDMyRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0SW50MzJGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoaW50MzJGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVJbnQzMkZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgaW50MzJGaWVsZF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaW50MzJGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRJbnQzMkZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoaW50MzJGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUludDMyRmllbGRJc011dGFibGUoKTsKICAgICAgICBpbnQzMkZpZWxkXy5hZGQodmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDMyRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRJbnQzMkZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlSW50MzJGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGludDMyRmllbGRfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDMyRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkSW50MzJGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlSW50MzJGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGludDMyRmllbGRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaW50MzJGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEludDMyRmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlSW50MzJGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGludDMyRmllbGRfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDMyRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsSW50MzJGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZT4gdmFsdWVzKSB7CiAgICAgIGlmIChpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUludDMyRmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgaW50MzJGaWVsZF8pOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDMyRmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJGaWVsZCgpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaW50MzJGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDMyRmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUludDMyRmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmIChpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUludDMyRmllbGRJc011dGFibGUoKTsKICAgICAgICBpbnQzMkZpZWxkXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDMyRmllbGRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuQnVpbGRlciBnZXRJbnQzMkZpZWxkQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGdldEludDMyRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlT3JCdWlsZGVyIGdldEludDMyRmllbGRPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIGlmIChpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBpbnQzMkZpZWxkXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gaW50MzJGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWVPckJ1aWxkZXI+IAogICAgICAgICBnZXRJbnQzMkZpZWxkT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGludDMyRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChpbnQzMkZpZWxkXyk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLkJ1aWxkZXIgYWRkSW50MzJGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMkZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5CdWlsZGVyIGFkZEludDMyRmllbGRCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZ2V0SW50MzJGaWVsZEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLkJ1aWxkZXI+IAogICAgICAgICBnZXRJbnQzMkZpZWxkQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiBnZXRJbnQzMkZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0SW50MzJGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaW50MzJGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGludDMyRmllbGRfLAogICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCksCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBpbnQzMkZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIGludDMyRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+IHVpbnQzMkZpZWxkXyA9CiAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIHByaXZhdGUgdm9pZCBlbnN1cmVVaW50MzJGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgIHVpbnQzMkZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+KHVpbnQzMkZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZU9yQnVpbGRlcj4gdWludDMyRmllbGRCdWlsZGVyXzsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZT4gZ2V0VWludDMyRmllbGRMaXN0KCkgewogICAgICBpZiAodWludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHVpbnQzMkZpZWxkXyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHVpbnQzMkZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGludCBnZXRVaW50MzJGaWVsZENvdW50KCkgewogICAgICBpZiAodWludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHVpbnQzMkZpZWxkXy5zaXplKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHVpbnQzMkZpZWxkQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgZ2V0VWludDMyRmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmICh1aW50MzJGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gdWludDMyRmllbGRfLmdldChpbmRleCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHVpbnQzMkZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFVpbnQzMkZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAodWludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVVaW50MzJGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHVpbnQzMkZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB1aW50MzJGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFVpbnQzMkZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAodWludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlVWludDMyRmllbGRJc011dGFibGUoKTsKICAgICAgICB1aW50MzJGaWVsZF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdWludDMyRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRVaW50MzJGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHZhbHVlKSB7CiAgICAgIGlmICh1aW50MzJGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVVpbnQzMkZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgdWludDMyRmllbGRfLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdWludDMyRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFVpbnQzMkZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAodWludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVVaW50MzJGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHVpbnQzMkZpZWxkXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB1aW50MzJGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFVpbnQzMkZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVVpbnQzMkZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgdWludDMyRmllbGRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdWludDMyRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFVpbnQzMkZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAodWludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlVWludDMyRmllbGRJc011dGFibGUoKTsKICAgICAgICB1aW50MzJGaWVsZF8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdWludDMyRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxVaW50MzJGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWU+IHZhbHVlcykgewogICAgICBpZiAodWludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlVWludDMyRmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgdWludDMyRmllbGRfKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB1aW50MzJGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVpbnQzMkZpZWxkKCkgewogICAgICBpZiAodWludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgdWludDMyRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB1aW50MzJGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVVaW50MzJGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVVpbnQzMkZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgdWludDMyRmllbGRfLnJlbW92ZShpbmRleCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdWludDMyRmllbGRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlciBnZXRVaW50MzJGaWVsZEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRVaW50MzJGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWVPckJ1aWxkZXIgZ2V0VWludDMyRmllbGRPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIGlmICh1aW50MzJGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gdWludDMyRmllbGRfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgIHJldHVybiB1aW50MzJGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWVPckJ1aWxkZXI+IAogICAgICAgICBnZXRVaW50MzJGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICAgIGlmICh1aW50MzJGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gdWludDMyRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdCh1aW50MzJGaWVsZF8pOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5CdWlsZGVyIGFkZFVpbnQzMkZpZWxkQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGdldFVpbnQzMkZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlciBhZGRVaW50MzJGaWVsZEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRVaW50MzJGaWVsZEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5CdWlsZGVyPiAKICAgICAgICAgZ2V0VWludDMyRmllbGRCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIGdldFVpbnQzMkZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0VWludDMyRmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmICh1aW50MzJGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICB1aW50MzJGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIHVpbnQzMkZpZWxkXywKICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgdWludDMyRmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gdWludDMyRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlPiBib29sRmllbGRfID0KICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUJvb2xGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgIGJvb2xGaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZT4oYm9vbEZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlcj4gYm9vbEZpZWxkQnVpbGRlcl87CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWU+IGdldEJvb2xGaWVsZExpc3QoKSB7CiAgICAgIGlmIChib29sRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGJvb2xGaWVsZF8pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBib29sRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0Qm9vbEZpZWxkQ291bnQoKSB7CiAgICAgIGlmIChib29sRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGJvb2xGaWVsZF8uc2l6ZSgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBib29sRmllbGRCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBnZXRCb29sRmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmIChib29sRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGJvb2xGaWVsZF8uZ2V0KGluZGV4KTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gYm9vbEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0Qm9vbEZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUJvb2xGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGJvb2xGaWVsZF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRCb29sRmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoYm9vbEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUJvb2xGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGJvb2xGaWVsZF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRCb29sRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUJvb2xGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGJvb2xGaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBib29sRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkQm9vbEZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUJvb2xGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGJvb2xGaWVsZF8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRCb29sRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVCb29sRmllbGRJc011dGFibGUoKTsKICAgICAgICBib29sRmllbGRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEJvb2xGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChib29sRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlQm9vbEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgYm9vbEZpZWxkXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBib29sRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEJvb2xGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlPiB2YWx1ZXMpIHsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVCb29sRmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgYm9vbEZpZWxkXyk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJCb29sRmllbGQoKSB7CiAgICAgIGlmIChib29sRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgYm9vbEZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlQm9vbEZpZWxkKGludCBpbmRleCkgewogICAgICBpZiAoYm9vbEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUJvb2xGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGJvb2xGaWVsZF8ucmVtb3ZlKGluZGV4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBib29sRmllbGRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuQnVpbGRlciBnZXRCb29sRmllbGRCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZ2V0Qm9vbEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlciBnZXRCb29sRmllbGRPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIGlmIChib29sRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGJvb2xGaWVsZF8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGJvb2xGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVPckJ1aWxkZXI+IAogICAgICAgICBnZXRCb29sRmllbGRPckJ1aWxkZXJMaXN0KCkgewogICAgICBpZiAoYm9vbEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiBib29sRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChib29sRmllbGRfKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuQnVpbGRlciBhZGRCb29sRmllbGRCdWlsZGVyKCkgewogICAgICByZXR1cm4gZ2V0Qm9vbEZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLkJ1aWxkZXIgYWRkQm9vbEZpZWxkQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGdldEJvb2xGaWVsZEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuQnVpbGRlcj4gCiAgICAgICAgIGdldEJvb2xGaWVsZEJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gZ2V0Qm9vbEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0Qm9vbEZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoYm9vbEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGJvb2xGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGJvb2xGaWVsZF8sCiAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIGJvb2xGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBib29sRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWU+IHN0cmluZ0ZpZWxkXyA9CiAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIHByaXZhdGUgdm9pZCBlbnN1cmVTdHJpbmdGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgIHN0cmluZ0ZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWU+KHN0cmluZ0ZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZU9yQnVpbGRlcj4gc3RyaW5nRmllbGRCdWlsZGVyXzsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZT4gZ2V0U3RyaW5nRmllbGRMaXN0KCkgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHN0cmluZ0ZpZWxkXyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHN0cmluZ0ZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGludCBnZXRTdHJpbmdGaWVsZENvdW50KCkgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHN0cmluZ0ZpZWxkXy5zaXplKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHN0cmluZ0ZpZWxkQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgZ2V0U3RyaW5nRmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gc3RyaW5nRmllbGRfLmdldChpbmRleCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHN0cmluZ0ZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cmluZ0ZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVTdHJpbmdGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHN0cmluZ0ZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cmluZ0ZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlU3RyaW5nRmllbGRJc011dGFibGUoKTsKICAgICAgICBzdHJpbmdGaWVsZF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RyaW5nRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRTdHJpbmdGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVN0cmluZ0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgc3RyaW5nRmllbGRfLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RyaW5nRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFN0cmluZ0ZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVTdHJpbmdGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHN0cmluZ0ZpZWxkXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFN0cmluZ0ZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKHN0cmluZ0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVN0cmluZ0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgc3RyaW5nRmllbGRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RyaW5nRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZFN0cmluZ0ZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlU3RyaW5nRmllbGRJc011dGFibGUoKTsKICAgICAgICBzdHJpbmdGaWVsZF8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RyaW5nRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxTdHJpbmdGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWU+IHZhbHVlcykgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlU3RyaW5nRmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgc3RyaW5nRmllbGRfKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZ0ZpZWxkKCkgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgc3RyaW5nRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVTdHJpbmdGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgaWYgKHN0cmluZ0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZVN0cmluZ0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgc3RyaW5nRmllbGRfLnJlbW92ZShpbmRleCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RyaW5nRmllbGRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuQnVpbGRlciBnZXRTdHJpbmdGaWVsZEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRTdHJpbmdGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWVPckJ1aWxkZXIgZ2V0U3RyaW5nRmllbGRPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gc3RyaW5nRmllbGRfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgIHJldHVybiBzdHJpbmdGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWVPckJ1aWxkZXI+IAogICAgICAgICBnZXRTdHJpbmdGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gc3RyaW5nRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChzdHJpbmdGaWVsZF8pOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyIGFkZFN0cmluZ0ZpZWxkQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGdldFN0cmluZ0ZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuQnVpbGRlciBhZGRTdHJpbmdGaWVsZEJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBnZXRTdHJpbmdGaWVsZEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyPiAKICAgICAgICAgZ2V0U3RyaW5nRmllbGRCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIGdldFN0cmluZ0ZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0U3RyaW5nRmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIHN0cmluZ0ZpZWxkXywKICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgc3RyaW5nRmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gc3RyaW5nRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZT4gYnl0ZXNGaWVsZF8gPQogICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICBwcml2YXRlIHZvaWQgZW5zdXJlQnl0ZXNGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgIGJ5dGVzRmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlPihieXRlc0ZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZU9yQnVpbGRlcj4gYnl0ZXNGaWVsZEJ1aWxkZXJfOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlPiBnZXRCeXRlc0ZpZWxkTGlzdCgpIHsKICAgICAgaWYgKGJ5dGVzRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGJ5dGVzRmllbGRfKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gYnl0ZXNGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEJ5dGVzRmllbGRDb3VudCgpIHsKICAgICAgaWYgKGJ5dGVzRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGJ5dGVzRmllbGRfLnNpemUoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gYnl0ZXNGaWVsZEJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGdldEJ5dGVzRmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmIChieXRlc0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBieXRlc0ZpZWxkXy5nZXQoaW5kZXgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBieXRlc0ZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRCeXRlc0ZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChieXRlc0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlQnl0ZXNGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGJ5dGVzRmllbGRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0Qnl0ZXNGaWVsZCgKICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoYnl0ZXNGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbnN1cmVCeXRlc0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgYnl0ZXNGaWVsZF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnl0ZXNGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRCeXRlc0ZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoYnl0ZXNGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZUJ5dGVzRmllbGRJc011dGFibGUoKTsKICAgICAgICBieXRlc0ZpZWxkXy5hZGQodmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBhZGRCeXRlc0ZpZWxkKAogICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChieXRlc0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlQnl0ZXNGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGJ5dGVzRmllbGRfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkQnl0ZXNGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGJ5dGVzRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlQnl0ZXNGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGJ5dGVzRmllbGRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnl0ZXNGaWVsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGFkZEJ5dGVzRmllbGQoCiAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGJ5dGVzRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZW5zdXJlQnl0ZXNGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGJ5dGVzRmllbGRfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsQnl0ZXNGaWVsZCgKICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZT4gdmFsdWVzKSB7CiAgICAgIGlmIChieXRlc0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUJ5dGVzRmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgYnl0ZXNGaWVsZF8pOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQnl0ZXNGaWVsZCgpIHsKICAgICAgaWYgKGJ5dGVzRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgYnl0ZXNGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUJ5dGVzRmllbGQoaW50IGluZGV4KSB7CiAgICAgIGlmIChieXRlc0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVuc3VyZUJ5dGVzRmllbGRJc011dGFibGUoKTsKICAgICAgICBieXRlc0ZpZWxkXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuQnVpbGRlciBnZXRCeXRlc0ZpZWxkQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGdldEJ5dGVzRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyIGdldEJ5dGVzRmllbGRPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIGlmIChieXRlc0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBieXRlc0ZpZWxkXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gYnl0ZXNGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWVPckJ1aWxkZXI+IAogICAgICAgICBnZXRCeXRlc0ZpZWxkT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgaWYgKGJ5dGVzRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGJ5dGVzRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChieXRlc0ZpZWxkXyk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLkJ1aWxkZXIgYWRkQnl0ZXNGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBnZXRCeXRlc0ZpZWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5CdWlsZGVyIGFkZEJ5dGVzRmllbGRCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gZ2V0Qnl0ZXNGaWVsZEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLkJ1aWxkZXI+IAogICAgICAgICBnZXRCeXRlc0ZpZWxkQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiBnZXRCeXRlc0ZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgIH0KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0Qnl0ZXNGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKGJ5dGVzRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgYnl0ZXNGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGJ5dGVzRmllbGRfLAogICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCksCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBieXRlc0ZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIGJ5dGVzRmllbGRCdWlsZGVyXzsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgfQoKCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5SZXBlYXRlZFdlbGxLbm93blR5cGVzKQogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMpCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMgREVGQVVMVF9JTlNUQU5DRTsKICBzdGF0aWMgewogICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuUmVwZWF0ZWRXZWxsS25vd25UeXBlcygpOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuUmVwZWF0ZWRXZWxsS25vd25UeXBlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlcGVhdGVkV2VsbEtub3duVHlwZXM+CiAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFJlcGVhdGVkV2VsbEtub3duVHlwZXM+KCkgewogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIFJlcGVhdGVkV2VsbEtub3duVHlwZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICB0cnkgewogICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICB9CiAgfTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXBlYXRlZFdlbGxLbm93blR5cGVzPiBwYXJzZXIoKSB7CiAgICByZXR1cm4gUEFSU0VSOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXBlYXRlZFdlbGxLbm93blR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogIH0KCn0KClBLAwQKAAAAAAAAACEAmcKrHfM5AADzOQAAPQAAAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdC9SZXBlYXRlZFdlbGxLbm93blR5cGVzT3JCdWlsZGVyLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF93ZWxsX2tub3duX3R5cGVzLnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3Q7CgpwdWJsaWMgaW50ZXJmYWNlIFJlcGVhdGVkV2VsbEtub3duVHlwZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlJlcGVhdGVkV2VsbEtub3duVHlwZXMpCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkFueT4gCiAgICAgIGdldEFueUZpZWxkTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGdldEFueUZpZWxkKGludCBpbmRleCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICovCiAgaW50IGdldEFueUZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXI+IAogICAgICBnZXRBbnlGaWVsZE9yQnVpbGRlckxpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlciBnZXRBbnlGaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KTsKCiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5BcGk+IAogICAgICBnZXRBcGlGaWVsZExpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSBnZXRBcGlGaWVsZChpbnQgaW5kZXgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAqLwogIGludCBnZXRBcGlGaWVsZENvdW50KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuQXBpT3JCdWlsZGVyPiAKICAgICAgZ2V0QXBpRmllbGRPckJ1aWxkZXJMaXN0KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXIgZ2V0QXBpRmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCk7CgogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uPiAKICAgICAgZ2V0RHVyYXRpb25GaWVsZExpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBnZXREdXJhdGlvbkZpZWxkKGludCBpbmRleCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAqLwogIGludCBnZXREdXJhdGlvbkZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25PckJ1aWxkZXI+IAogICAgICBnZXREdXJhdGlvbkZpZWxkT3JCdWlsZGVyTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyIGdldER1cmF0aW9uRmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCk7CgogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5PiAKICAgICAgZ2V0RW1wdHlGaWVsZExpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBnZXRFbXB0eUZpZWxkKGludCBpbmRleCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAqLwogIGludCBnZXRFbXB0eUZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHlPckJ1aWxkZXI+IAogICAgICBnZXRFbXB0eUZpZWxkT3JCdWlsZGVyTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5T3JCdWlsZGVyIGdldEVtcHR5RmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCk7CgogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaz4gCiAgICAgIGdldEZpZWxkTWFza0ZpZWxkTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBnZXRGaWVsZE1hc2tGaWVsZChpbnQgaW5kZXgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgKi8KICBpbnQgZ2V0RmllbGRNYXNrRmllbGRDb3VudCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXI+IAogICAgICBnZXRGaWVsZE1hc2tGaWVsZE9yQnVpbGRlckxpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tPckJ1aWxkZXIgZ2V0RmllbGRNYXNrRmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCk7CgogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dD4gCiAgICAgIGdldFNvdXJjZUNvbnRleHRGaWVsZExpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgZ2V0U291cmNlQ29udGV4dEZpZWxkKGludCBpbmRleCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICovCiAgaW50IGdldFNvdXJjZUNvbnRleHRGaWVsZENvdW50KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dE9yQnVpbGRlcj4gCiAgICAgIGdldFNvdXJjZUNvbnRleHRGaWVsZE9yQnVpbGRlckxpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHRPckJ1aWxkZXIgZ2V0U291cmNlQ29udGV4dEZpZWxkT3JCdWlsZGVyKAogICAgICBpbnQgaW5kZXgpOwoKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdD4gCiAgICAgIGdldFN0cnVjdEZpZWxkTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IGdldFN0cnVjdEZpZWxkKGludCBpbmRleCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICovCiAgaW50IGdldFN0cnVjdEZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RPckJ1aWxkZXI+IAogICAgICBnZXRTdHJ1Y3RGaWVsZE9yQnVpbGRlckxpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdE9yQnVpbGRlciBnZXRTdHJ1Y3RGaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KTsKCiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXA+IAogICAgICBnZXRUaW1lc3RhbXBGaWVsZExpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBnZXRUaW1lc3RhbXBGaWVsZChpbnQgaW5kZXgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAqLwogIGludCBnZXRUaW1lc3RhbXBGaWVsZENvdW50KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wT3JCdWlsZGVyPiAKICAgICAgZ2V0VGltZXN0YW1wRmllbGRPckJ1aWxkZXJMaXN0KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBPckJ1aWxkZXIgZ2V0VGltZXN0YW1wRmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCk7CgogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlPiAKICAgICAgZ2V0VHlwZUZpZWxkTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlIGdldFR5cGVGaWVsZChpbnQgaW5kZXgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICovCiAgaW50IGdldFR5cGVGaWVsZENvdW50KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlT3JCdWlsZGVyPiAKICAgICAgZ2V0VHlwZUZpZWxkT3JCdWlsZGVyTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlT3JCdWlsZGVyIGdldFR5cGVGaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KTsKCiAgLyoqCiAgICogPHByZT4KICAgKiBUaGVzZSBkb24ndCBhY3R1YWxseSBtYWtlIGEgbG90IG9mIHNlbnNlLCBidXQgdGhleSdyZSBub3QgcHJvaGliaXRlZC4uLgogICAqIDwvcHJlPgogICAqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZT4gCiAgICAgIGdldERvdWJsZUZpZWxkTGlzdCgpOwogIC8qKgogICAqIDxwcmU+CiAgICogVGhlc2UgZG9uJ3QgYWN0dWFsbHkgbWFrZSBhIGxvdCBvZiBzZW5zZSwgYnV0IHRoZXkncmUgbm90IHByb2hpYml0ZWQuLi4KICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZ2V0RG91YmxlRmllbGQoaW50IGluZGV4KTsKICAvKioKICAgKiA8cHJlPgogICAqIFRoZXNlIGRvbid0IGFjdHVhbGx5IG1ha2UgYSBsb3Qgb2Ygc2Vuc2UsIGJ1dCB0aGV5J3JlIG5vdCBwcm9oaWJpdGVkLi4uCiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgKi8KICBpbnQgZ2V0RG91YmxlRmllbGRDb3VudCgpOwogIC8qKgogICAqIDxwcmU+CiAgICogVGhlc2UgZG9uJ3QgYWN0dWFsbHkgbWFrZSBhIGxvdCBvZiBzZW5zZSwgYnV0IHRoZXkncmUgbm90IHByb2hpYml0ZWQuLi4KICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlT3JCdWlsZGVyPiAKICAgICAgZ2V0RG91YmxlRmllbGRPckJ1aWxkZXJMaXN0KCk7CiAgLyoqCiAgICogPHByZT4KICAgKiBUaGVzZSBkb24ndCBhY3R1YWxseSBtYWtlIGEgbG90IG9mIHNlbnNlLCBidXQgdGhleSdyZSBub3QgcHJvaGliaXRlZC4uLgogICAqIDwvcHJlPgogICAqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZU9yQnVpbGRlciBnZXREb3VibGVGaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KTsKCiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZT4gCiAgICAgIGdldEZsb2F0RmllbGRMaXN0KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBnZXRGbG9hdEZpZWxkKGludCBpbmRleCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAqLwogIGludCBnZXRGbG9hdEZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZU9yQnVpbGRlcj4gCiAgICAgIGdldEZsb2F0RmllbGRPckJ1aWxkZXJMaXN0KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZU9yQnVpbGRlciBnZXRGbG9hdEZpZWxkT3JCdWlsZGVyKAogICAgICBpbnQgaW5kZXgpOwoKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlPiAKICAgICAgZ2V0SW50NjRGaWVsZExpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGdldEludDY0RmllbGQoaW50IGluZGV4KTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICovCiAgaW50IGdldEludDY0RmllbGRDb3VudCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyPiAKICAgICAgZ2V0SW50NjRGaWVsZE9yQnVpbGRlckxpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyIGdldEludDY0RmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCk7CgogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWU+IAogICAgICBnZXRVaW50NjRGaWVsZExpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIGdldFVpbnQ2NEZpZWxkKGludCBpbmRleCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICovCiAgaW50IGdldFVpbnQ2NEZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZU9yQnVpbGRlcj4gCiAgICAgIGdldFVpbnQ2NEZpZWxkT3JCdWlsZGVyTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXIgZ2V0VWludDY0RmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCk7CgogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWU+IAogICAgICBnZXRJbnQzMkZpZWxkTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgZ2V0SW50MzJGaWVsZChpbnQgaW5kZXgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgKi8KICBpbnQgZ2V0SW50MzJGaWVsZENvdW50KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWVPckJ1aWxkZXI+IAogICAgICBnZXRJbnQzMkZpZWxkT3JCdWlsZGVyTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWVPckJ1aWxkZXIgZ2V0SW50MzJGaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KTsKCiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICovCiAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZT4gCiAgICAgIGdldFVpbnQzMkZpZWxkTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgZ2V0VWludDMyRmllbGQoaW50IGluZGV4KTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgKi8KICBpbnQgZ2V0VWludDMyRmllbGRDb3VudCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlT3JCdWlsZGVyPiAKICAgICAgZ2V0VWludDMyRmllbGRPckJ1aWxkZXJMaXN0KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZU9yQnVpbGRlciBnZXRVaW50MzJGaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KTsKCiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZT4gCiAgICAgIGdldEJvb2xGaWVsZExpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGdldEJvb2xGaWVsZChpbnQgaW5kZXgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICovCiAgaW50IGdldEJvb2xGaWVsZENvdW50KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVPckJ1aWxkZXI+IAogICAgICBnZXRCb29sRmllbGRPckJ1aWxkZXJMaXN0KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlciBnZXRCb29sRmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCk7CgogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWU+IAogICAgICBnZXRTdHJpbmdGaWVsZExpc3QoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIGdldFN0cmluZ0ZpZWxkKGludCBpbmRleCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICovCiAgaW50IGdldFN0cmluZ0ZpZWxkQ291bnQoKTsKICAvKioKICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZU9yQnVpbGRlcj4gCiAgICAgIGdldFN0cmluZ0ZpZWxkT3JCdWlsZGVyTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWVPckJ1aWxkZXIgZ2V0U3RyaW5nRmllbGRPckJ1aWxkZXIoCiAgICAgIGludCBpbmRleCk7CgogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgKi8KICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWU+IAogICAgICBnZXRCeXRlc0ZpZWxkTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgZ2V0Qnl0ZXNGaWVsZChpbnQgaW5kZXgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgKi8KICBpbnQgZ2V0Qnl0ZXNGaWVsZENvdW50KCk7CiAgLyoqCiAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAqLwogIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWVPckJ1aWxkZXI+IAogICAgICBnZXRCeXRlc0ZpZWxkT3JCdWlsZGVyTGlzdCgpOwogIC8qKgogICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWVPckJ1aWxkZXIgZ2V0Qnl0ZXNGaWVsZE9yQnVpbGRlcigKICAgICAgaW50IGluZGV4KTsKfQpQSwMECgAAAAAAAAAhAN7iIhUhGgIAIRoCADAAAABjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3QvVGVzdFdlbGxLbm93blR5cGVzLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF93ZWxsX2tub3duX3R5cGVzLnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3Q7CgovKioKICogPHByZT4KICogVGVzdCB0aGF0IHdlIGNhbiBpbmNsdWRlIGFsbCB3ZWxsLWtub3duIHR5cGVzLgogKiBFYWNoIHdyYXBwZXIgdHlwZSBpcyBpbmNsdWRlZCBzZXBhcmF0ZWx5LCBhcyBsYW5ndWFnZXMKICogbWFwIGhhbmRsZSBkaWZmZXJlbnQgd3JhcHBlcnMgaW4gZGlmZmVyZW50IHdheXMuCiAqIDwvcHJlPgogKgogKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0V2VsbEtub3duVHlwZXN9CiAqLwpwdWJsaWMgZmluYWwgY2xhc3MgVGVzdFdlbGxLbm93blR5cGVzIGV4dGVuZHMKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFdlbGxLbm93blR5cGVzKQogICAgVGVzdFdlbGxLbm93blR5cGVzT3JCdWlsZGVyIHsKcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgLy8gVXNlIFRlc3RXZWxsS25vd25UeXBlcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogIHByaXZhdGUgVGVzdFdlbGxLbm93blR5cGVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgc3VwZXIoYnVpbGRlcik7CiAgfQogIHByaXZhdGUgVGVzdFdlbGxLbm93blR5cGVzKCkgewogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICByZXR1cm4gbmV3IFRlc3RXZWxsS25vd25UeXBlcygpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RXZWxsS25vd25UeXBlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3I7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RXZWxsS25vd25UeXBlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFdlbGxLbm93blR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVGVzdFdlbGxLbm93blR5cGVzLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVGVzdFdlbGxLbm93blR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogIH0KCiAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTllfRklFTERfRklFTERfTlVNQkVSID0gMTsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGFueUZpZWxkXzsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGFueUZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzQW55RmllbGQoKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGFueUZpZWxkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkgZ2V0QW55RmllbGQoKSB7CiAgICByZXR1cm4gYW55RmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGFueUZpZWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlciBnZXRBbnlGaWVsZE9yQnVpbGRlcigpIHsKICAgIHJldHVybiBhbnlGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuQW55LmdldERlZmF1bHRJbnN0YW5jZSgpIDogYW55RmllbGRfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVBJX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDI7CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlGaWVsZF87CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhcGlGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc0FwaUZpZWxkKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBhcGlGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQXBpIGdldEFwaUZpZWxkKCkgewogICAgcmV0dXJuIGFwaUZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBhcGlGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlPckJ1aWxkZXIgZ2V0QXBpRmllbGRPckJ1aWxkZXIoKSB7CiAgICByZXR1cm4gYXBpRmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGFwaUZpZWxkXzsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERVUkFUSU9OX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDM7CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uRmllbGRfOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1cmF0aW9uRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNEdXJhdGlvbkZpZWxkKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgZHVyYXRpb25GaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZ2V0RHVyYXRpb25GaWVsZCgpIHsKICAgIHJldHVybiBkdXJhdGlvbkZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGR1cmF0aW9uRmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyIGdldER1cmF0aW9uRmllbGRPckJ1aWxkZXIoKSB7CiAgICByZXR1cm4gZHVyYXRpb25GaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBkdXJhdGlvbkZpZWxkXzsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVNUFRZX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDQ7CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5RmllbGRfOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGVtcHR5RmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNFbXB0eUZpZWxkKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgZW1wdHlGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkgZ2V0RW1wdHlGaWVsZCgpIHsKICAgIHJldHVybiBlbXB0eUZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGVtcHR5RmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5T3JCdWlsZGVyIGdldEVtcHR5RmllbGRPckJ1aWxkZXIoKSB7CiAgICByZXR1cm4gZW1wdHlGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBlbXB0eUZpZWxkXzsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX01BU0tfRklFTERfRklFTERfTlVNQkVSID0gNTsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkTWFza0ZpZWxkXzsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE1hc2tGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkTWFza0ZpZWxkKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgZmllbGRNYXNrRmllbGQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBnZXRGaWVsZE1hc2tGaWVsZCgpIHsKICAgIHJldHVybiBmaWVsZE1hc2tGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRNYXNrRmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza09yQnVpbGRlciBnZXRGaWVsZE1hc2tGaWVsZE9yQnVpbGRlcigpIHsKICAgIHJldHVybiBmaWVsZE1hc2tGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRNYXNrRmllbGRfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09VUkNFX0NPTlRFWFRfRklFTERfRklFTERfTlVNQkVSID0gNjsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VDb250ZXh0RmllbGRfOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgc291cmNlQ29udGV4dEZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzU291cmNlQ29udGV4dEZpZWxkKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBzb3VyY2VDb250ZXh0RmllbGQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgZ2V0U291cmNlQ29udGV4dEZpZWxkKCkgewogICAgcmV0dXJuIHNvdXJjZUNvbnRleHRGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHNvdXJjZUNvbnRleHRGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyIGdldFNvdXJjZUNvbnRleHRGaWVsZE9yQnVpbGRlcigpIHsKICAgIHJldHVybiBzb3VyY2VDb250ZXh0RmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzb3VyY2VDb250ZXh0RmllbGRfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSVUNUX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDc7CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RGaWVsZF87CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJ1Y3RGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc1N0cnVjdEZpZWxkKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBzdHJ1Y3RGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IGdldFN0cnVjdEZpZWxkKCkgewogICAgcmV0dXJuIHN0cnVjdEZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdHJ1Y3RGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RPckJ1aWxkZXIgZ2V0U3RydWN0RmllbGRPckJ1aWxkZXIoKSB7CiAgICByZXR1cm4gc3RydWN0RmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHN0cnVjdEZpZWxkXzsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRJTUVTVEFNUF9GSUVMRF9GSUVMRF9OVU1CRVIgPSA4OwogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wRmllbGRfOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgdGltZXN0YW1wRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNUaW1lc3RhbXBGaWVsZCgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgdGltZXN0YW1wRmllbGQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCBnZXRUaW1lc3RhbXBGaWVsZCgpIHsKICAgIHJldHVybiB0aW1lc3RhbXBGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLmdldERlZmF1bHRJbnN0YW5jZSgpIDogdGltZXN0YW1wRmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wT3JCdWlsZGVyIGdldFRpbWVzdGFtcEZpZWxkT3JCdWlsZGVyKCkgewogICAgcmV0dXJuIHRpbWVzdGFtcEZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiB0aW1lc3RhbXBGaWVsZF87CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDk7CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZUZpZWxkXzsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgdHlwZUZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzVHlwZUZpZWxkKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHR5cGVGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZSBnZXRUeXBlRmllbGQoKSB7CiAgICByZXR1cm4gdHlwZUZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogdHlwZUZpZWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZU9yQnVpbGRlciBnZXRUeXBlRmllbGRPckJ1aWxkZXIoKSB7CiAgICByZXR1cm4gdHlwZUZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogdHlwZUZpZWxkXzsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERPVUJMRV9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlRmllbGRfOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgZG91YmxlRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNEb3VibGVGaWVsZCgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgZG91YmxlRmllbGQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGdldERvdWJsZUZpZWxkKCkgewogICAgcmV0dXJuIGRvdWJsZUZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGRvdWJsZUZpZWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlT3JCdWlsZGVyIGdldERvdWJsZUZpZWxkT3JCdWlsZGVyKCkgewogICAgcmV0dXJuIGRvdWJsZUZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGRvdWJsZUZpZWxkXzsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZMT0FUX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDExOwogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0RmllbGRfOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZsb2F0RmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNGbG9hdEZpZWxkKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgZmxvYXRGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBnZXRGbG9hdEZpZWxkKCkgewogICAgcmV0dXJuIGZsb2F0RmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmbG9hdEZpZWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlT3JCdWlsZGVyIGdldEZsb2F0RmllbGRPckJ1aWxkZXIoKSB7CiAgICByZXR1cm4gZmxvYXRGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZsb2F0RmllbGRfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UNjRfRklFTERfRklFTERfTlVNQkVSID0gMTI7CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRGaWVsZF87CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50NjRGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc0ludDY0RmllbGQoKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBpbnQ2NEZpZWxkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGdldEludDY0RmllbGQoKSB7CiAgICByZXR1cm4gaW50NjRGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGludDY0RmllbGRfOwogIH0KICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWVPckJ1aWxkZXIgZ2V0SW50NjRGaWVsZE9yQnVpbGRlcigpIHsKICAgIHJldHVybiBpbnQ2NEZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogaW50NjRGaWVsZF87CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVSU5UNjRfRklFTERfRklFTERfTlVNQkVSID0gMTM7CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NEZpZWxkXzsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHVpbnQ2NEZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzVWludDY0RmllbGQoKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHVpbnQ2NEZpZWxkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBnZXRVaW50NjRGaWVsZCgpIHsKICAgIHJldHVybiB1aW50NjRGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiB1aW50NjRGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZU9yQnVpbGRlciBnZXRVaW50NjRGaWVsZE9yQnVpbGRlcigpIHsKICAgIHJldHVybiB1aW50NjRGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiB1aW50NjRGaWVsZF87CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxNDsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMkZpZWxkXzsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnQzMkZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzSW50MzJGaWVsZCgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGludDMyRmllbGQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgZ2V0SW50MzJGaWVsZCgpIHsKICAgIHJldHVybiBpbnQzMkZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogaW50MzJGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZU9yQnVpbGRlciBnZXRJbnQzMkZpZWxkT3JCdWlsZGVyKCkgewogICAgcmV0dXJuIGludDMyRmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBpbnQzMkZpZWxkXzsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVJTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxNTsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyRmllbGRfOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgdWludDMyRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNVaW50MzJGaWVsZCgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgdWludDMyRmllbGQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGdldFVpbnQzMkZpZWxkKCkgewogICAgcmV0dXJuIHVpbnQzMkZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHVpbnQzMkZpZWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlT3JCdWlsZGVyIGdldFVpbnQzMkZpZWxkT3JCdWlsZGVyKCkgewogICAgcmV0dXJuIHVpbnQzMkZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHVpbnQzMkZpZWxkXzsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJPT0xfRklFTERfRklFTERfTlVNQkVSID0gMTY7CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sRmllbGRfOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBib29sRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNCb29sRmllbGQoKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgYm9vbEZpZWxkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgZ2V0Qm9vbEZpZWxkKCkgewogICAgcmV0dXJuIGJvb2xGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogYm9vbEZpZWxkXzsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlT3JCdWlsZGVyIGdldEJvb2xGaWVsZE9yQnVpbGRlcigpIHsKICAgIHJldHVybiBib29sRmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGJvb2xGaWVsZF87CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJTkdfRklFTERfRklFTERfTlVNQkVSID0gMTc7CiAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ0ZpZWxkXzsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cmluZ0ZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzU3RyaW5nRmllbGQoKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHN0cmluZ0ZpZWxkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBnZXRTdHJpbmdGaWVsZCgpIHsKICAgIHJldHVybiBzdHJpbmdGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdHJpbmdGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZU9yQnVpbGRlciBnZXRTdHJpbmdGaWVsZE9yQnVpbGRlcigpIHsKICAgIHJldHVybiBzdHJpbmdGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdHJpbmdGaWVsZF87CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCWVRFU19GSUVMRF9GSUVMRF9OVU1CRVIgPSAxODsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc0ZpZWxkXzsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBieXRlc0ZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzQnl0ZXNGaWVsZCgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGJ5dGVzRmllbGQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgZ2V0Qnl0ZXNGaWVsZCgpIHsKICAgIHJldHVybiBieXRlc0ZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogYnl0ZXNGaWVsZF87CiAgfQogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZU9yQnVpbGRlciBnZXRCeXRlc0ZpZWxkT3JCdWlsZGVyKCkgewogICAgcmV0dXJuIGJ5dGVzRmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBieXRlc0ZpZWxkXzsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE5OwogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSB2YWx1ZUZpZWxkXzsKICAvKioKICAgKiA8cHJlPgogICAqIFBhcnQgb2Ygc3RydWN0LCBidXQgdXNlZnVsIHRvIGJlIGFibGUgdG8gdGVzdCBzZXBhcmF0ZWx5CiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHZhbHVlX2ZpZWxkID0gMTk7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgdmFsdWVGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc1ZhbHVlRmllbGQoKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogUGFydCBvZiBzdHJ1Y3QsIGJ1dCB1c2VmdWwgdG8gYmUgYWJsZSB0byB0ZXN0IHNlcGFyYXRlbHkKICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVmFsdWUgdmFsdWVfZmllbGQgPSAxOTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgdmFsdWVGaWVsZC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVmFsdWUgZ2V0VmFsdWVGaWVsZCgpIHsKICAgIHJldHVybiB2YWx1ZUZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHZhbHVlRmllbGRfOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFBhcnQgb2Ygc3RydWN0LCBidXQgdXNlZnVsIHRvIGJlIGFibGUgdG8gdGVzdCBzZXBhcmF0ZWx5CiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHZhbHVlX2ZpZWxkID0gMTk7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZU9yQnVpbGRlciBnZXRWYWx1ZUZpZWxkT3JCdWlsZGVyKCkgewogICAgcmV0dXJuIHZhbHVlRmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogdmFsdWVGaWVsZF87CiAgfQoKICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEsIGdldEFueUZpZWxkKCkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMiwgZ2V0QXBpRmllbGQoKSk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgzLCBnZXREdXJhdGlvbkZpZWxkKCkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNCwgZ2V0RW1wdHlGaWVsZCgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDUsIGdldEZpZWxkTWFza0ZpZWxkKCkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNiwgZ2V0U291cmNlQ29udGV4dEZpZWxkKCkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNywgZ2V0U3RydWN0RmllbGQoKSk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg4LCBnZXRUaW1lc3RhbXBGaWVsZCgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDksIGdldFR5cGVGaWVsZCgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEwLCBnZXREb3VibGVGaWVsZCgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDExLCBnZXRGbG9hdEZpZWxkKCkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTIsIGdldEludDY0RmllbGQoKSk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxMywgZ2V0VWludDY0RmllbGQoKSk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxNCwgZ2V0SW50MzJGaWVsZCgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDE1LCBnZXRVaW50MzJGaWVsZCgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDE2LCBnZXRCb29sRmllbGQoKSk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxNywgZ2V0U3RyaW5nRmllbGQoKSk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxOCwgZ2V0Qnl0ZXNGaWVsZCgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDE5LCBnZXRWYWx1ZUZpZWxkKCkpOwogICAgfQogICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgc2l6ZSA9IDA7CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRBbnlGaWVsZCgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIsIGdldEFwaUZpZWxkKCkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgZ2V0RHVyYXRpb25GaWVsZCgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQsIGdldEVtcHR5RmllbGQoKSk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1LCBnZXRGaWVsZE1hc2tGaWVsZCgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYsIGdldFNvdXJjZUNvbnRleHRGaWVsZCgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcsIGdldFN0cnVjdEZpZWxkKCkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOCwgZ2V0VGltZXN0YW1wRmllbGQoKSk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5LCBnZXRUeXBlRmllbGQoKSk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgZ2V0RG91YmxlRmllbGQoKSk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMSwgZ2V0RmxvYXRGaWVsZCgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyLCBnZXRJbnQ2NEZpZWxkKCkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTMsIGdldFVpbnQ2NEZpZWxkKCkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQsIGdldEludDMyRmllbGQoKSk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNSwgZ2V0VWludDMyRmllbGQoKSk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNiwgZ2V0Qm9vbEZpZWxkKCkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTcsIGdldFN0cmluZ0ZpZWxkKCkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgsIGdldEJ5dGVzRmllbGQoKSk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOSwgZ2V0VmFsdWVGaWVsZCgpKTsKICAgIH0KICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgcmV0dXJuIHNpemU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXMpKSB7CiAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgIH0KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXMgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlRlc3RXZWxsS25vd25UeXBlcykgb2JqOwoKICAgIGlmIChoYXNBbnlGaWVsZCgpICE9IG90aGVyLmhhc0FueUZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNBbnlGaWVsZCgpKSB7CiAgICAgIGlmICghZ2V0QW55RmllbGQoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRBbnlGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc0FwaUZpZWxkKCkgIT0gb3RoZXIuaGFzQXBpRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc0FwaUZpZWxkKCkpIHsKICAgICAgaWYgKCFnZXRBcGlGaWVsZCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEFwaUZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzRHVyYXRpb25GaWVsZCgpICE9IG90aGVyLmhhc0R1cmF0aW9uRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc0R1cmF0aW9uRmllbGQoKSkgewogICAgICBpZiAoIWdldER1cmF0aW9uRmllbGQoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXREdXJhdGlvbkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzRW1wdHlGaWVsZCgpICE9IG90aGVyLmhhc0VtcHR5RmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc0VtcHR5RmllbGQoKSkgewogICAgICBpZiAoIWdldEVtcHR5RmllbGQoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRFbXB0eUZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzRmllbGRNYXNrRmllbGQoKSAhPSBvdGhlci5oYXNGaWVsZE1hc2tGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzRmllbGRNYXNrRmllbGQoKSkgewogICAgICBpZiAoIWdldEZpZWxkTWFza0ZpZWxkKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmllbGRNYXNrRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmIChoYXNTb3VyY2VDb250ZXh0RmllbGQoKSAhPSBvdGhlci5oYXNTb3VyY2VDb250ZXh0RmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc1NvdXJjZUNvbnRleHRGaWVsZCgpKSB7CiAgICAgIGlmICghZ2V0U291cmNlQ29udGV4dEZpZWxkKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U291cmNlQ29udGV4dEZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzU3RydWN0RmllbGQoKSAhPSBvdGhlci5oYXNTdHJ1Y3RGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzU3RydWN0RmllbGQoKSkgewogICAgICBpZiAoIWdldFN0cnVjdEZpZWxkKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RydWN0RmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmIChoYXNUaW1lc3RhbXBGaWVsZCgpICE9IG90aGVyLmhhc1RpbWVzdGFtcEZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNUaW1lc3RhbXBGaWVsZCgpKSB7CiAgICAgIGlmICghZ2V0VGltZXN0YW1wRmllbGQoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRUaW1lc3RhbXBGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc1R5cGVGaWVsZCgpICE9IG90aGVyLmhhc1R5cGVGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzVHlwZUZpZWxkKCkpIHsKICAgICAgaWYgKCFnZXRUeXBlRmllbGQoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRUeXBlRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmIChoYXNEb3VibGVGaWVsZCgpICE9IG90aGVyLmhhc0RvdWJsZUZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNEb3VibGVGaWVsZCgpKSB7CiAgICAgIGlmICghZ2V0RG91YmxlRmllbGQoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXREb3VibGVGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc0Zsb2F0RmllbGQoKSAhPSBvdGhlci5oYXNGbG9hdEZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNGbG9hdEZpZWxkKCkpIHsKICAgICAgaWYgKCFnZXRGbG9hdEZpZWxkKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RmxvYXRGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc0ludDY0RmllbGQoKSAhPSBvdGhlci5oYXNJbnQ2NEZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNJbnQ2NEZpZWxkKCkpIHsKICAgICAgaWYgKCFnZXRJbnQ2NEZpZWxkKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0SW50NjRGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc1VpbnQ2NEZpZWxkKCkgIT0gb3RoZXIuaGFzVWludDY0RmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc1VpbnQ2NEZpZWxkKCkpIHsKICAgICAgaWYgKCFnZXRVaW50NjRGaWVsZCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFVpbnQ2NEZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzSW50MzJGaWVsZCgpICE9IG90aGVyLmhhc0ludDMyRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc0ludDMyRmllbGQoKSkgewogICAgICBpZiAoIWdldEludDMyRmllbGQoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRJbnQzMkZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzVWludDMyRmllbGQoKSAhPSBvdGhlci5oYXNVaW50MzJGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzVWludDMyRmllbGQoKSkgewogICAgICBpZiAoIWdldFVpbnQzMkZpZWxkKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0VWludDMyRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmIChoYXNCb29sRmllbGQoKSAhPSBvdGhlci5oYXNCb29sRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc0Jvb2xGaWVsZCgpKSB7CiAgICAgIGlmICghZ2V0Qm9vbEZpZWxkKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Qm9vbEZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzU3RyaW5nRmllbGQoKSAhPSBvdGhlci5oYXNTdHJpbmdGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzU3RyaW5nRmllbGQoKSkgewogICAgICBpZiAoIWdldFN0cmluZ0ZpZWxkKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyaW5nRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmIChoYXNCeXRlc0ZpZWxkKCkgIT0gb3RoZXIuaGFzQnl0ZXNGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzQnl0ZXNGaWVsZCgpKSB7CiAgICAgIGlmICghZ2V0Qnl0ZXNGaWVsZCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEJ5dGVzRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmIChoYXNWYWx1ZUZpZWxkKCkgIT0gb3RoZXIuaGFzVmFsdWVGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzVmFsdWVGaWVsZCgpKSB7CiAgICAgIGlmICghZ2V0VmFsdWVGaWVsZCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFZhbHVlRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgIH0KICAgIGludCBoYXNoID0gNDE7CiAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgIGlmIChoYXNBbnlGaWVsZCgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFOWV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEFueUZpZWxkKCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGlmIChoYXNBcGlGaWVsZCgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFQSV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEFwaUZpZWxkKCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGlmIChoYXNEdXJhdGlvbkZpZWxkKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVSQVRJT05fRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREdXJhdGlvbkZpZWxkKCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGlmIChoYXNFbXB0eUZpZWxkKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRU1QVFlfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRFbXB0eUZpZWxkKCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGlmIChoYXNGaWVsZE1hc2tGaWVsZCgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX01BU0tfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZE1hc2tGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoaGFzU291cmNlQ29udGV4dEZpZWxkKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU09VUkNFX0NPTlRFWFRfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTb3VyY2VDb250ZXh0RmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc1N0cnVjdEZpZWxkKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSVUNUX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RydWN0RmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc1RpbWVzdGFtcEZpZWxkKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVElNRVNUQU1QX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VGltZXN0YW1wRmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc1R5cGVGaWVsZCgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFRZUEVfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRUeXBlRmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc0RvdWJsZUZpZWxkKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRE9VQkxFX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RG91YmxlRmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc0Zsb2F0RmllbGQoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGTE9BVF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZsb2F0RmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc0ludDY0RmllbGQoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQ2NF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEludDY0RmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc1VpbnQ2NEZpZWxkKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVUlOVDY0X0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VWludDY0RmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc0ludDMyRmllbGQoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlQzMl9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEludDMyRmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc1VpbnQzMkZpZWxkKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVUlOVDMyX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VWludDMyRmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc0Jvb2xGaWVsZCgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEJPT0xfRklFTERfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCb29sRmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc1N0cmluZ0ZpZWxkKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSSU5HX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyaW5nRmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc0J5dGVzRmllbGQoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCWVRFU19GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEJ5dGVzRmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc1ZhbHVlRmllbGQoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBWQUxVRV9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFZhbHVlRmllbGQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgIHJldHVybiBoYXNoOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVGVzdFdlbGxLbm93blR5cGVzIHBhcnNlRnJvbSgKICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlRlc3RXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlRlc3RXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlRlc3RXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVGVzdFdlbGxLbm93blR5cGVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKAogICAgICBieXRlW10gZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlRlc3RXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKAogICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlRlc3RXZWxsS25vd25UeXBlcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVGVzdFdlbGxLbm93blR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlRlc3RXZWxsS25vd25UeXBlcyBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXMgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICB9CiAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlRlc3RXZWxsS25vd25UeXBlcyBwcm90b3R5cGUpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogIH0KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgIHJldHVybiBidWlsZGVyOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRlc3QgdGhhdCB3ZSBjYW4gaW5jbHVkZSBhbGwgd2VsbC1rbm93biB0eXBlcy4KICAgKiBFYWNoIHdyYXBwZXIgdHlwZSBpcyBpbmNsdWRlZCBzZXBhcmF0ZWx5LCBhcyBsYW5ndWFnZXMKICAgKiBtYXAgaGFuZGxlIGRpZmZlcmVudCB3cmFwcGVycyBpbiBkaWZmZXJlbnQgd2F5cy4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RXZWxsS25vd25UeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0V2VsbEtub3duVHlwZXMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXNPckJ1aWxkZXIgewogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0V2VsbEtub3duVHlwZXMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RXZWxsS25vd25UeXBlc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdFdlbGxLbm93blR5cGVzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0V2VsbEtub3duVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVGVzdFdlbGxLbm93blR5cGVzLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVGVzdFdlbGxLbm93blR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVGVzdFdlbGxLbm93blR5cGVzLm5ld0J1aWxkZXIoKQogICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICB9CgogICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgIH0KICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgIGdldEFueUZpZWxkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgZ2V0QXBpRmllbGRGaWVsZEJ1aWxkZXIoKTsKICAgICAgICBnZXREdXJhdGlvbkZpZWxkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgZ2V0RW1wdHlGaWVsZEZpZWxkQnVpbGRlcigpOwogICAgICAgIGdldEZpZWxkTWFza0ZpZWxkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgZ2V0U291cmNlQ29udGV4dEZpZWxkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgZ2V0U3RydWN0RmllbGRGaWVsZEJ1aWxkZXIoKTsKICAgICAgICBnZXRUaW1lc3RhbXBGaWVsZEZpZWxkQnVpbGRlcigpOwogICAgICAgIGdldFR5cGVGaWVsZEZpZWxkQnVpbGRlcigpOwogICAgICAgIGdldERvdWJsZUZpZWxkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgZ2V0RmxvYXRGaWVsZEZpZWxkQnVpbGRlcigpOwogICAgICAgIGdldEludDY0RmllbGRGaWVsZEJ1aWxkZXIoKTsKICAgICAgICBnZXRVaW50NjRGaWVsZEZpZWxkQnVpbGRlcigpOwogICAgICAgIGdldEludDMyRmllbGRGaWVsZEJ1aWxkZXIoKTsKICAgICAgICBnZXRVaW50MzJGaWVsZEZpZWxkQnVpbGRlcigpOwogICAgICAgIGdldEJvb2xGaWVsZEZpZWxkQnVpbGRlcigpOwogICAgICAgIGdldFN0cmluZ0ZpZWxkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgZ2V0Qnl0ZXNGaWVsZEZpZWxkQnVpbGRlcigpOwogICAgICAgIGdldFZhbHVlRmllbGRGaWVsZEJ1aWxkZXIoKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICBhbnlGaWVsZF8gPSBudWxsOwogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgYW55RmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgYW55RmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgYXBpRmllbGRfID0gbnVsbDsKICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIGFwaUZpZWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgIGFwaUZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIGR1cmF0aW9uRmllbGRfID0gbnVsbDsKICAgICAgaWYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgZHVyYXRpb25GaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBkdXJhdGlvbkZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIGVtcHR5RmllbGRfID0gbnVsbDsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBlbXB0eUZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIGZpZWxkTWFza0ZpZWxkXyA9IG51bGw7CiAgICAgIGlmIChmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBzb3VyY2VDb250ZXh0RmllbGRfID0gbnVsbDsKICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIHN0cnVjdEZpZWxkXyA9IG51bGw7CiAgICAgIGlmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBzdHJ1Y3RGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBzdHJ1Y3RGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICB0aW1lc3RhbXBGaWVsZF8gPSBudWxsOwogICAgICBpZiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgdGltZXN0YW1wRmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgdGltZXN0YW1wRmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgdHlwZUZpZWxkXyA9IG51bGw7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgdHlwZUZpZWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgIHR5cGVGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBkb3VibGVGaWVsZF8gPSBudWxsOwogICAgICBpZiAoZG91YmxlRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgZG91YmxlRmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgZG91YmxlRmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgZmxvYXRGaWVsZF8gPSBudWxsOwogICAgICBpZiAoZmxvYXRGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBmbG9hdEZpZWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgaW50NjRGaWVsZF8gPSBudWxsOwogICAgICBpZiAoaW50NjRGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBpbnQ2NEZpZWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgIGludDY0RmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgdWludDY0RmllbGRfID0gbnVsbDsKICAgICAgaWYgKHVpbnQ2NEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHVpbnQ2NEZpZWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgIHVpbnQ2NEZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIGludDMyRmllbGRfID0gbnVsbDsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgaW50MzJGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBpbnQzMkZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIHVpbnQzMkZpZWxkXyA9IG51bGw7CiAgICAgIGlmICh1aW50MzJGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICB1aW50MzJGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICB1aW50MzJGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBib29sRmllbGRfID0gbnVsbDsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBib29sRmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIHN0cmluZ0ZpZWxkXyA9IG51bGw7CiAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBieXRlc0ZpZWxkXyA9IG51bGw7CiAgICAgIGlmIChieXRlc0ZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgYnl0ZXNGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICB2YWx1ZUZpZWxkXyA9IG51bGw7CiAgICAgIGlmICh2YWx1ZUZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHZhbHVlRmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgdmFsdWVGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RXZWxsS25vd25UeXBlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXMgYnVpbGQoKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlRlc3RXZWxsS25vd25UeXBlcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXMgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXModGhpcyk7CiAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgIG9uQnVpbHQoKTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVGVzdFdlbGxLbm93blR5cGVzIHJlc3VsdCkgewogICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5hbnlGaWVsZF8gPSBhbnlGaWVsZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgPyBhbnlGaWVsZF8KICAgICAgICAgICAgOiBhbnlGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICB9CiAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgcmVzdWx0LmFwaUZpZWxkXyA9IGFwaUZpZWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICA/IGFwaUZpZWxkXwogICAgICAgICAgICA6IGFwaUZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQuZHVyYXRpb25GaWVsZF8gPSBkdXJhdGlvbkZpZWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICA/IGR1cmF0aW9uRmllbGRfCiAgICAgICAgICAgIDogZHVyYXRpb25GaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgcmVzdWx0LmVtcHR5RmllbGRfID0gZW1wdHlGaWVsZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgPyBlbXB0eUZpZWxkXwogICAgICAgICAgICA6IGVtcHR5RmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5maWVsZE1hc2tGaWVsZF8gPSBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgPyBmaWVsZE1hc2tGaWVsZF8KICAgICAgICAgICAgOiBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICB9CiAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgcmVzdWx0LnNvdXJjZUNvbnRleHRGaWVsZF8gPSBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgID8gc291cmNlQ29udGV4dEZpZWxkXwogICAgICAgICAgICA6IHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICB9CiAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgcmVzdWx0LnN0cnVjdEZpZWxkXyA9IHN0cnVjdEZpZWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICA/IHN0cnVjdEZpZWxkXwogICAgICAgICAgICA6IHN0cnVjdEZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQudGltZXN0YW1wRmllbGRfID0gdGltZXN0YW1wRmllbGRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgID8gdGltZXN0YW1wRmllbGRfCiAgICAgICAgICAgIDogdGltZXN0YW1wRmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC50eXBlRmllbGRfID0gdHlwZUZpZWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICA/IHR5cGVGaWVsZF8KICAgICAgICAgICAgOiB0eXBlRmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5kb3VibGVGaWVsZF8gPSBkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgPyBkb3VibGVGaWVsZF8KICAgICAgICAgICAgOiBkb3VibGVGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICB9CiAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgcmVzdWx0LmZsb2F0RmllbGRfID0gZmxvYXRGaWVsZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgPyBmbG9hdEZpZWxkXwogICAgICAgICAgICA6IGZsb2F0RmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5pbnQ2NEZpZWxkXyA9IGludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgID8gaW50NjRGaWVsZF8KICAgICAgICAgICAgOiBpbnQ2NEZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQudWludDY0RmllbGRfID0gdWludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgID8gdWludDY0RmllbGRfCiAgICAgICAgICAgIDogdWludDY0RmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5pbnQzMkZpZWxkXyA9IGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgID8gaW50MzJGaWVsZF8KICAgICAgICAgICAgOiBpbnQzMkZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQudWludDMyRmllbGRfID0gdWludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgID8gdWludDMyRmllbGRfCiAgICAgICAgICAgIDogdWludDMyRmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5ib29sRmllbGRfID0gYm9vbEZpZWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICA/IGJvb2xGaWVsZF8KICAgICAgICAgICAgOiBib29sRmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5zdHJpbmdGaWVsZF8gPSBzdHJpbmdGaWVsZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgPyBzdHJpbmdGaWVsZF8KICAgICAgICAgICAgOiBzdHJpbmdGaWVsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICB9CiAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgcmVzdWx0LmJ5dGVzRmllbGRfID0gYnl0ZXNGaWVsZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgPyBieXRlc0ZpZWxkXwogICAgICAgICAgICA6IGJ5dGVzRmllbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC52YWx1ZUZpZWxkXyA9IHZhbHVlRmllbGRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgID8gdmFsdWVGaWVsZF8KICAgICAgICAgICAgOiB2YWx1ZUZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgIH0KICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXMpIHsKICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVGVzdFdlbGxLbm93blR5cGVzKW90aGVyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICB9CgogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXMgb3RoZXIpIHsKICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5UZXN0V2VsbEtub3duVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICBpZiAob3RoZXIuaGFzQW55RmllbGQoKSkgewogICAgICAgIG1lcmdlQW55RmllbGQob3RoZXIuZ2V0QW55RmllbGQoKSk7CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc0FwaUZpZWxkKCkpIHsKICAgICAgICBtZXJnZUFwaUZpZWxkKG90aGVyLmdldEFwaUZpZWxkKCkpOwogICAgICB9CiAgICAgIGlmIChvdGhlci5oYXNEdXJhdGlvbkZpZWxkKCkpIHsKICAgICAgICBtZXJnZUR1cmF0aW9uRmllbGQob3RoZXIuZ2V0RHVyYXRpb25GaWVsZCgpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzRW1wdHlGaWVsZCgpKSB7CiAgICAgICAgbWVyZ2VFbXB0eUZpZWxkKG90aGVyLmdldEVtcHR5RmllbGQoKSk7CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkTWFza0ZpZWxkKCkpIHsKICAgICAgICBtZXJnZUZpZWxkTWFza0ZpZWxkKG90aGVyLmdldEZpZWxkTWFza0ZpZWxkKCkpOwogICAgICB9CiAgICAgIGlmIChvdGhlci5oYXNTb3VyY2VDb250ZXh0RmllbGQoKSkgewogICAgICAgIG1lcmdlU291cmNlQ29udGV4dEZpZWxkKG90aGVyLmdldFNvdXJjZUNvbnRleHRGaWVsZCgpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzU3RydWN0RmllbGQoKSkgewogICAgICAgIG1lcmdlU3RydWN0RmllbGQob3RoZXIuZ2V0U3RydWN0RmllbGQoKSk7CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc1RpbWVzdGFtcEZpZWxkKCkpIHsKICAgICAgICBtZXJnZVRpbWVzdGFtcEZpZWxkKG90aGVyLmdldFRpbWVzdGFtcEZpZWxkKCkpOwogICAgICB9CiAgICAgIGlmIChvdGhlci5oYXNUeXBlRmllbGQoKSkgewogICAgICAgIG1lcmdlVHlwZUZpZWxkKG90aGVyLmdldFR5cGVGaWVsZCgpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzRG91YmxlRmllbGQoKSkgewogICAgICAgIG1lcmdlRG91YmxlRmllbGQob3RoZXIuZ2V0RG91YmxlRmllbGQoKSk7CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc0Zsb2F0RmllbGQoKSkgewogICAgICAgIG1lcmdlRmxvYXRGaWVsZChvdGhlci5nZXRGbG9hdEZpZWxkKCkpOwogICAgICB9CiAgICAgIGlmIChvdGhlci5oYXNJbnQ2NEZpZWxkKCkpIHsKICAgICAgICBtZXJnZUludDY0RmllbGQob3RoZXIuZ2V0SW50NjRGaWVsZCgpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzVWludDY0RmllbGQoKSkgewogICAgICAgIG1lcmdlVWludDY0RmllbGQob3RoZXIuZ2V0VWludDY0RmllbGQoKSk7CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc0ludDMyRmllbGQoKSkgewogICAgICAgIG1lcmdlSW50MzJGaWVsZChvdGhlci5nZXRJbnQzMkZpZWxkKCkpOwogICAgICB9CiAgICAgIGlmIChvdGhlci5oYXNVaW50MzJGaWVsZCgpKSB7CiAgICAgICAgbWVyZ2VVaW50MzJGaWVsZChvdGhlci5nZXRVaW50MzJGaWVsZCgpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzQm9vbEZpZWxkKCkpIHsKICAgICAgICBtZXJnZUJvb2xGaWVsZChvdGhlci5nZXRCb29sRmllbGQoKSk7CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc1N0cmluZ0ZpZWxkKCkpIHsKICAgICAgICBtZXJnZVN0cmluZ0ZpZWxkKG90aGVyLmdldFN0cmluZ0ZpZWxkKCkpOwogICAgICB9CiAgICAgIGlmIChvdGhlci5oYXNCeXRlc0ZpZWxkKCkpIHsKICAgICAgICBtZXJnZUJ5dGVzRmllbGQob3RoZXIuZ2V0Qnl0ZXNGaWVsZCgpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzVmFsdWVGaWVsZCgpKSB7CiAgICAgICAgbWVyZ2VWYWx1ZUZpZWxkKG90aGVyLmdldFZhbHVlRmllbGQoKSk7CiAgICAgIH0KICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgfQogICAgICB0cnkgewogICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBnZXRBbnlGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0QXBpRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldER1cmF0aW9uRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldEVtcHR5RmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICBjYXNlIDQyOiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldEZpZWxkTWFza0ZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBnZXRTb3VyY2VDb250ZXh0RmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSA1MAogICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldFN0cnVjdEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgY2FzZSA2NjogewogICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBnZXRUaW1lc3RhbXBGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDY2CiAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0VHlwZUZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBnZXREb3VibGVGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDgyCiAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0RmxvYXRGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDkwCiAgICAgICAgICAgIGNhc2UgOTg6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0SW50NjRGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDk4CiAgICAgICAgICAgIGNhc2UgMTA2OiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldFVpbnQ2NEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMTA2CiAgICAgICAgICAgIGNhc2UgMTE0OiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldEludDMyRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMTQKICAgICAgICAgICAgY2FzZSAxMjI6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0VWludDMyRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMjIKICAgICAgICAgICAgY2FzZSAxMzA6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0Qm9vbEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMTMwCiAgICAgICAgICAgIGNhc2UgMTM4OiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldFN0cmluZ0ZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMTM4CiAgICAgICAgICAgIGNhc2UgMTQ2OiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldEJ5dGVzRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxNDYKICAgICAgICAgICAgY2FzZSAxNTQ6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0VmFsdWVGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDE1NAogICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICB9IGZpbmFsbHkgewogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9IC8vIGZpbmFsbHkKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55RmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4gYW55RmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGFueUZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzQW55RmllbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhbnlGaWVsZC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGdldEFueUZpZWxkKCkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGFueUZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBhbnlGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGFueUZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRBbnlGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZSkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBhbnlGaWVsZF8gPSB2YWx1ZTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhbnlGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0QW55RmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGFueUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGFueUZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGFueUZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUFueUZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlKSB7CiAgICAgIGlmIChhbnlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgIGFueUZpZWxkXyAhPSBudWxsICYmCiAgICAgICAgICBhbnlGaWVsZF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldEFueUZpZWxkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGFueUZpZWxkXyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBhbnlGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKGFueUZpZWxkXyAhPSBudWxsKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBbnlGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICBhbnlGaWVsZF8gPSBudWxsOwogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgYW55RmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgYW55RmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIgZ2V0QW55RmllbGRCdWlsZGVyKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZ2V0QW55RmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIgZ2V0QW55RmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmIChhbnlGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gYW55RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGFueUZpZWxkXyA9PSBudWxsID8KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBhbnlGaWVsZF87CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXI+IAogICAgICAgIGdldEFueUZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoYW55RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgYW55RmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgZ2V0QW55RmllbGQoKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIGFueUZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIGFueUZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGksIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQXBpT3JCdWlsZGVyPiBhcGlGaWVsZEJ1aWxkZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYXBpRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNBcGlGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGFwaUZpZWxkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkgZ2V0QXBpRmllbGQoKSB7CiAgICAgIGlmIChhcGlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gYXBpRmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGFwaUZpZWxkXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gYXBpRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldEFwaUZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuQXBpIHZhbHVlKSB7CiAgICAgIGlmIChhcGlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGFwaUZpZWxkXyA9IHZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgIGFwaUZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRBcGlGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoYXBpRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgYXBpRmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYXBpRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlQXBpRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkgdmFsdWUpIHsKICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSAmJgogICAgICAgICAgYXBpRmllbGRfICE9IG51bGwgJiYKICAgICAgICAgIGFwaUZpZWxkXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgZ2V0QXBpRmllbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYXBpRmllbGRfID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGFwaUZpZWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgfQogICAgICBpZiAoYXBpRmllbGRfICE9IG51bGwpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckFwaUZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgIGFwaUZpZWxkXyA9IG51bGw7CiAgICAgIGlmIChhcGlGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGkuQnVpbGRlciBnZXRBcGlGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBnZXRBcGlGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BcGkgYXBpX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaU9yQnVpbGRlciBnZXRBcGlGaWVsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKGFwaUZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiBhcGlGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gYXBpRmllbGRfID09IG51bGwgPwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGFwaUZpZWxkXzsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0QXBpRmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChhcGlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBhcGlGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQXBpLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBnZXRBcGlGaWVsZCgpLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgYXBpRmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gYXBpRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25GaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyPiBkdXJhdGlvbkZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVyYXRpb25GaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc0R1cmF0aW9uRmllbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVyYXRpb25GaWVsZC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZ2V0RHVyYXRpb25GaWVsZCgpIHsKICAgICAgaWYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGR1cmF0aW9uRmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZHVyYXRpb25GaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGR1cmF0aW9uRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXREdXJhdGlvbkZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gdmFsdWUpIHsKICAgICAgaWYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBkdXJhdGlvbkZpZWxkXyA9IHZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgIGR1cmF0aW9uRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXREdXJhdGlvbkZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24uQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgZHVyYXRpb25GaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkdXJhdGlvbkZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VEdXJhdGlvbkZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gdmFsdWUpIHsKICAgICAgaWYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApICYmCiAgICAgICAgICBkdXJhdGlvbkZpZWxkXyAhPSBudWxsICYmCiAgICAgICAgICBkdXJhdGlvbkZpZWxkXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBnZXREdXJhdGlvbkZpZWxkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGR1cmF0aW9uRmllbGRfID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGR1cmF0aW9uRmllbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICB9CiAgICAgIGlmIChkdXJhdGlvbkZpZWxkXyAhPSBudWxsKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIGR1cmF0aW9uX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRHVyYXRpb25GaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICBkdXJhdGlvbkZpZWxkXyA9IG51bGw7CiAgICAgIGlmIChkdXJhdGlvbkZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIGR1cmF0aW9uRmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgZHVyYXRpb25GaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24uQnVpbGRlciBnZXREdXJhdGlvbkZpZWxkQnVpbGRlcigpIHsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIGdldER1cmF0aW9uRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb25PckJ1aWxkZXIgZ2V0RHVyYXRpb25GaWVsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKGR1cmF0aW9uRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGR1cmF0aW9uRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGR1cmF0aW9uRmllbGRfID09IG51bGwgPwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZHVyYXRpb25GaWVsZF87CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiBkdXJhdGlvbl9maWVsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyPiAKICAgICAgICBnZXREdXJhdGlvbkZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoZHVyYXRpb25GaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBkdXJhdGlvbkZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiwgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbi5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGdldER1cmF0aW9uRmllbGQoKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIGR1cmF0aW9uRmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gZHVyYXRpb25GaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eUZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHlPckJ1aWxkZXI+IGVtcHR5RmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBlbXB0eUZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzRW1wdHlGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbXB0eUZpZWxkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBnZXRFbXB0eUZpZWxkKCkgewogICAgICBpZiAoZW1wdHlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gZW1wdHlGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBlbXB0eUZpZWxkXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZW1wdHlGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldEVtcHR5RmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSB2YWx1ZSkgewogICAgICBpZiAoZW1wdHlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVtcHR5RmllbGRfID0gdmFsdWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldEVtcHR5RmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoZW1wdHlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBlbXB0eUZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGVtcHR5RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUVtcHR5RmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSB2YWx1ZSkgewogICAgICBpZiAoZW1wdHlGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkgJiYKICAgICAgICAgIGVtcHR5RmllbGRfICE9IG51bGwgJiYKICAgICAgICAgIGVtcHR5RmllbGRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldEVtcHR5RmllbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZW1wdHlGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKGVtcHR5RmllbGRfICE9IG51bGwpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRW1wdHkgZW1wdHlfZmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJFbXB0eUZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgIGVtcHR5RmllbGRfID0gbnVsbDsKICAgICAgaWYgKGVtcHR5RmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgZW1wdHlGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBlbXB0eUZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eS5CdWlsZGVyIGdldEVtcHR5RmllbGRCdWlsZGVyKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZ2V0RW1wdHlGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eU9yQnVpbGRlciBnZXRFbXB0eUZpZWxkT3JCdWlsZGVyKCkgewogICAgICBpZiAoZW1wdHlGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gZW1wdHlGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gZW1wdHlGaWVsZF8gPT0gbnVsbCA/CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBlbXB0eUZpZWxkXzsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkVtcHR5IGVtcHR5X2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHlPckJ1aWxkZXI+IAogICAgICAgIGdldEVtcHR5RmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChlbXB0eUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGVtcHR5RmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LCBjb20uZ29vZ2xlLnByb3RvYnVmLkVtcHR5LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHlPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgZ2V0RW1wdHlGaWVsZCgpLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgZW1wdHlGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBlbXB0eUZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZE1hc2tGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2ssIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrT3JCdWlsZGVyPiBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTWFza0ZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRNYXNrRmllbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRNYXNrRmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBnZXRGaWVsZE1hc2tGaWVsZCgpIHsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBmaWVsZE1hc2tGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRNYXNrRmllbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkTWFza0ZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIHZhbHVlKSB7CiAgICAgIGlmIChmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGZpZWxkTWFza0ZpZWxkXyA9IHZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgIGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRNYXNrRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2suQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGZpZWxkTWFza0ZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGaWVsZE1hc2tGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayB2YWx1ZSkgewogICAgICBpZiAoZmllbGRNYXNrRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApICYmCiAgICAgICAgICBmaWVsZE1hc2tGaWVsZF8gIT0gbnVsbCAmJgogICAgICAgICAgZmllbGRNYXNrRmllbGRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBnZXRGaWVsZE1hc2tGaWVsZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmaWVsZE1hc2tGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmllbGRNYXNrRmllbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICB9CiAgICAgIGlmIChmaWVsZE1hc2tGaWVsZF8gIT0gbnVsbCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sgZmllbGRfbWFza19maWVsZCA9IDU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTWFza0ZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgIGZpZWxkTWFza0ZpZWxkXyA9IG51bGw7CiAgICAgIGlmIChmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLkJ1aWxkZXIgZ2V0RmllbGRNYXNrRmllbGRCdWlsZGVyKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZ2V0RmllbGRNYXNrRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrT3JCdWlsZGVyIGdldEZpZWxkTWFza0ZpZWxkT3JCdWlsZGVyKCkgewogICAgICBpZiAoZmllbGRNYXNrRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkTWFza0ZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBmaWVsZE1hc2tGaWVsZF8gPT0gbnVsbCA/CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGRNYXNrRmllbGRfOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza09yQnVpbGRlcj4gCiAgICAgICAgZ2V0RmllbGRNYXNrRmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBmaWVsZE1hc2tGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzay5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBnZXRGaWVsZE1hc2tGaWVsZCgpLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgZmllbGRNYXNrRmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gZmllbGRNYXNrRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VDb250ZXh0RmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dE9yQnVpbGRlcj4gc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzb3VyY2VDb250ZXh0RmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTb3VyY2VDb250ZXh0RmllbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzb3VyY2VDb250ZXh0RmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgZ2V0U291cmNlQ29udGV4dEZpZWxkKCkgewogICAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBzb3VyY2VDb250ZXh0RmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzb3VyY2VDb250ZXh0RmllbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFNvdXJjZUNvbnRleHRGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgdmFsdWUpIHsKICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZF8gPSB2YWx1ZTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFNvdXJjZUNvbnRleHRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVNvdXJjZUNvbnRleHRGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgdmFsdWUpIHsKICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkgJiYKICAgICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZF8gIT0gbnVsbCAmJgogICAgICAgICAgc291cmNlQ29udGV4dEZpZWxkXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldFNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRfID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZF8gIT0gbnVsbCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IHNvdXJjZV9jb250ZXh0X2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU291cmNlQ29udGV4dEZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgIHNvdXJjZUNvbnRleHRGaWVsZF8gPSBudWxsOwogICAgICBpZiAoc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dC5CdWlsZGVyIGdldFNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBnZXRTb3VyY2VDb250ZXh0RmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyIGdldFNvdXJjZUNvbnRleHRGaWVsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBzb3VyY2VDb250ZXh0RmllbGRfID09IG51bGwgPwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzb3VyY2VDb250ZXh0RmllbGRfOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyPiAKICAgICAgICBnZXRTb3VyY2VDb250ZXh0RmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChzb3VyY2VDb250ZXh0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0LCBjb20uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0T3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGdldFNvdXJjZUNvbnRleHRGaWVsZCgpLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgc291cmNlQ29udGV4dEZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIHNvdXJjZUNvbnRleHRGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0RmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0LCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdC5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdE9yQnVpbGRlcj4gc3RydWN0RmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cnVjdEZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzU3RydWN0RmllbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHJ1Y3RGaWVsZC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IGdldFN0cnVjdEZpZWxkKCkgewogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHN0cnVjdEZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdHJ1Y3RGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHN0cnVjdEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHJ1Y3RGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCB2YWx1ZSkgewogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBzdHJ1Y3RGaWVsZF8gPSB2YWx1ZTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdHJ1Y3RGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0U3RydWN0RmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKHN0cnVjdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHN0cnVjdEZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHN0cnVjdEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVN0cnVjdEZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IHZhbHVlKSB7CiAgICAgIGlmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkgJiYKICAgICAgICAgIHN0cnVjdEZpZWxkXyAhPSBudWxsICYmCiAgICAgICAgICBzdHJ1Y3RGaWVsZF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldFN0cnVjdEZpZWxkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN0cnVjdEZpZWxkXyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBzdHJ1Y3RGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKHN0cnVjdEZpZWxkXyAhPSBudWxsKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdHJ1Y3RGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICBzdHJ1Y3RGaWVsZF8gPSBudWxsOwogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgc3RydWN0RmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgc3RydWN0RmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCBzdHJ1Y3RfZmllbGQgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0LkJ1aWxkZXIgZ2V0U3RydWN0RmllbGRCdWlsZGVyKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZ2V0U3RydWN0RmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RPckJ1aWxkZXIgZ2V0U3RydWN0RmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmIChzdHJ1Y3RGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gc3RydWN0RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHN0cnVjdEZpZWxkXyA9PSBudWxsID8KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdHJ1Y3RGaWVsZF87CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RPckJ1aWxkZXI+IAogICAgICAgIGdldFN0cnVjdEZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoc3RydWN0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgc3RydWN0RmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgZ2V0U3RydWN0RmllbGQoKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIHN0cnVjdEZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIHN0cnVjdEZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAsIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wT3JCdWlsZGVyPiB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdGltZXN0YW1wRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNUaW1lc3RhbXBGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHRpbWVzdGFtcEZpZWxkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgZ2V0VGltZXN0YW1wRmllbGQoKSB7CiAgICAgIGlmICh0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gdGltZXN0YW1wRmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHRpbWVzdGFtcEZpZWxkXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gdGltZXN0YW1wRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFRpbWVzdGFtcEZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHZhbHVlKSB7CiAgICAgIGlmICh0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRpbWVzdGFtcEZpZWxkXyA9IHZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgIHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRUaW1lc3RhbXBGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAodGltZXN0YW1wRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgdGltZXN0YW1wRmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGltZXN0YW1wRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlVGltZXN0YW1wRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdmFsdWUpIHsKICAgICAgaWYgKHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSAmJgogICAgICAgICAgdGltZXN0YW1wRmllbGRfICE9IG51bGwgJiYKICAgICAgICAgIHRpbWVzdGFtcEZpZWxkXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgZ2V0VGltZXN0YW1wRmllbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdGltZXN0YW1wRmllbGRfID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgfQogICAgICBpZiAodGltZXN0YW1wRmllbGRfICE9IG51bGwpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhclRpbWVzdGFtcEZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgIHRpbWVzdGFtcEZpZWxkXyA9IG51bGw7CiAgICAgIGlmICh0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAuQnVpbGRlciBnZXRUaW1lc3RhbXBGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBnZXRUaW1lc3RhbXBGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcE9yQnVpbGRlciBnZXRUaW1lc3RhbXBGaWVsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKHRpbWVzdGFtcEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gdGltZXN0YW1wRmllbGRfID09IG51bGwgPwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHRpbWVzdGFtcEZpZWxkXzsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCB0aW1lc3RhbXBfZmllbGQgPSA4OzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcE9yQnVpbGRlcj4gCiAgICAgICAgZ2V0VGltZXN0YW1wRmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmICh0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICB0aW1lc3RhbXBGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcE9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBnZXRUaW1lc3RhbXBGaWVsZCgpLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgdGltZXN0YW1wRmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gdGltZXN0YW1wRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZU9yQnVpbGRlcj4gdHlwZUZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHR5cGVGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc1R5cGVGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdHlwZUZpZWxkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlIGdldFR5cGVGaWVsZCgpIHsKICAgICAgaWYgKHR5cGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gdHlwZUZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogdHlwZUZpZWxkXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gdHlwZUZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFR5cGVGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdmFsdWUpIHsKICAgICAgaWYgKHR5cGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHR5cGVGaWVsZF8gPSB2YWx1ZTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0eXBlRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0VHlwZUZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAodHlwZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHR5cGVGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0eXBlRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VUeXBlRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlIHZhbHVlKSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApICYmCiAgICAgICAgICB0eXBlRmllbGRfICE9IG51bGwgJiYKICAgICAgICAgIHR5cGVGaWVsZF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBnZXRUeXBlRmllbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdHlwZUZpZWxkXyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICB0eXBlRmllbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICB9CiAgICAgIGlmICh0eXBlRmllbGRfICE9IG51bGwpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVHlwZSB0eXBlX2ZpZWxkID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVHlwZUZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgIHR5cGVGaWVsZF8gPSBudWxsOwogICAgICBpZiAodHlwZUZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHR5cGVGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICB0eXBlRmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLkJ1aWxkZXIgZ2V0VHlwZUZpZWxkQnVpbGRlcigpIHsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIGdldFR5cGVGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZU9yQnVpbGRlciBnZXRUeXBlRmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHR5cGVGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gdHlwZUZpZWxkXyA9PSBudWxsID8KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogdHlwZUZpZWxkXzsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlT3JCdWlsZGVyPiAKICAgICAgICBnZXRUeXBlRmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmICh0eXBlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgdHlwZUZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5UeXBlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGdldFR5cGVGaWVsZCgpLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgdHlwZUZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIHR5cGVGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlT3JCdWlsZGVyPiBkb3VibGVGaWVsZEJ1aWxkZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZG91YmxlRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEb3VibGVGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRvdWJsZUZpZWxkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBnZXREb3VibGVGaWVsZCgpIHsKICAgICAgaWYgKGRvdWJsZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBkb3VibGVGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBkb3VibGVGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGRvdWJsZUZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXREb3VibGVGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGRvdWJsZUZpZWxkXyA9IHZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgIGRvdWJsZUZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXREb3VibGVGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBkb3VibGVGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkb3VibGVGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VEb3VibGVGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkgJiYKICAgICAgICAgIGRvdWJsZUZpZWxkXyAhPSBudWxsICYmCiAgICAgICAgICBkb3VibGVGaWVsZF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgZ2V0RG91YmxlRmllbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZG91YmxlRmllbGRfID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGRvdWJsZUZpZWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgfQogICAgICBpZiAoZG91YmxlRmllbGRfICE9IG51bGwpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRvdWJsZUZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgIGRvdWJsZUZpZWxkXyA9IG51bGw7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBkb3VibGVGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBkb3VibGVGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5CdWlsZGVyIGdldERvdWJsZUZpZWxkQnVpbGRlcigpIHsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIGdldERvdWJsZUZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWVPckJ1aWxkZXIgZ2V0RG91YmxlRmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gZG91YmxlRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGRvdWJsZUZpZWxkXyA9PSBudWxsID8KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGRvdWJsZUZpZWxkXzsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0RG91YmxlRmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChkb3VibGVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBkb3VibGVGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBnZXREb3VibGVGaWVsZCgpLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgZG91YmxlRmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gZG91YmxlRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdEZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWVPckJ1aWxkZXI+IGZsb2F0RmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmbG9hdEZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzRmxvYXRGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmbG9hdEZpZWxkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGdldEZsb2F0RmllbGQoKSB7CiAgICAgIGlmIChmbG9hdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBmbG9hdEZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmxvYXRGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGZsb2F0RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRGbG9hdEZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoZmxvYXRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGZsb2F0RmllbGRfID0gdmFsdWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmxvYXRGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldEZsb2F0RmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChmbG9hdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGZsb2F0RmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmxvYXRGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRmxvYXRGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApICYmCiAgICAgICAgICBmbG9hdEZpZWxkXyAhPSBudWxsICYmCiAgICAgICAgICBmbG9hdEZpZWxkXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldEZsb2F0RmllbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmxvYXRGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZmxvYXRGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKGZsb2F0RmllbGRfICE9IG51bGwpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGbG9hdEZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgIGZsb2F0RmllbGRfID0gbnVsbDsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgZmxvYXRGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBmbG9hdEZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlIGZsb2F0X2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlLkJ1aWxkZXIgZ2V0RmxvYXRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBnZXRGbG9hdEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWVPckJ1aWxkZXIgZ2V0RmxvYXRGaWVsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKGZsb2F0RmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGZsb2F0RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGZsb2F0RmllbGRfID09IG51bGwgPwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmbG9hdEZpZWxkXzsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWVPckJ1aWxkZXI+IAogICAgICAgIGdldEZsb2F0RmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChmbG9hdEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGZsb2F0RmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgZ2V0RmxvYXRGaWVsZCgpLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgZmxvYXRGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBmbG9hdEZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyPiBpbnQ2NEZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50NjRGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc0ludDY0RmllbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50NjRGaWVsZC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBnZXRJbnQ2NEZpZWxkKCkgewogICAgICBpZiAoaW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gaW50NjRGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGludDY0RmllbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBpbnQ2NEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0SW50NjRGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGludDY0RmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBpbnQ2NEZpZWxkXyA9IHZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRJbnQ2NEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoaW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpbnQ2NEZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUludDY0RmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSAmJgogICAgICAgICAgaW50NjRGaWVsZF8gIT0gbnVsbCAmJgogICAgICAgICAgaW50NjRGaWVsZF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBnZXRJbnQ2NEZpZWxkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGludDY0RmllbGRfID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICB9CiAgICAgIGlmIChpbnQ2NEZpZWxkXyAhPSBudWxsKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50NjRGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICBpbnQ2NEZpZWxkXyA9IG51bGw7CiAgICAgIGlmIChpbnQ2NEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIGludDY0RmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgaW50NjRGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZS5CdWlsZGVyIGdldEludDY0RmllbGRCdWlsZGVyKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZ2V0SW50NjRGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyIGdldEludDY0RmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmIChpbnQ2NEZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiBpbnQ2NEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBpbnQ2NEZpZWxkXyA9PSBudWxsID8KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogaW50NjRGaWVsZF87CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlIGludDY0X2ZpZWxkID0gMTI7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyPiAKICAgICAgICBnZXRJbnQ2NEZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoaW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpbnQ2NEZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGdldEludDY0RmllbGQoKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIGludDY0RmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gaW50NjRGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlT3JCdWlsZGVyPiB1aW50NjRGaWVsZEJ1aWxkZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdWludDY0RmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNVaW50NjRGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHVpbnQ2NEZpZWxkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBnZXRVaW50NjRGaWVsZCgpIHsKICAgICAgaWYgKHVpbnQ2NEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiB1aW50NjRGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiB1aW50NjRGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHVpbnQ2NEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRVaW50NjRGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHZhbHVlKSB7CiAgICAgIGlmICh1aW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHVpbnQ2NEZpZWxkXyA9IHZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgIHVpbnQ2NEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRVaW50NjRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmICh1aW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICB1aW50NjRGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICB1aW50NjRGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VVaW50NjRGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHZhbHVlKSB7CiAgICAgIGlmICh1aW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkgJiYKICAgICAgICAgIHVpbnQ2NEZpZWxkXyAhPSBudWxsICYmCiAgICAgICAgICB1aW50NjRGaWVsZF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgZ2V0VWludDY0RmllbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdWludDY0RmllbGRfID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIHVpbnQ2NEZpZWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgfQogICAgICBpZiAodWludDY0RmllbGRfICE9IG51bGwpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVpbnQ2NEZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgIHVpbnQ2NEZpZWxkXyA9IG51bGw7CiAgICAgIGlmICh1aW50NjRGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICB1aW50NjRGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICB1aW50NjRGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5CdWlsZGVyIGdldFVpbnQ2NEZpZWxkQnVpbGRlcigpIHsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIGdldFVpbnQ2NEZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXIgZ2V0VWludDY0RmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmICh1aW50NjRGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gdWludDY0RmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHVpbnQ2NEZpZWxkXyA9PSBudWxsID8KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHVpbnQ2NEZpZWxkXzsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0VWludDY0RmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmICh1aW50NjRGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICB1aW50NjRGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBnZXRVaW50NjRGaWVsZCgpLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgdWludDY0RmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gdWludDY0RmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMkZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWVPckJ1aWxkZXI+IGludDMyRmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnQzMkZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzSW50MzJGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbnQzMkZpZWxkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGdldEludDMyRmllbGQoKSB7CiAgICAgIGlmIChpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBpbnQzMkZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogaW50MzJGaWVsZF87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGludDMyRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRJbnQzMkZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoaW50MzJGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGludDMyRmllbGRfID0gdmFsdWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaW50MzJGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldEludDMyRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGludDMyRmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaW50MzJGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlSW50MzJGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApICYmCiAgICAgICAgICBpbnQzMkZpZWxkXyAhPSBudWxsICYmCiAgICAgICAgICBpbnQzMkZpZWxkXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldEludDMyRmllbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaW50MzJGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaW50MzJGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKGludDMyRmllbGRfICE9IG51bGwpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZSBpbnQzMl9maWVsZCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnQzMkZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgIGludDMyRmllbGRfID0gbnVsbDsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgaW50MzJGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBpbnQzMkZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlLkJ1aWxkZXIgZ2V0SW50MzJGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBnZXRJbnQzMkZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWVPckJ1aWxkZXIgZ2V0SW50MzJGaWVsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKGludDMyRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGludDMyRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIGludDMyRmllbGRfID09IG51bGwgPwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBpbnQzMkZpZWxkXzsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWVPckJ1aWxkZXI+IAogICAgICAgIGdldEludDMyRmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGludDMyRmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgZ2V0SW50MzJGaWVsZCgpLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgaW50MzJGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBpbnQzMkZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMkZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWVPckJ1aWxkZXI+IHVpbnQzMkZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB1aW50MzJGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc1VpbnQzMkZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdWludDMyRmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIGdldFVpbnQzMkZpZWxkKCkgewogICAgICBpZiAodWludDMyRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHVpbnQzMkZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHVpbnQzMkZpZWxkXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gdWludDMyRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFVpbnQzMkZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdWludDMyRmllbGRfID0gdmFsdWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdWludDMyRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFVpbnQzMkZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHVpbnQzMkZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHVpbnQzMkZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVVpbnQzMkZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSAmJgogICAgICAgICAgdWludDMyRmllbGRfICE9IG51bGwgJiYKICAgICAgICAgIHVpbnQzMkZpZWxkXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBnZXRVaW50MzJGaWVsZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB1aW50MzJGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdWludDMyRmllbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICB9CiAgICAgIGlmICh1aW50MzJGaWVsZF8gIT0gbnVsbCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVWludDMyRmllbGQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA0MDAwKTsKICAgICAgdWludDMyRmllbGRfID0gbnVsbDsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHVpbnQzMkZpZWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgIHVpbnQzMkZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLkJ1aWxkZXIgZ2V0VWludDMyRmllbGRCdWlsZGVyKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZ2V0VWludDMyRmllbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZU9yQnVpbGRlciBnZXRVaW50MzJGaWVsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiB1aW50MzJGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gdWludDMyRmllbGRfID09IG51bGwgPwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogdWludDMyRmllbGRfOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlT3JCdWlsZGVyPiAKICAgICAgICBnZXRVaW50MzJGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKHVpbnQzMkZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHVpbnQzMkZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGdldFVpbnQzMkZpZWxkKCksCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICB1aW50MzJGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiB1aW50MzJGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbEZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVPckJ1aWxkZXI+IGJvb2xGaWVsZEJ1aWxkZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBib29sRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNCb29sRmllbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJvb2xGaWVsZC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGdldEJvb2xGaWVsZCgpIHsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gYm9vbEZpZWxkXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBib29sRmllbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBib29sRmllbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0Qm9vbEZpZWxkKGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChib29sRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBib29sRmllbGRfID0gdmFsdWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldEJvb2xGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoYm9vbEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGJvb2xGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBib29sRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VCb29sRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkgJiYKICAgICAgICAgIGJvb2xGaWVsZF8gIT0gbnVsbCAmJgogICAgICAgICAgYm9vbEZpZWxkXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgZ2V0Qm9vbEZpZWxkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJvb2xGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgfQogICAgICBpZiAoYm9vbEZpZWxkXyAhPSBudWxsKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZSBib29sX2ZpZWxkID0gMTY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJvb2xGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDgwMDApOwogICAgICBib29sRmllbGRfID0gbnVsbDsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBib29sRmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgYm9vbEZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLkJ1aWxkZXIgZ2V0Qm9vbEZpZWxkQnVpbGRlcigpIHsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIGdldEJvb2xGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlT3JCdWlsZGVyIGdldEJvb2xGaWVsZE9yQnVpbGRlcigpIHsKICAgICAgaWYgKGJvb2xGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gYm9vbEZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBib29sRmllbGRfID09IG51bGwgPwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGJvb2xGaWVsZF87CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0Qm9vbEZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoYm9vbEZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGJvb2xGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBnZXRCb29sRmllbGQoKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIGJvb2xGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBib29sRmllbGRCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUsIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZU9yQnVpbGRlcj4gc3RyaW5nRmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cmluZ0ZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyaW5nRmllbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmdGaWVsZC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgZ2V0U3RyaW5nRmllbGQoKSB7CiAgICAgIGlmIChzdHJpbmdGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gc3RyaW5nRmllbGRfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3RyaW5nRmllbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBzdHJpbmdGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyaW5nRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBzdHJpbmdGaWVsZF8gPSB2YWx1ZTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyaW5nRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgc3RyaW5nRmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RyaW5nRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlU3RyaW5nRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSB2YWx1ZSkgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApICYmCiAgICAgICAgICBzdHJpbmdGaWVsZF8gIT0gbnVsbCAmJgogICAgICAgICAgc3RyaW5nRmllbGRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldFN0cmluZ0ZpZWxkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN0cmluZ0ZpZWxkXyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBzdHJpbmdGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKHN0cmluZ0ZpZWxkXyAhPSBudWxsKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdHJpbmdGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICBzdHJpbmdGaWVsZF8gPSBudWxsOwogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgc3RyaW5nRmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgc3RyaW5nRmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuQnVpbGRlciBnZXRTdHJpbmdGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBnZXRTdHJpbmdGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyIGdldFN0cmluZ0ZpZWxkT3JCdWlsZGVyKCkgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgcmV0dXJuIHN0cmluZ0ZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBzdHJpbmdGaWVsZF8gPT0gbnVsbCA/CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdHJpbmdGaWVsZF87CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWVPckJ1aWxkZXI+IAogICAgICAgIGdldFN0cmluZ0ZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoc3RyaW5nRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgc3RyaW5nRmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgZ2V0U3RyaW5nRmllbGQoKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIHN0cmluZ0ZpZWxkXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIHN0cmluZ0ZpZWxkQnVpbGRlcl87CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyPiBieXRlc0ZpZWxkQnVpbGRlcl87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYnl0ZXNGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc0J5dGVzRmllbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXNGaWVsZC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBnZXRCeXRlc0ZpZWxkKCkgewogICAgICBpZiAoYnl0ZXNGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gYnl0ZXNGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGJ5dGVzRmllbGRfOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBieXRlc0ZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0Qnl0ZXNGaWVsZChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgdmFsdWUpIHsKICAgICAgaWYgKGJ5dGVzRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBieXRlc0ZpZWxkXyA9IHZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRCeXRlc0ZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAoYnl0ZXNGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBieXRlc0ZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUJ5dGVzRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIHZhbHVlKSB7CiAgICAgIGlmIChieXRlc0ZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSAmJgogICAgICAgICAgYnl0ZXNGaWVsZF8gIT0gbnVsbCAmJgogICAgICAgICAgYnl0ZXNGaWVsZF8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICBnZXRCeXRlc0ZpZWxkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJ5dGVzRmllbGRfID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICB9CiAgICAgIGlmIChieXRlc0ZpZWxkXyAhPSBudWxsKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUgYnl0ZXNfZmllbGQgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQnl0ZXNGaWVsZCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICBieXRlc0ZpZWxkXyA9IG51bGw7CiAgICAgIGlmIChieXRlc0ZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIGJ5dGVzRmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgYnl0ZXNGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZS5CdWlsZGVyIGdldEJ5dGVzRmllbGRCdWlsZGVyKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZ2V0Qnl0ZXNGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyIGdldEJ5dGVzRmllbGRPckJ1aWxkZXIoKSB7CiAgICAgIGlmIChieXRlc0ZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiBieXRlc0ZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBieXRlc0ZpZWxkXyA9PSBudWxsID8KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogYnl0ZXNGaWVsZF87CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyPiAKICAgICAgICBnZXRCeXRlc0ZpZWxkRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAoYnl0ZXNGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBieXRlc0ZpZWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgIGdldEJ5dGVzRmllbGQoKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIGJ5dGVzRmllbGRfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gYnl0ZXNGaWVsZEJ1aWxkZXJfOwogICAgfQoKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSB2YWx1ZUZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVmFsdWVPckJ1aWxkZXI+IHZhbHVlRmllbGRCdWlsZGVyXzsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFBhcnQgb2Ygc3RydWN0LCBidXQgdXNlZnVsIHRvIGJlIGFibGUgdG8gdGVzdCBzZXBhcmF0ZWx5CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHZhbHVlX2ZpZWxkID0gMTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZUZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzVmFsdWVGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUGFydCBvZiBzdHJ1Y3QsIGJ1dCB1c2VmdWwgdG8gYmUgYWJsZSB0byB0ZXN0IHNlcGFyYXRlbHkKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVmFsdWUgdmFsdWVfZmllbGQgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSB2YWx1ZUZpZWxkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSBnZXRWYWx1ZUZpZWxkKCkgewogICAgICBpZiAodmFsdWVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gdmFsdWVGaWVsZF8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiB2YWx1ZUZpZWxkXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gdmFsdWVGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUGFydCBvZiBzdHJ1Y3QsIGJ1dCB1c2VmdWwgdG8gYmUgYWJsZSB0byB0ZXN0IHNlcGFyYXRlbHkKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVmFsdWUgdmFsdWVfZmllbGQgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFZhbHVlRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSB2YWx1ZSkgewogICAgICBpZiAodmFsdWVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHZhbHVlRmllbGRfID0gdmFsdWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdmFsdWVGaWVsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUGFydCBvZiBzdHJ1Y3QsIGJ1dCB1c2VmdWwgdG8gYmUgYWJsZSB0byB0ZXN0IHNlcGFyYXRlbHkKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVmFsdWUgdmFsdWVfZmllbGQgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFZhbHVlRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAodmFsdWVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICB2YWx1ZUZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICB9IGVsc2UgewogICAgICAgIHZhbHVlRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFBhcnQgb2Ygc3RydWN0LCBidXQgdXNlZnVsIHRvIGJlIGFibGUgdG8gdGVzdCBzZXBhcmF0ZWx5CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHZhbHVlX2ZpZWxkID0gMTk7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVZhbHVlRmllbGQoY29tLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSB2YWx1ZSkgewogICAgICBpZiAodmFsdWVGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkgJiYKICAgICAgICAgIHZhbHVlRmllbGRfICE9IG51bGwgJiYKICAgICAgICAgIHZhbHVlRmllbGRfICE9IGNvbS5nb29nbGUucHJvdG9idWYuVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldFZhbHVlRmllbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdmFsdWVGaWVsZF8gPSB2YWx1ZTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdmFsdWVGaWVsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKHZhbHVlRmllbGRfICE9IG51bGwpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBQYXJ0IG9mIHN0cnVjdCwgYnV0IHVzZWZ1bCB0byBiZSBhYmxlIHRvIHRlc3Qgc2VwYXJhdGVseQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSB2YWx1ZV9maWVsZCA9IDE5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJWYWx1ZUZpZWxkKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgIHZhbHVlRmllbGRfID0gbnVsbDsKICAgICAgaWYgKHZhbHVlRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgdmFsdWVGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICB2YWx1ZUZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFBhcnQgb2Ygc3RydWN0LCBidXQgdXNlZnVsIHRvIGJlIGFibGUgdG8gdGVzdCBzZXBhcmF0ZWx5CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHZhbHVlX2ZpZWxkID0gMTk7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZS5CdWlsZGVyIGdldFZhbHVlRmllbGRCdWlsZGVyKCkgewogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gZ2V0VmFsdWVGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFBhcnQgb2Ygc3RydWN0LCBidXQgdXNlZnVsIHRvIGJlIGFibGUgdG8gdGVzdCBzZXBhcmF0ZWx5CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHZhbHVlX2ZpZWxkID0gMTk7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZU9yQnVpbGRlciBnZXRWYWx1ZUZpZWxkT3JCdWlsZGVyKCkgewogICAgICBpZiAodmFsdWVGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gdmFsdWVGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gdmFsdWVGaWVsZF8gPT0gbnVsbCA/CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVmFsdWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiB2YWx1ZUZpZWxkXzsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUGFydCBvZiBzdHJ1Y3QsIGJ1dCB1c2VmdWwgdG8gYmUgYWJsZSB0byB0ZXN0IHNlcGFyYXRlbHkKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVmFsdWUgdmFsdWVfZmllbGQgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVmFsdWVPckJ1aWxkZXI+IAogICAgICAgIGdldFZhbHVlRmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmICh2YWx1ZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHZhbHVlRmllbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlZhbHVlLCBjb20uZ29vZ2xlLnByb3RvYnVmLlZhbHVlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuVmFsdWVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgZ2V0VmFsdWVGaWVsZCgpLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgdmFsdWVGaWVsZF8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiB2YWx1ZUZpZWxkQnVpbGRlcl87CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgIH0KCgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFdlbGxLbm93blR5cGVzKQogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RXZWxsS25vd25UeXBlcykKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVGVzdFdlbGxLbm93blR5cGVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgc3RhdGljIHsKICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlRlc3RXZWxsS25vd25UeXBlcygpOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVGVzdFdlbGxLbm93blR5cGVzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFdlbGxLbm93blR5cGVzPgogICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0V2VsbEtub3duVHlwZXM+KCkgewogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIFRlc3RXZWxsS25vd25UeXBlcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgIHRyeSB7CiAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgfQogICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgIH0KICB9OwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RXZWxsS25vd25UeXBlcz4gcGFyc2VyKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFdlbGxLbm93blR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlRlc3RXZWxsS25vd25UeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgfQoKfQoKUEsDBAoAAAAAAAAAIQAtgfLDAiQAAAIkAAA5AAAAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0L1Rlc3RXZWxsS25vd25UeXBlc09yQnVpbGRlci5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfd2VsbF9rbm93bl90eXBlcy5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0OwoKcHVibGljIGludGVyZmFjZSBUZXN0V2VsbEtub3duVHlwZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RXZWxsS25vd25UeXBlcykKICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgYW55RmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzQW55RmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfZmllbGQgPSAxOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBhbnlGaWVsZC4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSBnZXRBbnlGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV9maWVsZCA9IDE7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuQW55T3JCdWlsZGVyIGdldEFueUZpZWxkT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgYXBpRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzQXBpRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFwaSBhcGlfZmllbGQgPSAyOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBhcGlGaWVsZC4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkFwaSBnZXRBcGlGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQXBpIGFwaV9maWVsZCA9IDI7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuQXBpT3JCdWlsZGVyIGdldEFwaUZpZWxkT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1cmF0aW9uRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzRHVyYXRpb25GaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBkdXJhdGlvbkZpZWxkLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZ2V0RHVyYXRpb25GaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRHVyYXRpb24gZHVyYXRpb25fZmllbGQgPSAzOzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uT3JCdWlsZGVyIGdldER1cmF0aW9uRmllbGRPckJ1aWxkZXIoKTsKCiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgZW1wdHlGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNFbXB0eUZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGVtcHR5RmllbGQuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBnZXRFbXB0eUZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5FbXB0eSBlbXB0eV9maWVsZCA9IDQ7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHlPckJ1aWxkZXIgZ2V0RW1wdHlGaWVsZE9yQnVpbGRlcigpOwoKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBmaWVsZF9tYXNrX2ZpZWxkID0gNTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE1hc2tGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNGaWVsZE1hc2tGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBmaWVsZE1hc2tGaWVsZC4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzayBnZXRGaWVsZE1hc2tGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIGZpZWxkX21hc2tfZmllbGQgPSA1OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza09yQnVpbGRlciBnZXRGaWVsZE1hc2tGaWVsZE9yQnVpbGRlcigpOwoKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNvdXJjZUNvbnRleHRGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNTb3VyY2VDb250ZXh0RmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQgc291cmNlX2NvbnRleHRfZmllbGQgPSA2OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBzb3VyY2VDb250ZXh0RmllbGQuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0IGdldFNvdXJjZUNvbnRleHRGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dCBzb3VyY2VfY29udGV4dF9maWVsZCA9IDY7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dE9yQnVpbGRlciBnZXRTb3VyY2VDb250ZXh0RmllbGRPckJ1aWxkZXIoKTsKCiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJ1Y3RGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNTdHJ1Y3RGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RydWN0IHN0cnVjdF9maWVsZCA9IDc7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHN0cnVjdEZpZWxkLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0IGdldFN0cnVjdEZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Qgc3RydWN0X2ZpZWxkID0gNzs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RPckJ1aWxkZXIgZ2V0U3RydWN0RmllbGRPckJ1aWxkZXIoKTsKCiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSB0aW1lc3RhbXBGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNUaW1lc3RhbXBGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIHRpbWVzdGFtcF9maWVsZCA9IDg7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHRpbWVzdGFtcEZpZWxkLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wIGdldFRpbWVzdGFtcEZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAgdGltZXN0YW1wX2ZpZWxkID0gODs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBPckJ1aWxkZXIgZ2V0VGltZXN0YW1wRmllbGRPckJ1aWxkZXIoKTsKCiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHR5cGVGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNUeXBlRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlR5cGUgdHlwZV9maWVsZCA9IDk7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHR5cGVGaWVsZC4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGUgZ2V0VHlwZUZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5UeXBlIHR5cGVfZmllbGQgPSA5OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGVPckJ1aWxkZXIgZ2V0VHlwZUZpZWxkT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUgZG91YmxlX2ZpZWxkID0gMTA7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgZG91YmxlRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzRG91YmxlRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGRvdWJsZV9maWVsZCA9IDEwOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBkb3VibGVGaWVsZC4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkRvdWJsZVZhbHVlIGdldERvdWJsZUZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZSBkb3VibGVfZmllbGQgPSAxMDs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZU9yQnVpbGRlciBnZXREb3VibGVGaWVsZE9yQnVpbGRlcigpOwoKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmbG9hdEZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc0Zsb2F0RmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZmxvYXRfZmllbGQgPSAxMTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgZmxvYXRGaWVsZC4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWUgZ2V0RmxvYXRGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZSBmbG9hdF9maWVsZCA9IDExOzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkZsb2F0VmFsdWVPckJ1aWxkZXIgZ2V0RmxvYXRGaWVsZE9yQnVpbGRlcigpOwoKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnQ2NEZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc0ludDY0RmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgaW50NjRfZmllbGQgPSAxMjs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgaW50NjRGaWVsZC4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUgZ2V0SW50NjRGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZSBpbnQ2NF9maWVsZCA9IDEyOzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWVPckJ1aWxkZXIgZ2V0SW50NjRGaWVsZE9yQnVpbGRlcigpOwoKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbHVlIHVpbnQ2NF9maWVsZCA9IDEzOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHVpbnQ2NEZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc1VpbnQ2NEZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSB1aW50NjRfZmllbGQgPSAxMzs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgdWludDY0RmllbGQuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZSBnZXRVaW50NjRGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUgdWludDY0X2ZpZWxkID0gMTM7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWVPckJ1aWxkZXIgZ2V0VWludDY0RmllbGRPckJ1aWxkZXIoKTsKCiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50MzJGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNJbnQzMkZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGludDMyX2ZpZWxkID0gMTQ7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGludDMyRmllbGQuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlIGdldEludDMyRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUgaW50MzJfZmllbGQgPSAxNDs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlT3JCdWlsZGVyIGdldEludDMyRmllbGRPckJ1aWxkZXIoKTsKCiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZSB1aW50MzJfZmllbGQgPSAxNTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSB1aW50MzJGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNVaW50MzJGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgdWludDMyX2ZpZWxkID0gMTU7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHVpbnQzMkZpZWxkLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuVUludDMyVmFsdWUgZ2V0VWludDMyRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlIHVpbnQzMl9maWVsZCA9IDE1OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlT3JCdWlsZGVyIGdldFVpbnQzMkZpZWxkT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlIGJvb2xfZmllbGQgPSAxNjs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBib29sRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzQm9vbEZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBib29sRmllbGQuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgZ2V0Qm9vbEZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUgYm9vbF9maWVsZCA9IDE2OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZU9yQnVpbGRlciBnZXRCb29sRmllbGRPckJ1aWxkZXIoKTsKCiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZSBzdHJpbmdfZmllbGQgPSAxNzs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNTdHJpbmdGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgc3RyaW5nX2ZpZWxkID0gMTc7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHN0cmluZ0ZpZWxkLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUgZ2V0U3RyaW5nRmllbGQoKTsKICAvKioKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlIHN0cmluZ19maWVsZCA9IDE3OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlT3JCdWlsZGVyIGdldFN0cmluZ0ZpZWxkT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJ5dGVzRmllbGQgZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzQnl0ZXNGaWVsZCgpOwogIC8qKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBieXRlc19maWVsZCA9IDE4OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBieXRlc0ZpZWxkLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSBnZXRCeXRlc0ZpZWxkKCk7CiAgLyoqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5CeXRlc1ZhbHVlIGJ5dGVzX2ZpZWxkID0gMTg7PC9jb2RlPgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZU9yQnVpbGRlciBnZXRCeXRlc0ZpZWxkT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxwcmU+CiAgICogUGFydCBvZiBzdHJ1Y3QsIGJ1dCB1c2VmdWwgdG8gYmUgYWJsZSB0byB0ZXN0IHNlcGFyYXRlbHkKICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuVmFsdWUgdmFsdWVfZmllbGQgPSAxOTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZUZpZWxkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc1ZhbHVlRmllbGQoKTsKICAvKioKICAgKiA8cHJlPgogICAqIFBhcnQgb2Ygc3RydWN0LCBidXQgdXNlZnVsIHRvIGJlIGFibGUgdG8gdGVzdCBzZXBhcmF0ZWx5CiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLlZhbHVlIHZhbHVlX2ZpZWxkID0gMTk7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHZhbHVlRmllbGQuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSBnZXRWYWx1ZUZpZWxkKCk7CiAgLyoqCiAgICogPHByZT4KICAgKiBQYXJ0IG9mIHN0cnVjdCwgYnV0IHVzZWZ1bCB0byBiZSBhYmxlIHRvIHRlc3Qgc2VwYXJhdGVseQogICAqIDwvcHJlPgogICAqCiAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSB2YWx1ZV9maWVsZCA9IDE5OzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLlZhbHVlT3JCdWlsZGVyIGdldFZhbHVlRmllbGRPckJ1aWxkZXIoKTsKfQpQSwMECgAAAAAAAAAhAEX9ow62ZwAAtmcAACwAAABjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3QvVW5pdHRlc3RJbXBvcnQuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIFVuaXR0ZXN0SW1wb3J0IHsKICBwcml2YXRlIFVuaXR0ZXN0SW1wb3J0KCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bX0KICAgKi8KICBwdWJsaWMgZW51bSBJbXBvcnRFbnVtCiAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgIC8qKgogICAgICogPGNvZGU+SU1QT1JUX0ZPTyA9IDc7PC9jb2RlPgogICAgICovCiAgICBJTVBPUlRfRk9PKDcpLAogICAgLyoqCiAgICAgKiA8Y29kZT5JTVBPUlRfQkFSID0gODs8L2NvZGU+CiAgICAgKi8KICAgIElNUE9SVF9CQVIoOCksCiAgICAvKioKICAgICAqIDxjb2RlPklNUE9SVF9CQVogPSA5OzwvY29kZT4KICAgICAqLwogICAgSU1QT1JUX0JBWig5KSwKICAgIDsKCiAgICAvKioKICAgICAqIDxjb2RlPklNUE9SVF9GT08gPSA3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU1QT1JUX0ZPT19WQUxVRSA9IDc7CiAgICAvKioKICAgICAqIDxjb2RlPklNUE9SVF9CQVIgPSA4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU1QT1JUX0JBUl9WQUxVRSA9IDg7CiAgICAvKioKICAgICAqIDxjb2RlPklNUE9SVF9CQVogPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU1QT1JUX0JBWl9WQUxVRSA9IDk7CgoKICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICByZXR1cm4gdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBzdGF0aWMgSW1wb3J0RW51bSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIEltcG9ydEVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgY2FzZSA3OiByZXR1cm4gSU1QT1JUX0ZPTzsKICAgICAgICBjYXNlIDg6IHJldHVybiBJTVBPUlRfQkFSOwogICAgICAgIGNhc2UgOTogcmV0dXJuIElNUE9SVF9CQVo7CiAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8SW1wb3J0RW51bT4KICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgSW1wb3J0RW51bT4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxJbXBvcnRFbnVtPigpIHsKICAgICAgICAgICAgcHVibGljIEltcG9ydEVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgIHJldHVybiBJbXBvcnRFbnVtLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwoKICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICB9CiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEltcG9ydEVudW1bXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICBwdWJsaWMgc3RhdGljIEltcG9ydEVudW0gdmFsdWVPZigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgfQogICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgcHJpdmF0ZSBJbXBvcnRFbnVtKGludCB2YWx1ZSkgewogICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW0pCiAgfQoKICAvKioKICAgKiA8cHJlPgogICAqIFRvIHVzZSBhbiBlbnVtIGluIGEgbWFwLCBpdCBtdXN0IGhhcyB0aGUgZmlyc3QgdmFsdWUgYXMgMC4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtRm9yTWFwfQogICAqLwogIHB1YmxpYyBlbnVtIEltcG9ydEVudW1Gb3JNYXAKICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgLyoqCiAgICAgKiA8Y29kZT5VTktOT1dOID0gMDs8L2NvZGU+CiAgICAgKi8KICAgIFVOS05PV04oMCksCiAgICAvKioKICAgICAqIDxjb2RlPkZPTyA9IDE7PC9jb2RlPgogICAgICovCiAgICBGT08oMSksCiAgICAvKioKICAgICAqIDxjb2RlPkJBUiA9IDI7PC9jb2RlPgogICAgICovCiAgICBCQVIoMiksCiAgICA7CgogICAgLyoqCiAgICAgKiA8Y29kZT5VTktOT1dOID0gMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOS05PV05fVkFMVUUgPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5GT08gPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX1ZBTFVFID0gMTsKICAgIC8qKgogICAgICogPGNvZGU+QkFSID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9WQUxVRSA9IDI7CgoKICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICByZXR1cm4gdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBzdGF0aWMgSW1wb3J0RW51bUZvck1hcCB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIEltcG9ydEVudW1Gb3JNYXAgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgY2FzZSAwOiByZXR1cm4gVU5LTk9XTjsKICAgICAgICBjYXNlIDE6IHJldHVybiBGT087CiAgICAgICAgY2FzZSAyOiByZXR1cm4gQkFSOwogICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPEltcG9ydEVudW1Gb3JNYXA+CiAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgIEltcG9ydEVudW1Gb3JNYXA+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8SW1wb3J0RW51bUZvck1hcD4oKSB7CiAgICAgICAgICAgIHB1YmxpYyBJbXBvcnRFbnVtRm9yTWFwIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gSW1wb3J0RW51bUZvck1hcC5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKCiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgfQogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgxKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBJbXBvcnRFbnVtRm9yTWFwW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgcHVibGljIHN0YXRpYyBJbXBvcnRFbnVtRm9yTWFwIHZhbHVlT2YoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgIH0KICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgfQoKICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgIHByaXZhdGUgSW1wb3J0RW51bUZvck1hcChpbnQgdmFsdWUpIHsKICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtRm9yTWFwKQogIH0KCiAgcHVibGljIGludGVyZmFjZSBJbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGQuCiAgICAgKi8KICAgIGludCBnZXREKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgSW1wb3J0TWVzc2FnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSkKICAgICAgSW1wb3J0TWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgSW1wb3J0TWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBJbXBvcnRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgSW1wb3J0TWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBJbXBvcnRNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9pbXBvcnRfSW1wb3J0TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0X0ltcG9ydE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IGRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEQoKSB7CiAgICAgIHJldHVybiBkXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGRfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBkXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlKSBvYmo7CgogICAgICBpZiAoaGFzRCgpICE9IG90aGVyLmhhc0QoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRCgpKSB7CiAgICAgICAgaWYgKGdldEQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXREKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNEKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydF9JbXBvcnRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0X0ltcG9ydE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGRfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9pbXBvcnRfSW1wb3J0TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRfID0gZF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNEKCkpIHsKICAgICAgICAgIHNldEQob3RoZXIuZ2V0RCgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBkXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgZF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEQoKSB7CiAgICAgICAgcmV0dXJuIGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEQoaW50IHZhbHVlKSB7CgogICAgICAgIGRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgZF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEltcG9ydE1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8SW1wb3J0TWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEltcG9ydE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxJbXBvcnRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEltcG9ydE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydF9JbXBvcnRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydF9JbXBvcnRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4lZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ltcG9ydC5wcm90b1wwMjIiICsKICAgICAgIlwwMzBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnRcMDMyLGdvb2dsZS9wcm90b2IiICsKICAgICAgInVmL3VuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG9cIlwwMzJcblxySW1wb3IiICsKICAgICAgInRNZXNzYWdlXDAyMlx0XG5cMDAxZFwwMzBcMDAxIFwwMDEoXDAwNSo8XG5cbkltcG9ydEVudW1cMDIyXDAxNlxuXG5JTVAiICsKICAgICAgIk9SVF9GT09cMDIwXDAwN1wwMjJcMDE2XG5cbklNUE9SVF9CQVJcMDIwXDAxMFwwMjJcMDE2XG5cbklNUE9SVF9CQVpcMDIwIiArCiAgICAgICJcdCoxXG5cMDIwSW1wb3J0RW51bUZvck1hcFwwMjJcMDEzXG5cMDA3VU5LTk9XTlwwMjBcMDAwXDAyMlwwMDdcblwwMDNGTyIgKwogICAgICAiT1wwMjBcMDAxXDAyMlwwMDdcblwwMDNCQVJcMDIwXDAwMkJcMDM3XG5cMDMwY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0IiArCiAgICAgICJIXDAwMVwzNzBcMDAxXDAwMVBcMDAwIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuZ2V0RGVzY3JpcHRvcigpLAogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydF9JbXBvcnRNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydF9JbXBvcnRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydF9JbXBvcnRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJEIiwgfSk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuZ2V0RGVzY3JpcHRvcigpOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEAgKkftQZRAAAGUQAAMgAAAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdC9Vbml0dGVzdEltcG9ydFB1YmxpYy5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIFVuaXR0ZXN0SW1wb3J0UHVibGljIHsKICBwcml2YXRlIFVuaXR0ZXN0SW1wb3J0UHVibGljKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBwdWJsaWMgaW50ZXJmYWNlIFB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0UoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZS4KICAgICAqLwogICAgaW50IGdldEUoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBQdWJsaWNJbXBvcnRNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlKQogICAgICBQdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBQdWJsaWNJbXBvcnRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFB1YmxpY0ltcG9ydE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBQdWJsaWNJbXBvcnRNZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFB1YmxpY0ltcG9ydE1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydF9QdWJsaWNJbXBvcnRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9pbXBvcnRfUHVibGljSW1wb3J0TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgZV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNFKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RSgpIHsKICAgICAgcmV0dXJuIGVfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgZV8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIGVfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UpIG9iajsKCiAgICAgIGlmIChoYXNFKCkgIT0gb3RoZXIuaGFzRSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNFKCkpIHsKICAgICAgICBpZiAoZ2V0RSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEUoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0X1B1YmxpY0ltcG9ydE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9pbXBvcnRfUHVibGljSW1wb3J0TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgZV8gPSAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydF9QdWJsaWNJbXBvcnRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSByZXN1bHQgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZV8gPSBlXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0UoKSkgewogICAgICAgICAgc2V0RShvdGhlci5nZXRFKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIGVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBlXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RSgpIHsKICAgICAgICByZXR1cm4gZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGUgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RShpbnQgdmFsdWUpIHsKCiAgICAgICAgZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJFKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBlXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHVibGljSW1wb3J0TWVzc2FnZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxQdWJsaWNJbXBvcnRNZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgUHVibGljSW1wb3J0TWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFB1YmxpY0ltcG9ydE1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UHVibGljSW1wb3J0TWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0X1B1YmxpY0ltcG9ydE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0X1B1YmxpY0ltcG9ydE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcbixnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpYyIgKwogICAgICAiLnByb3RvXDAyMlwwMzBwcm90b2J1Zl91bml0dGVzdF9pbXBvcnRcIiBcblwwMjNQdWJsIiArCiAgICAgICJpY0ltcG9ydE1lc3NhZ2VcMDIyXHRcblwwMDFlXDAzMFwwMDEgXDAwMShcMDA1QlwwMzJcblwwMzBjb20uZ29vZ2xlIiArCiAgICAgICIucHJvdG9idWYudGVzdCIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydF9QdWJsaWNJbXBvcnRNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydF9QdWJsaWNJbXBvcnRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydF9QdWJsaWNJbXBvcnRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJFIiwgfSk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQCteki53ngAAN54AAA0AAAAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0L1VuaXR0ZXN0V2VsbEtub3duVHlwZXMuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3dlbGxfa25vd25fdHlwZXMucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdDsKCnB1YmxpYyBmaW5hbCBjbGFzcyBVbml0dGVzdFdlbGxLbm93blR5cGVzIHsKICBwcml2YXRlIFVuaXR0ZXN0V2VsbEtub3duVHlwZXMoKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0V2VsbEtub3duVHlwZXNfZGVzY3JpcHRvcjsKICBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RXZWxsS25vd25UeXBlc19maWVsZEFjY2Vzc29yVGFibGU7CiAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkV2VsbEtub3duVHlwZXNfZGVzY3JpcHRvcjsKICBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkV2VsbEtub3duVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbmVvZldlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbmVvZldlbGxLbm93blR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfZGVzY3JpcHRvcjsKICBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfQW55RmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfQW55RmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0FwaUZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0FwaUZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19EdXJhdGlvbkZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0R1cmF0aW9uRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0VtcHR5RmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRW1wdHlGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRmllbGRNYXNrRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRmllbGRNYXNrRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX1NvdXJjZUNvbnRleHRGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19Tb3VyY2VDb250ZXh0RmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX1N0cnVjdEZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX1N0cnVjdEZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19UaW1lc3RhbXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19UaW1lc3RhbXBGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfVHlwZUZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX1R5cGVGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRG91YmxlRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRG91YmxlRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0Zsb2F0RmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRmxvYXRGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfSW50NjRGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19JbnQ2NEZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19VaW50NjRGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19VaW50NjRGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19JbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19VaW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19VaW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfQm9vbEZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0Jvb2xGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfU3RyaW5nRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfQnl0ZXNGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4vZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3dlbGxfa25vd25fdHkiICsKICAgICAgInBlcy5wcm90b1wwMjJcMDIxcHJvdG9idWZfdW5pdHRlc3RcMDMyXDAzMWdvb2dsZS9wcm8iICsKICAgICAgInRvYnVmL2FueS5wcm90b1wwMzJcMDMxZ29vZ2xlL3Byb3RvYnVmL2FwaS5wcm8iICsKICAgICAgInRvXDAzMlwwMzZnb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG9cMDMyXDAzM2dvb2ciICsKICAgICAgImxlL3Byb3RvYnVmL2VtcHR5LnByb3RvXDAzMiBnb29nbGUvcHJvdG9idWYiICsKICAgICAgIi9maWVsZF9tYXNrLnByb3RvXDAzMiRnb29nbGUvcHJvdG9idWYvc291cmMiICsKICAgICAgImVfY29udGV4dC5wcm90b1wwMzJcMDM0Z29vZ2xlL3Byb3RvYnVmL3N0cnVjdC4iICsKICAgICAgInByb3RvXDAzMlwwMzdnb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvXDAzMlwwMzIiICsKICAgICAgImdvb2dsZS9wcm90b2J1Zi90eXBlLnByb3RvXDAzMlwwMzZnb29nbGUvcHJvdG8iICsKICAgICAgImJ1Zi93cmFwcGVycy5wcm90b1wiXDI3NlwwMDdcblwwMjJUZXN0V2VsbEtub3duVHlwZSIgKwogICAgICAic1wwMjJcJ1xuXHRhbnlfZmllbGRcMDMwXDAwMSBcMDAxKFwwMTMyXDAyNC5nb29nbGUucHJvdG9idWYuQSIgKwogICAgICAibnlcMDIyXCdcblx0YXBpX2ZpZWxkXDAzMFwwMDIgXDAwMShcMDEzMlwwMjQuZ29vZ2xlLnByb3RvYnVmLiIgKwogICAgICAiQXBpXDAyMjFcblwwMTZkdXJhdGlvbl9maWVsZFwwMzBcMDAzIFwwMDEoXDAxMzJcMDMxLmdvb2dsZS5wcm8iICsKICAgICAgInRvYnVmLkR1cmF0aW9uXDAyMitcblwwMTNlbXB0eV9maWVsZFwwMzBcMDA0IFwwMDEoXDAxMzJcMDI2LmdvIiArCiAgICAgICJvZ2xlLnByb3RvYnVmLkVtcHR5XDAyMjRcblwwMjBmaWVsZF9tYXNrX2ZpZWxkXDAzMCIgKwogICAgICAiXDAwNSBcMDAxKFwwMTMyXDAzMi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrXDAyMjxcblwwMjRzb3UiICsKICAgICAgInJjZV9jb250ZXh0X2ZpZWxkXDAzMFwwMDYgXDAwMShcMDEzMlwwMzYuZ29vZ2xlLnByb3RvYnUiICsKICAgICAgImYuU291cmNlQ29udGV4dFwwMjItXG5cMDE0c3RydWN0X2ZpZWxkXDAzMFwwMDcgXDAwMShcMDEzMlwwMjcuIiArCiAgICAgICJnb29nbGUucHJvdG9idWYuU3RydWN0XDAyMjNcblwwMTd0aW1lc3RhbXBfZmllbCIgKwogICAgICAiZFwwMzBcMDEwIFwwMDEoXDAxMzJcMDMyLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBcMDIyKVxuXG50IiArCiAgICAgICJ5cGVfZmllbGRcMDMwXHQgXDAwMShcMDEzMlwwMjUuZ29vZ2xlLnByb3RvYnVmLlR5cGVcMDIyMiIgKwogICAgICAiXG5cMDE0ZG91YmxlX2ZpZWxkXDAzMFxuIFwwMDEoXDAxMzJcMDM0Lmdvb2dsZS5wcm90b2J1Zi5EIiArCiAgICAgICJvdWJsZVZhbHVlXDAyMjBcblwwMTNmbG9hdF9maWVsZFwwMzBcMDEzIFwwMDEoXDAxMzJcMDMzLmdvb2dsZSIgKwogICAgICAiLnByb3RvYnVmLkZsb2F0VmFsdWVcMDIyMFxuXDAxM2ludDY0X2ZpZWxkXDAzMFwwMTQgXDAwMSgiICsKICAgICAgIlwwMTMyXDAzMy5nb29nbGUucHJvdG9idWYuSW50NjRWYWx1ZVwwMjIyXG5cMDE0dWludDY0IiArCiAgICAgICJfZmllbGRcMDMwXHIgXDAwMShcMDEzMlwwMzQuZ29vZ2xlLnByb3RvYnVmLlVJbnQ2NFZhbCIgKwogICAgICAidWVcMDIyMFxuXDAxM2ludDMyX2ZpZWxkXDAzMFwwMTYgXDAwMShcMDEzMlwwMzMuZ29vZ2xlLnByb3RvYnUiICsKICAgICAgImYuSW50MzJWYWx1ZVwwMjIyXG5cMDE0dWludDMyX2ZpZWxkXDAzMFwwMTcgXDAwMShcMDEzMlwwMzQuZ29vIiArCiAgICAgICJnbGUucHJvdG9idWYuVUludDMyVmFsdWVcMDIyLlxuXG5ib29sX2ZpZWxkXDAzMFwwMjAiICsKICAgICAgIiBcMDAxKFwwMTMyXDAzMi5nb29nbGUucHJvdG9idWYuQm9vbFZhbHVlXDAyMjJcblwwMTRzdHJpIiArCiAgICAgICJuZ19maWVsZFwwMzBcMDIxIFwwMDEoXDAxMzJcMDM0Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWIiArCiAgICAgICJhbHVlXDAyMjBcblwwMTNieXRlc19maWVsZFwwMzBcMDIyIFwwMDEoXDAxMzJcMDMzLmdvb2dsZS5wcm90byIgKwogICAgICAiYnVmLkJ5dGVzVmFsdWVcMDIyK1xuXDAxM3ZhbHVlX2ZpZWxkXDAzMFwwMjMgXDAwMShcMDEzMlwwMjYuZ28iICsKICAgICAgIm9nbGUucHJvdG9idWYuVmFsdWVcIlwyMjVcMDA3XG5cMDI2UmVwZWF0ZWRXZWxsS25vdyIgKwogICAgICAiblR5cGVzXDAyMlwnXG5cdGFueV9maWVsZFwwMzBcMDAxIFwwMDMoXDAxMzJcMDI0Lmdvb2dsZS5wcm90byIgKwogICAgICAiYnVmLkFueVwwMjJcJ1xuXHRhcGlfZmllbGRcMDMwXDAwMiBcMDAzKFwwMTMyXDAyNC5nb29nbGUucHJvdCIgKwogICAgICAib2J1Zi5BcGlcMDIyMVxuXDAxNmR1cmF0aW9uX2ZpZWxkXDAzMFwwMDMgXDAwMyhcMDEzMlwwMzEuZ29vZ2wiICsKICAgICAgImUucHJvdG9idWYuRHVyYXRpb25cMDIyK1xuXDAxM2VtcHR5X2ZpZWxkXDAzMFwwMDQgXDAwMyhcMDEzIiArCiAgICAgICIyXDAyNi5nb29nbGUucHJvdG9idWYuRW1wdHlcMDIyNFxuXDAyMGZpZWxkX21hc2tfZiIgKwogICAgICAiaWVsZFwwMzBcMDA1IFwwMDMoXDAxMzJcMDMyLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tcMDIyPCIgKwogICAgICAiXG5cMDI0c291cmNlX2NvbnRleHRfZmllbGRcMDMwXDAwNiBcMDAzKFwwMTMyXDAzNi5nb29nbGUucHIiICsKICAgICAgIm90b2J1Zi5Tb3VyY2VDb250ZXh0XDAyMi1cblwwMTRzdHJ1Y3RfZmllbGRcMDMwXDAwNyBcMDAzIiArCiAgICAgICIoXDAxMzJcMDI3Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RcMDIyM1xuXDAxN3RpbWVzdGFtcCIgKwogICAgICAiX2ZpZWxkXDAzMFwwMTAgXDAwMyhcMDEzMlwwMzIuZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCIgKwogICAgICAiXDAyMilcblxudHlwZV9maWVsZFwwMzBcdCBcMDAzKFwwMTMyXDAyNS5nb29nbGUucHJvdG9idWYuVCIgKwogICAgICAieXBlXDAyMjJcblwwMTRkb3VibGVfZmllbGRcMDMwXG4gXDAwMyhcMDEzMlwwMzQuZ29vZ2xlLnByb3RvIiArCiAgICAgICJidWYuRG91YmxlVmFsdWVcMDIyMFxuXDAxM2Zsb2F0X2ZpZWxkXDAzMFwwMTMgXDAwMyhcMDEzMlwwMzMuZyIgKwogICAgICAib29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZVwwMjIwXG5cMDEzaW50NjRfZmllbGQiICsKICAgICAgIlwwMzBcMDE0IFwwMDMoXDAxMzJcMDMzLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlXDAyMjJcblwwMTR1IiArCiAgICAgICJpbnQ2NF9maWVsZFwwMzBcciBcMDAzKFwwMTMyXDAzNC5nb29nbGUucHJvdG9idWYuVUludCIgKwogICAgICAiNjRWYWx1ZVwwMjIwXG5cMDEzaW50MzJfZmllbGRcMDMwXDAxNiBcMDAzKFwwMTMyXDAzMy5nb29nbGUucHIiICsKICAgICAgIm90b2J1Zi5JbnQzMlZhbHVlXDAyMjJcblwwMTR1aW50MzJfZmllbGRcMDMwXDAxNyBcMDAzKFwwMTMyIiArCiAgICAgICJcMDM0Lmdvb2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZVwwMjIuXG5cbmJvb2xfZmkiICsKICAgICAgImVsZFwwMzBcMDIwIFwwMDMoXDAxMzJcMDMyLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWVcMDIyMlxuIiArCiAgICAgICJcMDE0c3RyaW5nX2ZpZWxkXDAzMFwwMjEgXDAwMyhcMDEzMlwwMzQuZ29vZ2xlLnByb3RvYnVmLlN0IiArCiAgICAgICJyaW5nVmFsdWVcMDIyMFxuXDAxM2J5dGVzX2ZpZWxkXDAzMFwwMjIgXDAwMyhcMDEzMlwwMzMuZ29vZ2xlLiIgKwogICAgICAicHJvdG9idWYuQnl0ZXNWYWx1ZVwiXDMwNVwwMDdcblwwMjNPbmVvZldlbGxLbm93blR5IiArCiAgICAgICJwZXNcMDIyKVxuXHRhbnlfZmllbGRcMDMwXDAwMSBcMDAxKFwwMTMyXDAyNC5nb29nbGUucHJvdG9idWYiICsKICAgICAgIi5BbnlIXDAwMFwwMjIpXG5cdGFwaV9maWVsZFwwMzBcMDAyIFwwMDEoXDAxMzJcMDI0Lmdvb2dsZS5wcm90byIgKwogICAgICAiYnVmLkFwaUhcMDAwXDAyMjNcblwwMTZkdXJhdGlvbl9maWVsZFwwMzBcMDAzIFwwMDEoXDAxMzJcMDMxLmdvb2ciICsKICAgICAgImxlLnByb3RvYnVmLkR1cmF0aW9uSFwwMDBcMDIyLVxuXDAxM2VtcHR5X2ZpZWxkXDAzMFwwMDQgIiArCiAgICAgICJcMDAxKFwwMTMyXDAyNi5nb29nbGUucHJvdG9idWYuRW1wdHlIXDAwMFwwMjI2XG5cMDIwZmllbGRfbSIgKwogICAgICAiYXNrX2ZpZWxkXDAzMFwwMDUgXDAwMShcMDEzMlwwMzIuZ29vZ2xlLnByb3RvYnVmLkZpZWxkTSIgKwogICAgICAiYXNrSFwwMDBcMDIyPlxuXDAyNHNvdXJjZV9jb250ZXh0X2ZpZWxkXDAzMFwwMDYgXDAwMShcMDEzMlwwMzYuZ28iICsKICAgICAgIm9nbGUucHJvdG9idWYuU291cmNlQ29udGV4dEhcMDAwXDAyMi9cblwwMTRzdHJ1Y3RfIiArCiAgICAgICJmaWVsZFwwMzBcMDA3IFwwMDEoXDAxMzJcMDI3Lmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RIXDAwMFwwMjI1IiArCiAgICAgICJcblwwMTd0aW1lc3RhbXBfZmllbGRcMDMwXDAxMCBcMDAxKFwwMTMyXDAzMi5nb29nbGUucHJvdG9idSIgKwogICAgICAiZi5UaW1lc3RhbXBIXDAwMFwwMjIrXG5cbnR5cGVfZmllbGRcMDMwXHQgXDAwMShcMDEzMlwwMjUuZ29vZyIgKwogICAgICAibGUucHJvdG9idWYuVHlwZUhcMDAwXDAyMjRcblwwMTRkb3VibGVfZmllbGRcMDMwXG4gXDAwMShcMDEzIiArCiAgICAgICIyXDAzNC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWVIXDAwMFwwMjIyXG5cMDEzZmxvYSIgKwogICAgICAidF9maWVsZFwwMzBcMDEzIFwwMDEoXDAxMzJcMDMzLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbCIgKwogICAgICAidWVIXDAwMFwwMjIyXG5cMDEzaW50NjRfZmllbGRcMDMwXDAxNCBcMDAxKFwwMTMyXDAzMy5nb29nbGUucHJvdG8iICsKICAgICAgImJ1Zi5JbnQ2NFZhbHVlSFwwMDBcMDIyNFxuXDAxNHVpbnQ2NF9maWVsZFwwMzBcciBcMDAxKFwwMTMyXDAzNCIgKwogICAgICAiLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZUhcMDAwXDAyMjJcblwwMTNpbnQzMl8iICsKICAgICAgImZpZWxkXDAzMFwwMTYgXDAwMShcMDEzMlwwMzMuZ29vZ2xlLnByb3RvYnVmLkludDMyVmFsdWUiICsKICAgICAgIkhcMDAwXDAyMjRcblwwMTR1aW50MzJfZmllbGRcMDMwXDAxNyBcMDAxKFwwMTMyXDAzNC5nb29nbGUucHJvdG9iIiArCiAgICAgICJ1Zi5VSW50MzJWYWx1ZUhcMDAwXDAyMjBcblxuYm9vbF9maWVsZFwwMzBcMDIwIFwwMDEoXDAxMzJcMDMyLmciICsKICAgICAgIm9vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZUhcMDAwXDAyMjRcblwwMTRzdHJpbmdfZmllIiArCiAgICAgICJsZFwwMzBcMDIxIFwwMDEoXDAxMzJcMDM0Lmdvb2dsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZUhcMDAwIiArCiAgICAgICJcMDIyMlxuXDAxM2J5dGVzX2ZpZWxkXDAzMFwwMjIgXDAwMShcMDEzMlwwMzMuZ29vZ2xlLnByb3RvYnVmLiIgKwogICAgICAiQnl0ZXNWYWx1ZUhcMDAwQlxyXG5cMDEzb25lb2ZfZmllbGRcIlwyMjZcMDI2XG5cMDIxTWFwV2VsbEsiICsKICAgICAgIm5vd25UeXBlc1wwMjJFXG5cdGFueV9maWVsZFwwMzBcMDAxIFwwMDMoXDAxMzIyLnByb3RvYnVmXyIgKwogICAgICAidW5pdHRlc3QuTWFwV2VsbEtub3duVHlwZXMuQW55RmllbGRFbnRyeSIgKwogICAgICAiXDAyMkVcblx0YXBpX2ZpZWxkXDAzMFwwMDIgXDAwMyhcMDEzMjIucHJvdG9idWZfdW5pdHRlc3QuIiArCiAgICAgICJNYXBXZWxsS25vd25UeXBlcy5BcGlGaWVsZEVudHJ5XDAyMk9cblwwMTZkdXJhdCIgKwogICAgICAiaW9uX2ZpZWxkXDAzMFwwMDMgXDAwMyhcMDEzMjcucHJvdG9idWZfdW5pdHRlc3QuTWFwVyIgKwogICAgICAiZWxsS25vd25UeXBlcy5EdXJhdGlvbkZpZWxkRW50cnlcMDIySVxuXDAxM2VtcHQiICsKICAgICAgInlfZmllbGRcMDMwXDAwNCBcMDAzKFwwMTMyNC5wcm90b2J1Zl91bml0dGVzdC5NYXBXZWwiICsKICAgICAgImxLbm93blR5cGVzLkVtcHR5RmllbGRFbnRyeVwwMjJSXG5cMDIwZmllbGRfbWFzIiArCiAgICAgICJrX2ZpZWxkXDAzMFwwMDUgXDAwMyhcMDEzMjgucHJvdG9idWZfdW5pdHRlc3QuTWFwV2VsIiArCiAgICAgICJsS25vd25UeXBlcy5GaWVsZE1hc2tGaWVsZEVudHJ5XDAyMlpcblwwMjRzb3VyYyIgKwogICAgICAiZV9jb250ZXh0X2ZpZWxkXDAzMFwwMDYgXDAwMyhcMDEzMjwucHJvdG9idWZfdW5pdHRlcyIgKwogICAgICAidC5NYXBXZWxsS25vd25UeXBlcy5Tb3VyY2VDb250ZXh0RmllbGRFbiIgKwogICAgICAidHJ5XDAyMktcblwwMTRzdHJ1Y3RfZmllbGRcMDMwXDAwNyBcMDAzKFwwMTMyNS5wcm90b2J1Zl91bmkiICsKICAgICAgInR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzLlN0cnVjdEZpZWxkRW50cnkiICsKICAgICAgIlwwMjJRXG5cMDE3dGltZXN0YW1wX2ZpZWxkXDAzMFwwMTAgXDAwMyhcMDEzMjgucHJvdG9idWZfdW5pIiArCiAgICAgICJ0dGVzdC5NYXBXZWxsS25vd25UeXBlcy5UaW1lc3RhbXBGaWVsZEVuIiArCiAgICAgICJ0cnlcMDIyR1xuXG50eXBlX2ZpZWxkXDAzMFx0IFwwMDMoXDAxMzIzLnByb3RvYnVmX3VuaXR0IiArCiAgICAgICJlc3QuTWFwV2VsbEtub3duVHlwZXMuVHlwZUZpZWxkRW50cnlcMDIyS1xuXDAxNCIgKwogICAgICAiZG91YmxlX2ZpZWxkXDAzMFxuIFwwMDMoXDAxMzI1LnByb3RvYnVmX3VuaXR0ZXN0Lk0iICsKICAgICAgImFwV2VsbEtub3duVHlwZXMuRG91YmxlRmllbGRFbnRyeVwwMjJJXG5cMDEzZmxvIiArCiAgICAgICJhdF9maWVsZFwwMzBcMDEzIFwwMDMoXDAxMzI0LnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlIiArCiAgICAgICJsbEtub3duVHlwZXMuRmxvYXRGaWVsZEVudHJ5XDAyMklcblwwMTNpbnQ2NF9maSIgKwogICAgICAiZWxkXDAzMFwwMTQgXDAwMyhcMDEzMjQucHJvdG9idWZfdW5pdHRlc3QuTWFwV2VsbEtubyIgKwogICAgICAid25UeXBlcy5JbnQ2NEZpZWxkRW50cnlcMDIyS1xuXDAxNHVpbnQ2NF9maWVsZFwwMzAiICsKICAgICAgIlxyIFwwMDMoXDAxMzI1LnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5IiArCiAgICAgICJwZXMuVWludDY0RmllbGRFbnRyeVwwMjJJXG5cMDEzaW50MzJfZmllbGRcMDMwXDAxNiBcMDAzKCIgKwogICAgICAiXDAxMzI0LnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzLiIgKwogICAgICAiSW50MzJGaWVsZEVudHJ5XDAyMktcblwwMTR1aW50MzJfZmllbGRcMDMwXDAxNyBcMDAzKFwwMTMyNS4iICsKICAgICAgInByb3RvYnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzLlVpbnQiICsKICAgICAgIjMyRmllbGRFbnRyeVwwMjJHXG5cbmJvb2xfZmllbGRcMDMwXDAyMCBcMDAzKFwwMTMyMy5wcm90byIgKwogICAgICAiYnVmX3VuaXR0ZXN0Lk1hcFdlbGxLbm93blR5cGVzLkJvb2xGaWVsZCIgKwogICAgICAiRW50cnlcMDIyS1xuXDAxNHN0cmluZ19maWVsZFwwMzBcMDIxIFwwMDMoXDAxMzI1LnByb3RvYnVmX3UiICsKICAgICAgIm5pdHRlc3QuTWFwV2VsbEtub3duVHlwZXMuU3RyaW5nRmllbGRFbnQiICsKICAgICAgInJ5XDAyMklcblwwMTNieXRlc19maWVsZFwwMzBcMDIyIFwwMDMoXDAxMzI0LnByb3RvYnVmX3VuaXR0IiArCiAgICAgICJlc3QuTWFwV2VsbEtub3duVHlwZXMuQnl0ZXNGaWVsZEVudHJ5XDAzMkVcbiIgKwogICAgICAiXHJBbnlGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyI1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSIgKwogICAgICAiKFwwMTMyXDAyNC5nb29nbGUucHJvdG9idWYuQW55OlwwMDI4XDAwMVwwMzJFXG5cckFwaUZpZWxkIiArCiAgICAgICJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMiNcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzJcMDI0Lmdvb2ciICsKICAgICAgImxlLnByb3RvYnVmLkFwaTpcMDAyOFwwMDFcMDMyT1xuXDAyMkR1cmF0aW9uRmllbGRFbnRyIiArCiAgICAgICJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyKFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMlwwMzEuZ29vZ2xlLnAiICsKICAgICAgInJvdG9idWYuRHVyYXRpb246XDAwMjhcMDAxXDAzMklcblwwMTdFbXB0eUZpZWxkRW50cnlcMDIyIiArCiAgICAgICJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMiVcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzJcMDI2Lmdvb2dsZS5wcm8iICsKICAgICAgInRvYnVmLkVtcHR5OlwwMDI4XDAwMVwwMzJRXG5cMDIzRmllbGRNYXNrRmllbGRFbnRyeVwwMjJcMDEzIiArCiAgICAgICJcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyKVxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMlwwMzIuZ29vZ2xlLnByb3QiICsKICAgICAgIm9idWYuRmllbGRNYXNrOlwwMDI4XDAwMVwwMzJZXG5cMDI3U291cmNlQ29udGV4dEZpZWxkIiArCiAgICAgICJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMi1cblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzJcMDM2Lmdvb2ciICsKICAgICAgImxlLnByb3RvYnVmLlNvdXJjZUNvbnRleHQ6XDAwMjhcMDAxXDAzMktcblwwMjBTdHJ1Y3RGIiArCiAgICAgICJpZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjImXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyXDAyNy4iICsKICAgICAgImdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3Q6XDAwMjhcMDAxXDAzMlFcblwwMjNUaW1lc3RhbXBGIiArCiAgICAgICJpZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjIpXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyXDAzMi4iICsKICAgICAgImdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXA6XDAwMjhcMDAxXDAzMkdcblwwMTZUeXBlRmllIiArCiAgICAgICJsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyJFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMlwwMjUuZ28iICsKICAgICAgIm9nbGUucHJvdG9idWYuVHlwZTpcMDAyOFwwMDFcMDMyUFxuXDAyMERvdWJsZUZpZWxkRW50IiArCiAgICAgICJyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMitcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzJcMDM0Lmdvb2dsZS4iICsKICAgICAgInByb3RvYnVmLkRvdWJsZVZhbHVlOlwwMDI4XDAwMVwwMzJOXG5cMDE3RmxvYXRGaWVsZEVuIiArCiAgICAgICJ0cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjIqXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyXDAzMy5nb29nbGUiICsKICAgICAgIi5wcm90b2J1Zi5GbG9hdFZhbHVlOlwwMDI4XDAwMVwwMzJOXG5cMDE3SW50NjRGaWVsZEVuIiArCiAgICAgICJ0cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjIqXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyXDAzMy5nb29nbGUiICsKICAgICAgIi5wcm90b2J1Zi5JbnQ2NFZhbHVlOlwwMDI4XDAwMVwwMzJQXG5cMDIwVWludDY0RmllbGRFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyK1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMlwwMzQuZ29vZ2wiICsKICAgICAgImUucHJvdG9idWYuVUludDY0VmFsdWU6XDAwMjhcMDAxXDAzMk5cblwwMTdJbnQzMkZpZWxkIiArCiAgICAgICJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMipcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzJcMDMzLmdvb2ciICsKICAgICAgImxlLnByb3RvYnVmLkludDMyVmFsdWU6XDAwMjhcMDAxXDAzMlBcblwwMjBVaW50MzJGaWVsIiArCiAgICAgICJkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjIrXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyXDAzNC5nb28iICsKICAgICAgImdsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZTpcMDAyOFwwMDFcMDMyTFxuXDAxNkJvb2xGaWVsIiArCiAgICAgICJkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjIpXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyXDAzMi5nb28iICsKICAgICAgImdsZS5wcm90b2J1Zi5Cb29sVmFsdWU6XDAwMjhcMDAxXDAzMlBcblwwMjBTdHJpbmdGaWVsIiArCiAgICAgICJkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjIrXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyXDAzNC5nb28iICsKICAgICAgImdsZS5wcm90b2J1Zi5TdHJpbmdWYWx1ZTpcMDAyOFwwMDFcMDMyTlxuXDAxN0J5dGVzRmllIiArCiAgICAgICJsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyKlxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMlwwMzMuZ28iICsKICAgICAgIm9nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZTpcMDAyOFwwMDFCOVxuXDAzMGNvbS5nb29nIiArCiAgICAgICJsZS5wcm90b2J1Zi50ZXN0UFwwMDFcMjUyXDAwMlwwMzJHb29nbGUuUHJvdG9idWYuVGVzIiArCiAgICAgICJ0UHJvdG9zYlwwMDZwcm90bzMiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55UHJvdG8uZ2V0RGVzY3JpcHRvcigpLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BcGlQcm90by5nZXREZXNjcmlwdG9yKCksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uUHJvdG8uZ2V0RGVzY3JpcHRvcigpLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FbXB0eVByb3RvLmdldERlc2NyaXB0b3IoKSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrUHJvdG8uZ2V0RGVzY3JpcHRvcigpLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb250ZXh0UHJvdG8uZ2V0RGVzY3JpcHRvcigpLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RQcm90by5nZXREZXNjcmlwdG9yKCksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcFByb3RvLmdldERlc2NyaXB0b3IoKSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuVHlwZVByb3RvLmdldERlc2NyaXB0b3IoKSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV3JhcHBlcnNQcm90by5nZXREZXNjcmlwdG9yKCksCiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RXZWxsS25vd25UeXBlc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0V2VsbEtub3duVHlwZXNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkFueUZpZWxkIiwgIkFwaUZpZWxkIiwgIkR1cmF0aW9uRmllbGQiLCAiRW1wdHlGaWVsZCIsICJGaWVsZE1hc2tGaWVsZCIsICJTb3VyY2VDb250ZXh0RmllbGQiLCAiU3RydWN0RmllbGQiLCAiVGltZXN0YW1wRmllbGQiLCAiVHlwZUZpZWxkIiwgIkRvdWJsZUZpZWxkIiwgIkZsb2F0RmllbGQiLCAiSW50NjRGaWVsZCIsICJVaW50NjRGaWVsZCIsICJJbnQzMkZpZWxkIiwgIlVpbnQzMkZpZWxkIiwgIkJvb2xGaWVsZCIsICJTdHJpbmdGaWVsZCIsICJCeXRlc0ZpZWxkIiwgIlZhbHVlRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SZXBlYXRlZFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkV2VsbEtub3duVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmVwZWF0ZWRXZWxsS25vd25UeXBlc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQW55RmllbGQiLCAiQXBpRmllbGQiLCAiRHVyYXRpb25GaWVsZCIsICJFbXB0eUZpZWxkIiwgIkZpZWxkTWFza0ZpZWxkIiwgIlNvdXJjZUNvbnRleHRGaWVsZCIsICJTdHJ1Y3RGaWVsZCIsICJUaW1lc3RhbXBGaWVsZCIsICJUeXBlRmllbGQiLCAiRG91YmxlRmllbGQiLCAiRmxvYXRGaWVsZCIsICJJbnQ2NEZpZWxkIiwgIlVpbnQ2NEZpZWxkIiwgIkludDMyRmllbGQiLCAiVWludDMyRmllbGQiLCAiQm9vbEZpZWxkIiwgIlN0cmluZ0ZpZWxkIiwgIkJ5dGVzRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbmVvZldlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09uZW9mV2VsbEtub3duVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT25lb2ZXZWxsS25vd25UeXBlc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQW55RmllbGQiLCAiQXBpRmllbGQiLCAiRHVyYXRpb25GaWVsZCIsICJFbXB0eUZpZWxkIiwgIkZpZWxkTWFza0ZpZWxkIiwgIlNvdXJjZUNvbnRleHRGaWVsZCIsICJTdHJ1Y3RGaWVsZCIsICJUaW1lc3RhbXBGaWVsZCIsICJUeXBlRmllbGQiLCAiRG91YmxlRmllbGQiLCAiRmxvYXRGaWVsZCIsICJJbnQ2NEZpZWxkIiwgIlVpbnQ2NEZpZWxkIiwgIkludDMyRmllbGQiLCAiVWludDMyRmllbGQiLCAiQm9vbEZpZWxkIiwgIlN0cmluZ0ZpZWxkIiwgIkJ5dGVzRmllbGQiLCAiT25lb2ZGaWVsZCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJBbnlGaWVsZCIsICJBcGlGaWVsZCIsICJEdXJhdGlvbkZpZWxkIiwgIkVtcHR5RmllbGQiLCAiRmllbGRNYXNrRmllbGQiLCAiU291cmNlQ29udGV4dEZpZWxkIiwgIlN0cnVjdEZpZWxkIiwgIlRpbWVzdGFtcEZpZWxkIiwgIlR5cGVGaWVsZCIsICJEb3VibGVGaWVsZCIsICJGbG9hdEZpZWxkIiwgIkludDY0RmllbGQiLCAiVWludDY0RmllbGQiLCAiSW50MzJGaWVsZCIsICJVaW50MzJGaWVsZCIsICJCb29sRmllbGQiLCAiU3RyaW5nRmllbGQiLCAiQnl0ZXNGaWVsZCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0FueUZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0FueUZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfQW55RmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfQXBpRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfQXBpRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19BcGlGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19EdXJhdGlvbkZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0R1cmF0aW9uRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19EdXJhdGlvbkZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0VtcHR5RmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRW1wdHlGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0VtcHR5RmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRmllbGRNYXNrRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRmllbGRNYXNrRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19GaWVsZE1hc2tGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19Tb3VyY2VDb250ZXh0RmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfU291cmNlQ29udGV4dEZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfU291cmNlQ29udGV4dEZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX1N0cnVjdEZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX1N0cnVjdEZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfU3RydWN0RmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfVGltZXN0YW1wRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfVGltZXN0YW1wRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19UaW1lc3RhbXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19UeXBlRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfVHlwZUZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfVHlwZUZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0RvdWJsZUZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0RvdWJsZUZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRG91YmxlRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRmxvYXRGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfRmxvYXRGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0Zsb2F0RmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfSW50NjRGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfSW50NjRGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0ludDY0RmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfVWludDY0RmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX1VpbnQ2NEZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfVWludDY0RmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfSW50MzJGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfSW50MzJGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0ludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfVWludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX1VpbnQzMkZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfVWludDMyRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfQm9vbEZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19Cb29sRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYXBXZWxsS25vd25UeXBlc19Cb29sRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX1N0cmluZ0ZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfU3RyaW5nRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfQnl0ZXNGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFwV2VsbEtub3duVHlwZXNfQnl0ZXNGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hcFdlbGxLbm93blR5cGVzX0J5dGVzRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueVByb3RvLmdldERlc2NyaXB0b3IoKTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuQXBpUHJvdG8uZ2V0RGVzY3JpcHRvcigpOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvblByb3RvLmdldERlc2NyaXB0b3IoKTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuRW1wdHlQcm90by5nZXREZXNjcmlwdG9yKCk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza1Byb3RvLmdldERlc2NyaXB0b3IoKTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dFByb3RvLmdldERlc2NyaXB0b3IoKTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuU3RydWN0UHJvdG8uZ2V0RGVzY3JpcHRvcigpOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBQcm90by5nZXREZXNjcmlwdG9yKCk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlR5cGVQcm90by5nZXREZXNjcmlwdG9yKCk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldyYXBwZXJzUHJvdG8uZ2V0RGVzY3JpcHRvcigpOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEAS/JHoDsoAAA7KAAALwAAAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9wcm90by9CYWROYW1lcy5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2JhZF9tYWNyb3MucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90bzsKCi8qKgogKiA8cHJlPgogKiBKdXN0IGEgY29udGFpbmVyIGZvciBiYWQgbWFjcm8gbmFtZXMuIFNvbWUgb2YgdGhlc2UgZG8gbm90IGZvbGxvdyB0aGUgbm9ybWFsCiAqIG5hbWluZyBjb252ZW50aW9ucywgdGhpcyBpcyBpbnRlbnRpb25hbCwgd2UganVzdCB3YW50IHRvIHRyaWdnZXIgYSBidWlsZAogKiBmYWlsdXJlIGlmIHRoZSBtYWNybyBpcyBsZWZ0IGRlZmluZWQuCiAqIDwvcHJlPgogKgogKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5CYWROYW1lc30KICovCnB1YmxpYyBlbnVtIEJhZE5hbWVzCiAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgLyoqCiAgICogPHByZT4KICAgKiBhdXRvaGVhZGVyIGRlZmluZXMgdGhpcyBpbiBzb21lIGNpcmN1bXN0YW5jZXMuCiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT5QQUNLQUdFID0gMDs8L2NvZGU+CiAgICovCiAgUEFDS0FHRSgwKSwKICAvKioKICAgKiA8cHJlPgogICAqIFRoZSBjb21tZW50IHNheXMgImEgZmV3IGNvbW1vbiBoZWFkZXJzIGRlZmluZSB0aGlzIi4KICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPlBBQ0tFRCA9IDE7PC9jb2RlPgogICAqLwogIFBBQ0tFRCgxKSwKICAvKioKICAgKiA8cHJlPgogICAqIERlZmluZWQgaW4gbWFueSBMaW51eCBzeXN0ZW0gaGVhZGVycy4KICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPmxpbnV4ID0gMjs8L2NvZGU+CiAgICovCiAgbGludXgoMiksCiAgLyoqCiAgICogPHByZT4KICAgKiBUaGlzIGlzIG9mdGVuIGEgbWFjcm8gaW4gYCZsdDttYXRoLmgmZ3Q7YC4KICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPkRPTUFJTiA9IDM7PC9jb2RlPgogICAqLwogIERPTUFJTigzKSwKICAvKioKICAgKiA8cHJlPgogICAqIFRoZXNlIGFyZSBkZWZpbmVkIGluIGJvdGggV2luZG93cyBhbmQgbWFjT1MgaGVhZGVycy4KICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPlRSVUUgPSA0OzwvY29kZT4KICAgKi8KICBUUlVFKDQpLAogIC8qKgogICAqIDxjb2RlPkZBTFNFID0gNTs8L2NvZGU+CiAgICovCiAgRkFMU0UoNSksCiAgLyoqCiAgICogPHByZT4KICAgKiBTb21ldGltZXMgZGVmaW5lZCBpbiBXaW5kb3dzIHN5c3RlbSBoZWFkZXJzLgogICAqIDwvcHJlPgogICAqCiAgICogPGNvZGU+Q1JFQVRFX05FVyA9IDY7PC9jb2RlPgogICAqLwogIENSRUFURV9ORVcoNiksCiAgLyoqCiAgICogPGNvZGU+REVMRVRFID0gNzs8L2NvZGU+CiAgICovCiAgREVMRVRFKDcpLAogIC8qKgogICAqIDxjb2RlPkRPVUJMRV9DTElDSyA9IDg7PC9jb2RlPgogICAqLwogIERPVUJMRV9DTElDSyg4KSwKICAvKioKICAgKiA8Y29kZT5FUlJPUiA9IDk7PC9jb2RlPgogICAqLwogIEVSUk9SKDkpLAogIC8qKgogICAqIDxjb2RlPkVSUk9SX0JVU1kgPSAxMDs8L2NvZGU+CiAgICovCiAgRVJST1JfQlVTWSgxMCksCiAgLyoqCiAgICogPGNvZGU+RVJST1JfSU5TVEFMTF9GQUlMRUQgPSAxMTs8L2NvZGU+CiAgICovCiAgRVJST1JfSU5TVEFMTF9GQUlMRUQoMTEpLAogIC8qKgogICAqIDxjb2RlPkVSUk9SX05PVF9GT1VORCA9IDEyOzwvY29kZT4KICAgKi8KICBFUlJPUl9OT1RfRk9VTkQoMTIpLAogIC8qKgogICAqIDxjb2RlPkdldENsYXNzTmFtZSA9IDEzOzwvY29kZT4KICAgKi8KICBHZXRDbGFzc05hbWUoMTMpLAogIC8qKgogICAqIDxjb2RlPkdldEN1cnJlbnRUaW1lID0gMTQ7PC9jb2RlPgogICAqLwogIEdldEN1cnJlbnRUaW1lKDE0KSwKICAvKioKICAgKiA8Y29kZT5HZXRNZXNzYWdlID0gMTU7PC9jb2RlPgogICAqLwogIEdldE1lc3NhZ2UoMTUpLAogIC8qKgogICAqIDxjb2RlPkdldE9iamVjdCA9IDE2OzwvY29kZT4KICAgKi8KICBHZXRPYmplY3QoMTYpLAogIC8qKgogICAqIDxjb2RlPklHTk9SRSA9IDE3OzwvY29kZT4KICAgKi8KICBJR05PUkUoMTcpLAogIC8qKgogICAqIDxjb2RlPklOID0gMTg7PC9jb2RlPgogICAqLwogIElOKDE4KSwKICAvKioKICAgKiA8Y29kZT5JTlBVVF9LRVlCT0FSRCA9IDE5OzwvY29kZT4KICAgKi8KICBJTlBVVF9LRVlCT0FSRCgxOSksCiAgLyoqCiAgICogPGNvZGU+Tk9fRVJST1IgPSAyMDs8L2NvZGU+CiAgICovCiAgTk9fRVJST1IoMjApLAogIC8qKgogICAqIDxjb2RlPk9VVCA9IDIxOzwvY29kZT4KICAgKi8KICBPVVQoMjEpLAogIC8qKgogICAqIDxjb2RlPk9QVElPTkFMID0gMjI7PC9jb2RlPgogICAqLwogIE9QVElPTkFMKDIyKSwKICAvKioKICAgKiA8Y29kZT5ORUFSID0gMjM7PC9jb2RlPgogICAqLwogIE5FQVIoMjMpLAogIC8qKgogICAqIDxjb2RlPk5PX0RBVEEgPSAyNDs8L2NvZGU+CiAgICovCiAgTk9fREFUQSgyNCksCiAgLyoqCiAgICogPGNvZGU+UkVBU09OX1VOS05PV04gPSAyNTs8L2NvZGU+CiAgICovCiAgUkVBU09OX1VOS05PV04oMjUpLAogIC8qKgogICAqIDxjb2RlPlNFUlZJQ0VfRElTQUJMRUQgPSAyNjs8L2NvZGU+CiAgICovCiAgU0VSVklDRV9ESVNBQkxFRCgyNiksCiAgLyoqCiAgICogPGNvZGU+U0VWRVJJVFlfRVJST1IgPSAyNzs8L2NvZGU+CiAgICovCiAgU0VWRVJJVFlfRVJST1IoMjcpLAogIC8qKgogICAqIDxjb2RlPlNUQVRVU19QRU5ESU5HID0gMjg7PC9jb2RlPgogICAqLwogIFNUQVRVU19QRU5ESU5HKDI4KSwKICAvKioKICAgKiA8Y29kZT5TVFJJQ1QgPSAyOTs8L2NvZGU+CiAgICovCiAgU1RSSUNUKDI5KSwKICAvKioKICAgKiA8cHJlPgogICAqIFNvbWV0aW1lZCBkZWZpbmVkIGluIG1hY09TIHN5c3RlbSBoZWFkZXJzLgogICAqIDwvcHJlPgogICAqCiAgICogPGNvZGU+VFlQRV9CT09MID0gMzA7PC9jb2RlPgogICAqLwogIFRZUEVfQk9PTCgzMCksCiAgLyoqCiAgICogPHByZT4KICAgKiBEZWZpbmVkIGluIG1hY09TLCBXaW5kb3dzLCBhbmQgTGludXggaGVhZGVycy4KICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPkRFQlVHID0gMzE7PC9jb2RlPgogICAqLwogIERFQlVHKDMxKSwKICBVTlJFQ09HTklaRUQoLTEpLAogIDsKCiAgLyoqCiAgICogPHByZT4KICAgKiBhdXRvaGVhZGVyIGRlZmluZXMgdGhpcyBpbiBzb21lIGNpcmN1bXN0YW5jZXMuCiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT5QQUNLQUdFID0gMDs8L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0FHRV9WQUxVRSA9IDA7CiAgLyoqCiAgICogPHByZT4KICAgKiBUaGUgY29tbWVudCBzYXlzICJhIGZldyBjb21tb24gaGVhZGVycyBkZWZpbmUgdGhpcyIuCiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT5QQUNLRUQgPSAxOzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfVkFMVUUgPSAxOwogIC8qKgogICAqIDxwcmU+CiAgICogRGVmaW5lZCBpbiBtYW55IExpbnV4IHN5c3RlbSBoZWFkZXJzLgogICAqIDwvcHJlPgogICAqCiAgICogPGNvZGU+bGludXggPSAyOzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBsaW51eF9WQUxVRSA9IDI7CiAgLyoqCiAgICogPHByZT4KICAgKiBUaGlzIGlzIG9mdGVuIGEgbWFjcm8gaW4gYCZsdDttYXRoLmgmZ3Q7YC4KICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPkRPTUFJTiA9IDM7PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERPTUFJTl9WQUxVRSA9IDM7CiAgLyoqCiAgICogPHByZT4KICAgKiBUaGVzZSBhcmUgZGVmaW5lZCBpbiBib3RoIFdpbmRvd3MgYW5kIG1hY09TIGhlYWRlcnMuCiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT5UUlVFID0gNDs8L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFJVRV9WQUxVRSA9IDQ7CiAgLyoqCiAgICogPGNvZGU+RkFMU0UgPSA1OzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGQUxTRV9WQUxVRSA9IDU7CiAgLyoqCiAgICogPHByZT4KICAgKiBTb21ldGltZXMgZGVmaW5lZCBpbiBXaW5kb3dzIHN5c3RlbSBoZWFkZXJzLgogICAqIDwvcHJlPgogICAqCiAgICogPGNvZGU+Q1JFQVRFX05FVyA9IDY7PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENSRUFURV9ORVdfVkFMVUUgPSA2OwogIC8qKgogICAqIDxjb2RlPkRFTEVURSA9IDc7PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFTEVURV9WQUxVRSA9IDc7CiAgLyoqCiAgICogPGNvZGU+RE9VQkxFX0NMSUNLID0gODs8L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRE9VQkxFX0NMSUNLX1ZBTFVFID0gODsKICAvKioKICAgKiA8Y29kZT5FUlJPUiA9IDk7PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSUk9SX1ZBTFVFID0gOTsKICAvKioKICAgKiA8Y29kZT5FUlJPUl9CVVNZID0gMTA7PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVSUk9SX0JVU1lfVkFMVUUgPSAxMDsKICAvKioKICAgKiA8Y29kZT5FUlJPUl9JTlNUQUxMX0ZBSUxFRCA9IDExOzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUlJPUl9JTlNUQUxMX0ZBSUxFRF9WQUxVRSA9IDExOwogIC8qKgogICAqIDxjb2RlPkVSUk9SX05PVF9GT1VORCA9IDEyOzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFUlJPUl9OT1RfRk9VTkRfVkFMVUUgPSAxMjsKICAvKioKICAgKiA8Y29kZT5HZXRDbGFzc05hbWUgPSAxMzs8L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgR2V0Q2xhc3NOYW1lX1ZBTFVFID0gMTM7CiAgLyoqCiAgICogPGNvZGU+R2V0Q3VycmVudFRpbWUgPSAxNDs8L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgR2V0Q3VycmVudFRpbWVfVkFMVUUgPSAxNDsKICAvKioKICAgKiA8Y29kZT5HZXRNZXNzYWdlID0gMTU7PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEdldE1lc3NhZ2VfVkFMVUUgPSAxNTsKICAvKioKICAgKiA8Y29kZT5HZXRPYmplY3QgPSAxNjs8L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgR2V0T2JqZWN0X1ZBTFVFID0gMTY7CiAgLyoqCiAgICogPGNvZGU+SUdOT1JFID0gMTc7PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElHTk9SRV9WQUxVRSA9IDE3OwogIC8qKgogICAqIDxjb2RlPklOID0gMTg7PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOX1ZBTFVFID0gMTg7CiAgLyoqCiAgICogPGNvZGU+SU5QVVRfS0VZQk9BUkQgPSAxOTs8L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5QVVRfS0VZQk9BUkRfVkFMVUUgPSAxOTsKICAvKioKICAgKiA8Y29kZT5OT19FUlJPUiA9IDIwOzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT19FUlJPUl9WQUxVRSA9IDIwOwogIC8qKgogICAqIDxjb2RlPk9VVCA9IDIxOzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPVVRfVkFMVUUgPSAyMTsKICAvKioKICAgKiA8Y29kZT5PUFRJT05BTCA9IDIyOzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9WQUxVRSA9IDIyOwogIC8qKgogICAqIDxjb2RlPk5FQVIgPSAyMzs8L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkVBUl9WQUxVRSA9IDIzOwogIC8qKgogICAqIDxjb2RlPk5PX0RBVEEgPSAyNDs8L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTk9fREFUQV9WQUxVRSA9IDI0OwogIC8qKgogICAqIDxjb2RlPlJFQVNPTl9VTktOT1dOID0gMjU7PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFQVNPTl9VTktOT1dOX1ZBTFVFID0gMjU7CiAgLyoqCiAgICogPGNvZGU+U0VSVklDRV9ESVNBQkxFRCA9IDI2OzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVJWSUNFX0RJU0FCTEVEX1ZBTFVFID0gMjY7CiAgLyoqCiAgICogPGNvZGU+U0VWRVJJVFlfRVJST1IgPSAyNzs8L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VWRVJJVFlfRVJST1JfVkFMVUUgPSAyNzsKICAvKioKICAgKiA8Y29kZT5TVEFUVVNfUEVORElORyA9IDI4OzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVEFUVVNfUEVORElOR19WQUxVRSA9IDI4OwogIC8qKgogICAqIDxjb2RlPlNUUklDVCA9IDI5OzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJQ1RfVkFMVUUgPSAyOTsKICAvKioKICAgKiA8cHJlPgogICAqIFNvbWV0aW1lZCBkZWZpbmVkIGluIG1hY09TIHN5c3RlbSBoZWFkZXJzLgogICAqIDwvcHJlPgogICAqCiAgICogPGNvZGU+VFlQRV9CT09MID0gMzA7PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfQk9PTF9WQUxVRSA9IDMwOwogIC8qKgogICAqIDxwcmU+CiAgICogRGVmaW5lZCBpbiBtYWNPUywgV2luZG93cywgYW5kIExpbnV4IGhlYWRlcnMuCiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT5ERUJVRyA9IDMxOzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUJVR19WQUxVRSA9IDMxOwoKCiAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBudW1iZXIgb2YgYW4gdW5rbm93biBlbnVtIHZhbHVlLiIpOwogICAgfQogICAgcmV0dXJuIHZhbHVlOwogIH0KCiAgLyoqCiAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAqLwogIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogIHB1YmxpYyBzdGF0aWMgQmFkTmFtZXMgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogIH0KCiAgLyoqCiAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAqLwogIHB1YmxpYyBzdGF0aWMgQmFkTmFtZXMgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgc3dpdGNoICh2YWx1ZSkgewogICAgICBjYXNlIDA6IHJldHVybiBQQUNLQUdFOwogICAgICBjYXNlIDE6IHJldHVybiBQQUNLRUQ7CiAgICAgIGNhc2UgMjogcmV0dXJuIGxpbnV4OwogICAgICBjYXNlIDM6IHJldHVybiBET01BSU47CiAgICAgIGNhc2UgNDogcmV0dXJuIFRSVUU7CiAgICAgIGNhc2UgNTogcmV0dXJuIEZBTFNFOwogICAgICBjYXNlIDY6IHJldHVybiBDUkVBVEVfTkVXOwogICAgICBjYXNlIDc6IHJldHVybiBERUxFVEU7CiAgICAgIGNhc2UgODogcmV0dXJuIERPVUJMRV9DTElDSzsKICAgICAgY2FzZSA5OiByZXR1cm4gRVJST1I7CiAgICAgIGNhc2UgMTA6IHJldHVybiBFUlJPUl9CVVNZOwogICAgICBjYXNlIDExOiByZXR1cm4gRVJST1JfSU5TVEFMTF9GQUlMRUQ7CiAgICAgIGNhc2UgMTI6IHJldHVybiBFUlJPUl9OT1RfRk9VTkQ7CiAgICAgIGNhc2UgMTM6IHJldHVybiBHZXRDbGFzc05hbWU7CiAgICAgIGNhc2UgMTQ6IHJldHVybiBHZXRDdXJyZW50VGltZTsKICAgICAgY2FzZSAxNTogcmV0dXJuIEdldE1lc3NhZ2U7CiAgICAgIGNhc2UgMTY6IHJldHVybiBHZXRPYmplY3Q7CiAgICAgIGNhc2UgMTc6IHJldHVybiBJR05PUkU7CiAgICAgIGNhc2UgMTg6IHJldHVybiBJTjsKICAgICAgY2FzZSAxOTogcmV0dXJuIElOUFVUX0tFWUJPQVJEOwogICAgICBjYXNlIDIwOiByZXR1cm4gTk9fRVJST1I7CiAgICAgIGNhc2UgMjE6IHJldHVybiBPVVQ7CiAgICAgIGNhc2UgMjI6IHJldHVybiBPUFRJT05BTDsKICAgICAgY2FzZSAyMzogcmV0dXJuIE5FQVI7CiAgICAgIGNhc2UgMjQ6IHJldHVybiBOT19EQVRBOwogICAgICBjYXNlIDI1OiByZXR1cm4gUkVBU09OX1VOS05PV047CiAgICAgIGNhc2UgMjY6IHJldHVybiBTRVJWSUNFX0RJU0FCTEVEOwogICAgICBjYXNlIDI3OiByZXR1cm4gU0VWRVJJVFlfRVJST1I7CiAgICAgIGNhc2UgMjg6IHJldHVybiBTVEFUVVNfUEVORElORzsKICAgICAgY2FzZSAyOTogcmV0dXJuIFNUUklDVDsKICAgICAgY2FzZSAzMDogcmV0dXJuIFRZUEVfQk9PTDsKICAgICAgY2FzZSAzMTogcmV0dXJuIERFQlVHOwogICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgIH0KICB9CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxCYWROYW1lcz4KICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogIH0KICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICBCYWROYW1lcz4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8QmFkTmFtZXM+KCkgewogICAgICAgICAgcHVibGljIEJhZE5hbWVzIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgcmV0dXJuIEJhZE5hbWVzLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgfQogICAgICAgIH07CgogIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAogICAgICAgICAgIkNhbid0IGdldCB0aGUgZGVzY3JpcHRvciBvZiBhbiB1bnJlY29nbml6ZWQgZW51bSB2YWx1ZS4iKTsKICAgIH0KICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgfQogIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICB9CiAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlVuaXR0ZXN0UHJvdG8zQmFkTWFjcm9zLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMik7CiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBCYWROYW1lc1tdIFZBTFVFUyA9IHZhbHVlcygpOwoKICBwdWJsaWMgc3RhdGljIEJhZE5hbWVzIHZhbHVlT2YoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgfQogICAgaWYgKGRlc2MuZ2V0SW5kZXgoKSA9PSAtMSkgewogICAgICByZXR1cm4gVU5SRUNPR05JWkVEOwogICAgfQogICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogIH0KCiAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogIHByaXZhdGUgQmFkTmFtZXMoaW50IHZhbHVlKSB7CiAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5CYWROYW1lcykKfQoKUEsDBAoAAAAAAAAAIQBpbsdmxAsAAMQLAAAqAAAAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3Byb3RvL0dJRC5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2JhZF9tYWNyb3MucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90bzsKCi8qKgogKiA8cHJlPgogKiBUaGlzIGdlbmVyYXRlcyBgR0lEX01BWGAsIHdoaWNoIGlzIGEgbWFjcm8gaW4gc29tZSBjaXJjdW1zdGFuY2VzLgogKiA8L3ByZT4KICoKICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuR0lEfQogKi8KcHVibGljIGVudW0gR0lECiAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgLyoqCiAgICogPGNvZGU+R0lEX1VOVVNFRCA9IDA7PC9jb2RlPgogICAqLwogIEdJRF9VTlVTRUQoMCksCiAgVU5SRUNPR05JWkVEKC0xKSwKICA7CgogIC8qKgogICAqIDxjb2RlPkdJRF9VTlVTRUQgPSAwOzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBHSURfVU5VU0VEX1ZBTFVFID0gMDsKCgogIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgIkNhbid0IGdldCB0aGUgbnVtYmVyIG9mIGFuIHVua25vd24gZW51bSB2YWx1ZS4iKTsKICAgIH0KICAgIHJldHVybiB2YWx1ZTsKICB9CgogIC8qKgogICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBwdWJsaWMgc3RhdGljIEdJRCB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgfQoKICAvKioKICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICovCiAgcHVibGljIHN0YXRpYyBHSUQgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgc3dpdGNoICh2YWx1ZSkgewogICAgICBjYXNlIDA6IHJldHVybiBHSURfVU5VU0VEOwogICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgIH0KICB9CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxHSUQ+CiAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgR0lEPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxHSUQ+KCkgewogICAgICAgICAgcHVibGljIEdJRCBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgIHJldHVybiBHSUQuZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICB9CiAgICAgICAgfTsKCiAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oCiAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBkZXNjcmlwdG9yIG9mIGFuIHVucmVjb2duaXplZCBlbnVtIHZhbHVlLiIpOwogICAgfQogICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICB9CiAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogIH0KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVW5pdHRlc3RQcm90bzNCYWRNYWNyb3MuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIEdJRFtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICBwdWJsaWMgc3RhdGljIEdJRCB2YWx1ZU9mKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgIH0KICAgIGlmIChkZXNjLmdldEluZGV4KCkgPT0gLTEpIHsKICAgICAgcmV0dXJuIFVOUkVDT0dOSVpFRDsKICAgIH0KICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICB9CgogIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICBwcml2YXRlIEdJRChpbnQgdmFsdWUpIHsKICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkdJRCkKfQoKUEsDBAoAAAAAAAAAIQBqbymh+j4AAPo+AAA/AAAAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3Byb3RvL1Byb3RvM09wdGlvbmFsRXh0ZW5zaW9ucy5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX29wdGlvbmFsLnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG87CgovKioKICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zfQogKi8KcHVibGljIGZpbmFsIGNsYXNzIFByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucyBleHRlbmRzCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucykKICAgIFByb3RvM09wdGlvbmFsRXh0ZW5zaW9uc09yQnVpbGRlciB7CnByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogIC8vIFVzZSBQcm90bzNPcHRpb25hbEV4dGVuc2lvbnMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICBwcml2YXRlIFByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgIHN1cGVyKGJ1aWxkZXIpOwogIH0KICBwcml2YXRlIFByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucygpIHsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgcmV0dXJuIG5ldyBQcm90bzNPcHRpb25hbEV4dGVuc2lvbnMoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlVuaXR0ZXN0UHJvdG8zT3B0aW9uYWwuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Byb3RvM09wdGlvbmFsRXh0ZW5zaW9uc19kZXNjcmlwdG9yOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlVuaXR0ZXN0UHJvdG8zT3B0aW9uYWwuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Byb3RvM09wdGlvbmFsRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucy5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucy5CdWlsZGVyLmNsYXNzKTsKICB9CgogIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgc2l6ZSA9IDA7CiAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgIHJldHVybiBzaXplOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zKSkgewogICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICB9CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zIG90aGVyID0gKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnMpIG9iajsKCiAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICB9CiAgICBpbnQgaGFzaCA9IDQxOwogICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgcmV0dXJuIGhhc2g7CiAgfQoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgIGJ5dGVbXSBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogIH0KICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zIHByb3RvdHlwZSkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgfQogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgcmV0dXJuIGJ1aWxkZXI7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlByb3RvM09wdGlvbmFsRXh0ZW5zaW9uc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnNPckJ1aWxkZXIgewogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlVuaXR0ZXN0UHJvdG8zT3B0aW9uYWwuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Byb3RvM09wdGlvbmFsRXh0ZW5zaW9uc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Vbml0dGVzdFByb3RvM09wdGlvbmFsLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zLm5ld0J1aWxkZXIoKQogICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgIH0KCiAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgc3VwZXIocGFyZW50KTsKCiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlVuaXR0ZXN0UHJvdG8zT3B0aW9uYWwuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Byb3RvM09wdGlvbmFsRXh0ZW5zaW9uc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zIGJ1aWxkKCkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICB9CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnMgYnVpbGRQYXJ0aWFsKCkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zKHRoaXMpOwogICAgICBvbkJ1aWx0KCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zKSB7CiAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucylvdGhlcik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zIG90aGVyKSB7CiAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgfQogICAgICB0cnkgewogICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfSAvLyBmaW5hbGx5CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICB9CgoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucykKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnMpCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucyBERUZBVUxUX0lOU1RBTkNFOwogIHN0YXRpYyB7CiAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnMoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucz4KICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zPigpIHsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBQcm90bzNPcHRpb25hbEV4dGVuc2lvbnMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICB0cnkgewogICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICB9CiAgfTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxQcm90bzNPcHRpb25hbEV4dGVuc2lvbnM+IHBhcnNlcigpIHsKICAgIHJldHVybiBQQVJTRVI7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgIHJldHVybiBQQVJTRVI7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVhUX05PX09QVElPTkFMX0ZJRUxEX05VTUJFUiA9IDM1NTg4NjcyODsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5NZXNzYWdlT3B0aW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IGV4dE5vT3B0aW9uYWwgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgMCwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFWFRfV0lUSF9PUFRJT05BTF9GSUVMRF9OVU1CRVIgPSAzNTU4ODY3Mjk7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuTWVzc2FnZU9wdGlvbnMsCiAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiBleHRXaXRoT3B0aW9uYWwgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgMSwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKfQoKUEsDBAoAAAAAAAAAIQBR/x8JjgEAAI4BAABIAAAAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3Byb3RvL1Byb3RvM09wdGlvbmFsRXh0ZW5zaW9uc09yQnVpbGRlci5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX29wdGlvbmFsLnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG87CgpwdWJsaWMgaW50ZXJmYWNlIFByb3RvM09wdGlvbmFsRXh0ZW5zaW9uc09yQnVpbGRlciBleHRlbmRzCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zKQogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKfQpQSwMECgAAAAAAAAAhAAs4UTgHvwEAB78BADkAAABjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvcHJvdG8vVGVzdFByb3RvM09wdGlvbmFsLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcm90bzNfb3B0aW9uYWwucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90bzsKCi8qKgogKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWx9CiAqLwpwdWJsaWMgZmluYWwgY2xhc3MgVGVzdFByb3RvM09wdGlvbmFsIGV4dGVuZHMKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsKQogICAgVGVzdFByb3RvM09wdGlvbmFsT3JCdWlsZGVyIHsKcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgLy8gVXNlIFRlc3RQcm90bzNPcHRpb25hbC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogIHByaXZhdGUgVGVzdFByb3RvM09wdGlvbmFsKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgc3VwZXIoYnVpbGRlcik7CiAgfQogIHByaXZhdGUgVGVzdFByb3RvM09wdGlvbmFsKCkgewogICAgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIG9wdGlvbmFsQ29yZF8gPSAiIjsKICAgIG9wdGlvbmFsTmVzdGVkRW51bV8gPSAwOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICByZXR1cm4gbmV3IFRlc3RQcm90bzNPcHRpb25hbCgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVW5pdHRlc3RQcm90bzNPcHRpb25hbC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsX2Rlc2NyaXB0b3I7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVW5pdHRlc3RQcm90bzNPcHRpb25hbC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLkJ1aWxkZXIuY2xhc3MpOwogIH0KCiAgLyoqCiAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZEVudW19CiAgICovCiAgcHVibGljIGVudW0gTmVzdGVkRW51bQogICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAvKioKICAgICAqIDxjb2RlPlVOU1BFQ0lGSUVEID0gMDs8L2NvZGU+CiAgICAgKi8KICAgIFVOU1BFQ0lGSUVEKDApLAogICAgLyoqCiAgICAgKiA8Y29kZT5GT08gPSAxOzwvY29kZT4KICAgICAqLwogICAgRk9PKDEpLAogICAgLyoqCiAgICAgKiA8Y29kZT5CQVIgPSAyOzwvY29kZT4KICAgICAqLwogICAgQkFSKDIpLAogICAgLyoqCiAgICAgKiA8Y29kZT5CQVogPSAzOzwvY29kZT4KICAgICAqLwogICAgQkFaKDMpLAogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogSW50ZW50aW9uYWxseSBuZWdhdGl2ZS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPk5FRyA9IC0xOzwvY29kZT4KICAgICAqLwogICAgTkVHKC0xKSwKICAgIFVOUkVDT0dOSVpFRCgtMSksCiAgICA7CgogICAgLyoqCiAgICAgKiA8Y29kZT5VTlNQRUNJRklFRCA9IDA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlNQRUNJRklFRF9WQUxVRSA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPkZPTyA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fVkFMVUUgPSAxOwogICAgLyoqCiAgICAgKiA8Y29kZT5CQVIgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSX1ZBTFVFID0gMjsKICAgIC8qKgogICAgICogPGNvZGU+QkFaID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBWl9WQUxVRSA9IDM7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBJbnRlbnRpb25hbGx5IG5lZ2F0aXZlLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+TkVHID0gLTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBORUdfVkFMVUUgPSAtMTsKCgogICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBudW1iZXIgb2YgYW4gdW5rbm93biBlbnVtIHZhbHVlLiIpOwogICAgICB9CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICBjYXNlIDA6IHJldHVybiBVTlNQRUNJRklFRDsKICAgICAgICBjYXNlIDE6IHJldHVybiBGT087CiAgICAgICAgY2FzZSAyOiByZXR1cm4gQkFSOwogICAgICAgIGNhc2UgMzogcmV0dXJuIEJBWjsKICAgICAgICBjYXNlIC0xOiByZXR1cm4gTkVHOwogICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE5lc3RlZEVudW0+CiAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgIE5lc3RlZEVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgIHB1YmxpYyBOZXN0ZWRFbnVtIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gTmVzdGVkRW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKCiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgZGVzY3JpcHRvciBvZiBhbiB1bnJlY29nbml6ZWQgZW51bSB2YWx1ZS4iKTsKICAgICAgfQogICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgfQogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTmVzdGVkRW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSB2YWx1ZU9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICB9CiAgICAgIGlmIChkZXNjLmdldEluZGV4KCkgPT0gLTEpIHsKICAgICAgICByZXR1cm4gVU5SRUNPR05JWkVEOwogICAgICB9CiAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICBwcml2YXRlIE5lc3RlZEVudW0oaW50IHZhbHVlKSB7CiAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkRW51bSkKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0JiKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJiLgogICAgICovCiAgICBpbnQgZ2V0QmIoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBOZXN0ZWRNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlKQogICAgICBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBOZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBOZXN0ZWRNZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE5lc3RlZE1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVW5pdHRlc3RQcm90bzNPcHRpb25hbC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVW5pdHRlc3RQcm90bzNPcHRpb25hbC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkJfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IGJiXyA9IDA7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNCYigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAqIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCiAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRCYigpIHsKICAgICAgcmV0dXJuIGJiXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGJiXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgYmJfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UpIG9iajsKCiAgICAgIGlmIChoYXNCYigpICE9IG90aGVyLmhhc0JiKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0JiKCkpIHsKICAgICAgICBpZiAoZ2V0QmIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRCYigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzQmIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEJCX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCYigpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVW5pdHRlc3RQcm90bzNPcHRpb25hbC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlVuaXR0ZXN0UHJvdG8zT3B0aW9uYWwuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzNPcHRpb25hbF9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBiYl8gPSAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVW5pdHRlc3RQcm90bzNPcHRpb25hbC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmJiXyA9IGJiXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNCYigpKSB7CiAgICAgICAgICBzZXRCYihvdGhlci5nZXRCYigpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBiYl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGJiXyA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNCYigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAqIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCiAgICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYmIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0QmIoKSB7CiAgICAgICAgcmV0dXJuIGJiXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICogVGhpcyBmaWxlIG5lZWRzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIHRvIHRlc3QgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJiIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmIoaW50IHZhbHVlKSB7CgogICAgICAgIGJiXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICogVGhpcyBmaWxlIG5lZWRzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIHRvIHRlc3QgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJiKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBiYl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkTWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE5lc3RlZE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDE7CiAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMl8gPSAwOwogIC8qKgogICAqIDxwcmU+CiAgICogU2luZ3VsYXIKICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMigpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBTaW5ndWxhcgogICAqIDwvcHJlPgogICAqCiAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIoKSB7CiAgICByZXR1cm4gb3B0aW9uYWxJbnQzMl87CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQ2NF9GSUVMRF9OVU1CRVIgPSAyOwogIHByaXZhdGUgbG9uZyBvcHRpb25hbEludDY0XyA9IDBMOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDY0IGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQ2NCgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjQgPSAyOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDY0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbEludDY0KCkgewogICAgcmV0dXJuIG9wdGlvbmFsSW50NjRfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDM7CiAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzJfID0gMDsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzIoKSB7CiAgICByZXR1cm4gb3B0aW9uYWxVaW50MzJfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfVUlOVDY0X0ZJRUxEX05VTUJFUiA9IDQ7CiAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsVWludDY0XyA9IDBMOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDY0IGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50NjQoKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQ2NC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxVaW50NjQoKSB7CiAgICByZXR1cm4gb3B0aW9uYWxVaW50NjRfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0lOVDMyX0ZJRUxEX05VTUJFUiA9IDU7CiAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTaW50MzJfID0gMDsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2ludDMyKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTaW50MzIuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxTaW50MzIoKSB7CiAgICByZXR1cm4gb3B0aW9uYWxTaW50MzJfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0lOVDY0X0ZJRUxEX05VTUJFUiA9IDY7CiAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsU2ludDY0XyA9IDBMOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBvcHRpb25hbF9zaW50NjQgPSA2OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2ludDY0IGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTaW50NjQoKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBvcHRpb25hbF9zaW50NjQgPSA2OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQ2NC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxTaW50NjQoKSB7CiAgICByZXR1cm4gb3B0aW9uYWxTaW50NjRfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA3OwogIHByaXZhdGUgaW50IG9wdGlvbmFsRml4ZWQzMl8gPSAwOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGaXhlZDMyIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxGaXhlZDMyKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZpeGVkMzIuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxGaXhlZDMyKCkgewogICAgcmV0dXJuIG9wdGlvbmFsRml4ZWQzMl87CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9GSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDg7CiAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsRml4ZWQ2NF8gPSAwTDsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRml4ZWQ2NCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsRml4ZWQ2NCgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBvcHRpb25hbF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGaXhlZDY0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbEZpeGVkNjQoKSB7CiAgICByZXR1cm4gb3B0aW9uYWxGaXhlZDY0XzsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NGSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDk7CiAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZml4ZWQzMl8gPSAwOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNmaXhlZDMyIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTZml4ZWQzMigpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDMyLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldE9wdGlvbmFsU2ZpeGVkMzIoKSB7CiAgICByZXR1cm4gb3B0aW9uYWxTZml4ZWQzMl87CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSAxMDsKICBwcml2YXRlIGxvbmcgb3B0aW9uYWxTZml4ZWQ2NF8gPSAwTDsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2ZpeGVkNjQgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFNmaXhlZDY0KCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDY0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbFNmaXhlZDY0KCkgewogICAgcmV0dXJuIG9wdGlvbmFsU2ZpeGVkNjRfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRkxPQVRfRklFTERfTlVNQkVSID0gMTE7CiAgcHJpdmF0ZSBmbG9hdCBvcHRpb25hbEZsb2F0XyA9IDBGOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsRmxvYXQoKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRmxvYXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBmbG9hdCBnZXRPcHRpb25hbEZsb2F0KCkgewogICAgcmV0dXJuIG9wdGlvbmFsRmxvYXRfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRE9VQkxFX0ZJRUxEX05VTUJFUiA9IDEyOwogIHByaXZhdGUgZG91YmxlIG9wdGlvbmFsRG91YmxlXyA9IDBEOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBvcHRpb25hbF9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbERvdWJsZSBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsRG91YmxlKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgb3B0aW9uYWxfZG91YmxlID0gMTI7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRG91YmxlLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgZG91YmxlIGdldE9wdGlvbmFsRG91YmxlKCkgewogICAgcmV0dXJuIG9wdGlvbmFsRG91YmxlXzsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0JPT0xfRklFTERfTlVNQkVSID0gMTM7CiAgcHJpdmF0ZSBib29sZWFuIG9wdGlvbmFsQm9vbF8gPSBmYWxzZTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEJvb2wgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEJvb2woKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJvb2wuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGdldE9wdGlvbmFsQm9vbCgpIHsKICAgIHJldHVybiBvcHRpb25hbEJvb2xfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDE0OwogIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFN0cmluZ18gPSAiIjsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTdHJpbmcgZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFN0cmluZygpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmcoKSB7CiAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nXzsKICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgfSBlbHNlIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICBvcHRpb25hbFN0cmluZ18gPSBzOwogICAgICByZXR1cm4gczsKICAgIH0KICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdCeXRlcygpIHsKICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdfOwogICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IGI7CiAgICAgIHJldHVybiBiOwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgIH0KICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0JZVEVTX0ZJRUxEX05VTUJFUiA9IDE1OwogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIG9wdGlvbmFsQnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMTU7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQnl0ZXMoKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMTU7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQnl0ZXMuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T3B0aW9uYWxCeXRlcygpIHsKICAgIHJldHVybiBvcHRpb25hbEJ5dGVzXzsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0NPUkRfRklFTERfTlVNQkVSID0gMTY7CiAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsQ29yZF8gPSAiIjsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfY29yZCA9IDE2IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQ29yZCBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQ29yZCgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAxNiBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgb3B0aW9uYWxDb3JkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbENvcmQoKSB7CiAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsQ29yZF87CiAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgIH0gZWxzZSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgb3B0aW9uYWxDb3JkXyA9IHM7CiAgICAgIHJldHVybiBzOwogICAgfQogIH0KICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfY29yZCA9IDE2IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxDb3JkLgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgIGdldE9wdGlvbmFsQ29yZEJ5dGVzKCkgewogICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbENvcmRfOwogICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgIG9wdGlvbmFsQ29yZF8gPSBiOwogICAgICByZXR1cm4gYjsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICB9CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAxODsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZS4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTEFaWV9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAxOTsKICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBsYXp5TmVzdGVkTWVzc2FnZV87CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIGxhenlfbmVzdGVkX21lc3NhZ2UgPSAxOSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxhenlOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzTGF6eU5lc3RlZE1lc3NhZ2UoKSB7CiAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgfQogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBsYXp5X25lc3RlZF9tZXNzYWdlID0gMTkgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgbGF6eU5lc3RlZE1lc3NhZ2UuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UgZ2V0TGF6eU5lc3RlZE1lc3NhZ2UoKSB7CiAgICByZXR1cm4gbGF6eU5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBsYXp5TmVzdGVkTWVzc2FnZV87CiAgfQogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBsYXp5X25lc3RlZF9tZXNzYWdlID0gMTkgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0TGF6eU5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICByZXR1cm4gbGF6eU5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBsYXp5TmVzdGVkTWVzc2FnZV87CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVIgPSAyMTsKICBwcml2YXRlIGludCBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE5lc3RlZEVudW0gZmllbGQgaXMgc2V0LgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxOZXN0ZWRFbnVtKCkgewogICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApOwogIH0KICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbE5lc3RlZEVudW0uCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCkgewogICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkRW51bV87CiAgfQogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZEVudW0uCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkRW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZEVudW0uZm9yTnVtYmVyKG9wdGlvbmFsTmVzdGVkRW51bV8pOwogICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJTkdVTEFSX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDIyOwogIHByaXZhdGUgaW50IHNpbmd1bGFySW50MzJfID0gMDsKICAvKioKICAgKiA8cHJlPgogICAqIEFkZCBzb21lIG5vbi1vcHRpb25hbCBmaWVsZHMgdG8gdmVyaWZ5IHdlIGNhbiBtaXggdGhlbS4KICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPmludDMyIHNpbmd1bGFyX2ludDMyID0gMjI7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHNpbmd1bGFySW50MzIuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgZ2V0U2luZ3VsYXJJbnQzMigpIHsKICAgIHJldHVybiBzaW5ndWxhckludDMyXzsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJTkdVTEFSX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDIzOwogIHByaXZhdGUgbG9uZyBzaW5ndWxhckludDY0XyA9IDBMOwogIC8qKgogICAqIDxjb2RlPmludDY0IHNpbmd1bGFyX2ludDY0ID0gMjM7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIHNpbmd1bGFySW50NjQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBsb25nIGdldFNpbmd1bGFySW50NjQoKSB7CiAgICByZXR1cm4gc2luZ3VsYXJJbnQ2NF87CiAgfQoKICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBvcHRpb25hbEludDMyXyk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgb3V0cHV0LndyaXRlSW50NjQoMiwgb3B0aW9uYWxJbnQ2NF8pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZVVJbnQzMigzLCBvcHRpb25hbFVpbnQzMl8pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCg0LCBvcHRpb25hbFVpbnQ2NF8pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZVNJbnQzMig1LCBvcHRpb25hbFNpbnQzMl8pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZVNJbnQ2NCg2LCBvcHRpb25hbFNpbnQ2NF8pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZUZpeGVkMzIoNywgb3B0aW9uYWxGaXhlZDMyXyk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NCg4LCBvcHRpb25hbEZpeGVkNjRfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVTRml4ZWQzMig5LCBvcHRpb25hbFNmaXhlZDMyXyk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjQoMTAsIG9wdGlvbmFsU2ZpeGVkNjRfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVGbG9hdCgxMSwgb3B0aW9uYWxGbG9hdF8pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZURvdWJsZSgxMiwgb3B0aW9uYWxEb3VibGVfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVCb29sKDEzLCBvcHRpb25hbEJvb2xfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDE0LCBvcHRpb25hbFN0cmluZ18pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDE1LCBvcHRpb25hbEJ5dGVzXyk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxNiwgb3B0aW9uYWxDb3JkXyk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxOCwgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTksIGdldExhenlOZXN0ZWRNZXNzYWdlKCkpOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZUVudW0oMjEsIG9wdGlvbmFsTmVzdGVkRW51bV8pOwogICAgfQogICAgaWYgKHNpbmd1bGFySW50MzJfICE9IDApIHsKICAgICAgb3V0cHV0LndyaXRlSW50MzIoMjIsIHNpbmd1bGFySW50MzJfKTsKICAgIH0KICAgIGlmIChzaW5ndWxhckludDY0XyAhPSAwTCkgewogICAgICBvdXRwdXQud3JpdGVJbnQ2NCgyMywgc2luZ3VsYXJJbnQ2NF8pOwogICAgfQogICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgc2l6ZSA9IDA7CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgb3B0aW9uYWxJbnQzMl8pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlSW50NjRTaXplKDIsIG9wdGlvbmFsSW50NjRfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoMywgb3B0aW9uYWxVaW50MzJfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemUoNCwgb3B0aW9uYWxVaW50NjRfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemUoNSwgb3B0aW9uYWxTaW50MzJfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemUoNiwgb3B0aW9uYWxTaW50NjRfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZUZpeGVkMzJTaXplKDcsIG9wdGlvbmFsRml4ZWQzMl8pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlRml4ZWQ2NFNpemUoOCwgb3B0aW9uYWxGaXhlZDY0Xyk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVTRml4ZWQzMlNpemUoOSwgb3B0aW9uYWxTZml4ZWQzMl8pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlU0ZpeGVkNjRTaXplKDEwLCBvcHRpb25hbFNmaXhlZDY0Xyk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVGbG9hdFNpemUoMTEsIG9wdGlvbmFsRmxvYXRfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZURvdWJsZVNpemUoMTIsIG9wdGlvbmFsRG91YmxlXyk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSgxMywgb3B0aW9uYWxCb29sXyk7CiAgICB9CiAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxNCwgb3B0aW9uYWxTdHJpbmdfKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgxNSwgb3B0aW9uYWxCeXRlc18pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMTYsIG9wdGlvbmFsQ29yZF8pOwogICAgfQogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgsIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5LCBnZXRMYXp5TmVzdGVkTWVzc2FnZSgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZUVudW1TaXplKDIxLCBvcHRpb25hbE5lc3RlZEVudW1fKTsKICAgIH0KICAgIGlmIChzaW5ndWxhckludDMyXyAhPSAwKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIyLCBzaW5ndWxhckludDMyXyk7CiAgICB9CiAgICBpZiAoc2luZ3VsYXJJbnQ2NF8gIT0gMEwpIHsKICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemUoMjMsIHNpbmd1bGFySW50NjRfKTsKICAgIH0KICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgcmV0dXJuIHNpemU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwpKSB7CiAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgIH0KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwgb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbCkgb2JqOwoKICAgIGlmIChoYXNPcHRpb25hbEludDMyKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMigpKSB7CiAgICAgIGlmIChnZXRPcHRpb25hbEludDMyKCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsSW50NjQoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDY0KCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNPcHRpb25hbEludDY0KCkpIHsKICAgICAgaWYgKGdldE9wdGlvbmFsSW50NjQoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIoKSAhPSBvdGhlci5oYXNPcHRpb25hbFVpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIoKSkgewogICAgICBpZiAoZ2V0T3B0aW9uYWxVaW50MzIoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxVaW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsVWludDY0KCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVaW50NjQoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc09wdGlvbmFsVWludDY0KCkpIHsKICAgICAgaWYgKGdldE9wdGlvbmFsVWludDY0KCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDY0KCkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmIChoYXNPcHRpb25hbFNpbnQzMigpICE9IG90aGVyLmhhc09wdGlvbmFsU2ludDMyKCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNPcHRpb25hbFNpbnQzMigpKSB7CiAgICAgIGlmIChnZXRPcHRpb25hbFNpbnQzMigpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFNpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzT3B0aW9uYWxTaW50NjQoKSAhPSBvdGhlci5oYXNPcHRpb25hbFNpbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzT3B0aW9uYWxTaW50NjQoKSkgewogICAgICBpZiAoZ2V0T3B0aW9uYWxTaW50NjQoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxTaW50NjQoKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsRml4ZWQzMigpICE9IG90aGVyLmhhc09wdGlvbmFsRml4ZWQzMigpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzT3B0aW9uYWxGaXhlZDMyKCkpIHsKICAgICAgaWYgKGdldE9wdGlvbmFsRml4ZWQzMigpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEZpeGVkMzIoKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsRml4ZWQ2NCgpICE9IG90aGVyLmhhc09wdGlvbmFsRml4ZWQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzT3B0aW9uYWxGaXhlZDY0KCkpIHsKICAgICAgaWYgKGdldE9wdGlvbmFsRml4ZWQ2NCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEZpeGVkNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsU2ZpeGVkMzIoKSAhPSBvdGhlci5oYXNPcHRpb25hbFNmaXhlZDMyKCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNPcHRpb25hbFNmaXhlZDMyKCkpIHsKICAgICAgaWYgKGdldE9wdGlvbmFsU2ZpeGVkMzIoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxTZml4ZWQzMigpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzT3B0aW9uYWxTZml4ZWQ2NCgpICE9IG90aGVyLmhhc09wdGlvbmFsU2ZpeGVkNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc09wdGlvbmFsU2ZpeGVkNjQoKSkgewogICAgICBpZiAoZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFNmaXhlZDY0KCkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmIChoYXNPcHRpb25hbEZsb2F0KCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxGbG9hdCgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzT3B0aW9uYWxGbG9hdCgpKSB7CiAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0T3B0aW9uYWxGbG9hdCgpKQogICAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICAgIG90aGVyLmdldE9wdGlvbmFsRmxvYXQoKSkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmIChoYXNPcHRpb25hbERvdWJsZSgpICE9IG90aGVyLmhhc09wdGlvbmFsRG91YmxlKCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNPcHRpb25hbERvdWJsZSgpKSB7CiAgICAgIGlmIChqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0T3B0aW9uYWxEb3VibGUoKSkKICAgICAgICAgICE9IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cygKICAgICAgICAgICAgICBvdGhlci5nZXRPcHRpb25hbERvdWJsZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsQm9vbCgpICE9IG90aGVyLmhhc09wdGlvbmFsQm9vbCgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzT3B0aW9uYWxCb29sKCkpIHsKICAgICAgaWYgKGdldE9wdGlvbmFsQm9vbCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEJvb2woKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsU3RyaW5nKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxTdHJpbmcoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc09wdGlvbmFsU3RyaW5nKCkpIHsKICAgICAgaWYgKCFnZXRPcHRpb25hbFN0cmluZygpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsU3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzT3B0aW9uYWxCeXRlcygpICE9IG90aGVyLmhhc09wdGlvbmFsQnl0ZXMoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc09wdGlvbmFsQnl0ZXMoKSkgewogICAgICBpZiAoIWdldE9wdGlvbmFsQnl0ZXMoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEJ5dGVzKCkpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoaGFzT3B0aW9uYWxDb3JkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxDb3JkKCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNPcHRpb25hbENvcmQoKSkgewogICAgICBpZiAoIWdldE9wdGlvbmFsQ29yZCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsQ29yZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHsKICAgICAgaWYgKCFnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmIChoYXNMYXp5TmVzdGVkTWVzc2FnZSgpICE9IG90aGVyLmhhc0xhenlOZXN0ZWRNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgIGlmIChoYXNMYXp5TmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgIGlmICghZ2V0TGF6eU5lc3RlZE1lc3NhZ2UoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRMYXp5TmVzdGVkTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkRW51bSgpICE9IG90aGVyLmhhc09wdGlvbmFsTmVzdGVkRW51bSgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRFbnVtKCkpIHsKICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkRW51bV8gIT0gb3RoZXIub3B0aW9uYWxOZXN0ZWRFbnVtXykgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKGdldFNpbmd1bGFySW50MzIoKQogICAgICAgICE9IG90aGVyLmdldFNpbmd1bGFySW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGdldFNpbmd1bGFySW50NjQoKQogICAgICAgICE9IG90aGVyLmdldFNpbmd1bGFySW50NjQoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgfQogICAgaW50IGhhc2ggPSA0MTsKICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgaWYgKGhhc09wdGlvbmFsSW50MzIoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzIoKTsKICAgIH0KICAgIGlmIChoYXNPcHRpb25hbEludDY0KCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0T3B0aW9uYWxJbnQ2NCgpKTsKICAgIH0KICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMigpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsVWludDMyKCk7CiAgICB9CiAgICBpZiAoaGFzT3B0aW9uYWxVaW50NjQoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9VSU5UNjRfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0T3B0aW9uYWxVaW50NjQoKSk7CiAgICB9CiAgICBpZiAoaGFzT3B0aW9uYWxTaW50MzIoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TSU5UMzJfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFNpbnQzMigpOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsU2ludDY0KCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgIGdldE9wdGlvbmFsU2ludDY0KCkpOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsRml4ZWQzMigpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEZpeGVkMzIoKTsKICAgIH0KICAgIGlmIChoYXNPcHRpb25hbEZpeGVkNjQoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgIGdldE9wdGlvbmFsRml4ZWQ2NCgpKTsKICAgIH0KICAgIGlmIChoYXNPcHRpb25hbFNmaXhlZDMyKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFNmaXhlZDMyKCk7CiAgICB9CiAgICBpZiAoaGFzT3B0aW9uYWxTZml4ZWQ2NCgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1NGSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgIGdldE9wdGlvbmFsU2ZpeGVkNjQoKSk7CiAgICB9CiAgICBpZiAoaGFzT3B0aW9uYWxGbG9hdCgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0ZMT0FUX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgZ2V0T3B0aW9uYWxGbG9hdCgpKTsKICAgIH0KICAgIGlmIChoYXNPcHRpb25hbERvdWJsZSgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0T3B0aW9uYWxEb3VibGUoKSkpOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsQm9vbCgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0JPT0xfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKAogICAgICAgICAgZ2V0T3B0aW9uYWxCb29sKCkpOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsU3RyaW5nKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsQnl0ZXMoKSkgewogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9CWVRFU19GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsQ29yZCgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0NPUkRfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbENvcmQoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgIH0KICAgIGlmIChoYXNMYXp5TmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIExBWllfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRMYXp5TmVzdGVkTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRFbnVtKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBvcHRpb25hbE5lc3RlZEVudW1fOwogICAgfQogICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU0lOR1VMQVJfSU5UMzJfRklFTERfTlVNQkVSOwogICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U2luZ3VsYXJJbnQzMigpOwogICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU0lOR1VMQVJfSU5UNjRfRklFTERfTlVNQkVSOwogICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICBnZXRTaW5ndWxhckludDY0KCkpOwogICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgIHJldHVybiBoYXNoOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsIHBhcnNlRnJvbSgKICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbCBwYXJzZUZyb20oCiAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbCBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbCBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwgcGFyc2VGcm9tKAogICAgICBieXRlW10gZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwgcGFyc2VGcm9tKAogICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbCBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICB9CiAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbCBwcm90b3R5cGUpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogIH0KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgIHJldHVybiBidWlsZGVyOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWx9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsT3JCdWlsZGVyIHsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Vbml0dGVzdFByb3RvM09wdGlvbmFsLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVW5pdHRlc3RQcm90bzNPcHRpb25hbC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5uZXdCdWlsZGVyKCkKICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgfQoKICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBzdXBlcihwYXJlbnQpOwogICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICB9CiAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICBnZXRMYXp5TmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgIG9wdGlvbmFsSW50MzJfID0gMDsKICAgICAgb3B0aW9uYWxJbnQ2NF8gPSAwTDsKICAgICAgb3B0aW9uYWxVaW50MzJfID0gMDsKICAgICAgb3B0aW9uYWxVaW50NjRfID0gMEw7CiAgICAgIG9wdGlvbmFsU2ludDMyXyA9IDA7CiAgICAgIG9wdGlvbmFsU2ludDY0XyA9IDBMOwogICAgICBvcHRpb25hbEZpeGVkMzJfID0gMDsKICAgICAgb3B0aW9uYWxGaXhlZDY0XyA9IDBMOwogICAgICBvcHRpb25hbFNmaXhlZDMyXyA9IDA7CiAgICAgIG9wdGlvbmFsU2ZpeGVkNjRfID0gMEw7CiAgICAgIG9wdGlvbmFsRmxvYXRfID0gMEY7CiAgICAgIG9wdGlvbmFsRG91YmxlXyA9IDBEOwogICAgICBvcHRpb25hbEJvb2xfID0gZmFsc2U7CiAgICAgIG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgICBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgb3B0aW9uYWxDb3JkXyA9ICIiOwogICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIGxhenlOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgIGlmIChsYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBsYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBsYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgICAgc2luZ3VsYXJJbnQzMl8gPSAwOwogICAgICBzaW5ndWxhckludDY0XyA9IDBMOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVW5pdHRlc3RQcm90bzNPcHRpb25hbC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwgYnVpbGQoKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbCBidWlsZFBhcnRpYWwoKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwgcmVzdWx0ID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwodGhpcyk7CiAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgIG9uQnVpbHQoKTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsIHJlc3VsdCkgewogICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyXyA9IG9wdGlvbmFsSW50MzJfOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5vcHRpb25hbEludDY0XyA9IG9wdGlvbmFsSW50NjRfOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMl8gPSBvcHRpb25hbFVpbnQzMl87CiAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVWludDY0XyA9IG9wdGlvbmFsVWludDY0XzsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQub3B0aW9uYWxTaW50MzJfID0gb3B0aW9uYWxTaW50MzJfOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5vcHRpb25hbFNpbnQ2NF8gPSBvcHRpb25hbFNpbnQ2NF87CiAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICB9CiAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRml4ZWQzMl8gPSBvcHRpb25hbEZpeGVkMzJfOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5vcHRpb25hbEZpeGVkNjRfID0gb3B0aW9uYWxGaXhlZDY0XzsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQub3B0aW9uYWxTZml4ZWQzMl8gPSBvcHRpb25hbFNmaXhlZDMyXzsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQub3B0aW9uYWxTZml4ZWQ2NF8gPSBvcHRpb25hbFNmaXhlZDY0XzsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQub3B0aW9uYWxGbG9hdF8gPSBvcHRpb25hbEZsb2F0XzsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQub3B0aW9uYWxEb3VibGVfID0gb3B0aW9uYWxEb3VibGVfOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5vcHRpb25hbEJvb2xfID0gb3B0aW9uYWxCb29sXzsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQub3B0aW9uYWxTdHJpbmdfID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5vcHRpb25hbEJ5dGVzXyA9IG9wdGlvbmFsQnl0ZXNfOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5vcHRpb25hbENvcmRfID0gb3B0aW9uYWxDb3JkXzsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQub3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgPyBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfCiAgICAgICAgICAgIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQubGF6eU5lc3RlZE1lc3NhZ2VfID0gbGF6eU5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgID8gbGF6eU5lc3RlZE1lc3NhZ2VfCiAgICAgICAgICAgIDogbGF6eU5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5vcHRpb25hbE5lc3RlZEVudW1fID0gb3B0aW9uYWxOZXN0ZWRFbnVtXzsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICByZXN1bHQuc2luZ3VsYXJJbnQzMl8gPSBzaW5ndWxhckludDMyXzsKICAgICAgfQogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5zaW5ndWxhckludDY0XyA9IHNpbmd1bGFySW50NjRfOwogICAgICB9CiAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsKSB7CiAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbClvdGhlcik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsIG90aGVyKSB7CiAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50MzIoKSkgewogICAgICAgIHNldE9wdGlvbmFsSW50MzIob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMigpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQ2NCgpKSB7CiAgICAgICAgc2V0T3B0aW9uYWxJbnQ2NChvdGhlci5nZXRPcHRpb25hbEludDY0KCkpOwogICAgICB9CiAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFVpbnQzMigpKSB7CiAgICAgICAgc2V0T3B0aW9uYWxVaW50MzIob3RoZXIuZ2V0T3B0aW9uYWxVaW50MzIoKSk7CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsVWludDY0KCkpIHsKICAgICAgICBzZXRPcHRpb25hbFVpbnQ2NChvdGhlci5nZXRPcHRpb25hbFVpbnQ2NCgpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxTaW50MzIoKSkgewogICAgICAgIHNldE9wdGlvbmFsU2ludDMyKG90aGVyLmdldE9wdGlvbmFsU2ludDMyKCkpOwogICAgICB9CiAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFNpbnQ2NCgpKSB7CiAgICAgICAgc2V0T3B0aW9uYWxTaW50NjQob3RoZXIuZ2V0T3B0aW9uYWxTaW50NjQoKSk7CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsRml4ZWQzMigpKSB7CiAgICAgICAgc2V0T3B0aW9uYWxGaXhlZDMyKG90aGVyLmdldE9wdGlvbmFsRml4ZWQzMigpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxGaXhlZDY0KCkpIHsKICAgICAgICBzZXRPcHRpb25hbEZpeGVkNjQob3RoZXIuZ2V0T3B0aW9uYWxGaXhlZDY0KCkpOwogICAgICB9CiAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFNmaXhlZDMyKCkpIHsKICAgICAgICBzZXRPcHRpb25hbFNmaXhlZDMyKG90aGVyLmdldE9wdGlvbmFsU2ZpeGVkMzIoKSk7CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsU2ZpeGVkNjQoKSkgewogICAgICAgIHNldE9wdGlvbmFsU2ZpeGVkNjQob3RoZXIuZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxGbG9hdCgpKSB7CiAgICAgICAgc2V0T3B0aW9uYWxGbG9hdChvdGhlci5nZXRPcHRpb25hbEZsb2F0KCkpOwogICAgICB9CiAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbERvdWJsZSgpKSB7CiAgICAgICAgc2V0T3B0aW9uYWxEb3VibGUob3RoZXIuZ2V0T3B0aW9uYWxEb3VibGUoKSk7CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsQm9vbCgpKSB7CiAgICAgICAgc2V0T3B0aW9uYWxCb29sKG90aGVyLmdldE9wdGlvbmFsQm9vbCgpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxTdHJpbmcoKSkgewogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IG90aGVyLm9wdGlvbmFsU3RyaW5nXzsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsQnl0ZXMoKSkgewogICAgICAgIHNldE9wdGlvbmFsQnl0ZXMob3RoZXIuZ2V0T3B0aW9uYWxCeXRlcygpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxDb3JkKCkpIHsKICAgICAgICBvcHRpb25hbENvcmRfID0gb3RoZXIub3B0aW9uYWxDb3JkXzsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0KICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgbWVyZ2VPcHRpb25hbE5lc3RlZE1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmIChvdGhlci5oYXNMYXp5TmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgbWVyZ2VMYXp5TmVzdGVkTWVzc2FnZShvdGhlci5nZXRMYXp5TmVzdGVkTWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxOZXN0ZWRFbnVtKCkpIHsKICAgICAgICBzZXRPcHRpb25hbE5lc3RlZEVudW0ob3RoZXIuZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtKCkpOwogICAgICB9CiAgICAgIGlmIChvdGhlci5nZXRTaW5ndWxhckludDMyKCkgIT0gMCkgewogICAgICAgIHNldFNpbmd1bGFySW50MzIob3RoZXIuZ2V0U2luZ3VsYXJJbnQzMigpKTsKICAgICAgfQogICAgICBpZiAob3RoZXIuZ2V0U2luZ3VsYXJJbnQ2NCgpICE9IDBMKSB7CiAgICAgICAgc2V0U2luZ3VsYXJJbnQ2NChvdGhlci5nZXRTaW5ndWxhckludDY0KCkpOwogICAgICB9CiAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgdHJ5IHsKICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgIG9wdGlvbmFsSW50MzJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgb3B0aW9uYWxJbnQ2NF8gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgb3B0aW9uYWxVaW50MzJfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgIGNhc2UgMzI6IHsKICAgICAgICAgICAgICBvcHRpb25hbFVpbnQ2NF8gPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMzIKICAgICAgICAgICAgY2FzZSA0MDogewogICAgICAgICAgICAgIG9wdGlvbmFsU2ludDMyXyA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSA0MAogICAgICAgICAgICBjYXNlIDQ4OiB7CiAgICAgICAgICAgICAgb3B0aW9uYWxTaW50NjRfID0gaW5wdXQucmVhZFNJbnQ2NCgpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDQ4CiAgICAgICAgICAgIGNhc2UgNjE6IHsKICAgICAgICAgICAgICBvcHRpb25hbEZpeGVkMzJfID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSA2MQogICAgICAgICAgICBjYXNlIDY1OiB7CiAgICAgICAgICAgICAgb3B0aW9uYWxGaXhlZDY0XyA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNjUKICAgICAgICAgICAgY2FzZSA3NzogewogICAgICAgICAgICAgIG9wdGlvbmFsU2ZpeGVkMzJfID0gaW5wdXQucmVhZFNGaXhlZDMyKCk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgNzcKICAgICAgICAgICAgY2FzZSA4MTogewogICAgICAgICAgICAgIG9wdGlvbmFsU2ZpeGVkNjRfID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgODEKICAgICAgICAgICAgY2FzZSA5MzogewogICAgICAgICAgICAgIG9wdGlvbmFsRmxvYXRfID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgOTMKICAgICAgICAgICAgY2FzZSA5NzogewogICAgICAgICAgICAgIG9wdGlvbmFsRG91YmxlXyA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSA5NwogICAgICAgICAgICBjYXNlIDEwNDogewogICAgICAgICAgICAgIG9wdGlvbmFsQm9vbF8gPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDEwNAogICAgICAgICAgICBjYXNlIDExNDogewogICAgICAgICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDExNAogICAgICAgICAgICBjYXNlIDEyMjogewogICAgICAgICAgICAgIG9wdGlvbmFsQnl0ZXNfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMTIyCiAgICAgICAgICAgIGNhc2UgMTMwOiB7CiAgICAgICAgICAgICAgb3B0aW9uYWxDb3JkXyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDEzMAogICAgICAgICAgICBjYXNlIDE0NjogewogICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxNDYKICAgICAgICAgICAgY2FzZSAxNTQ6IHsKICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgZ2V0TGF6eU5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxNTQKICAgICAgICAgICAgY2FzZSAxNjg6IHsKICAgICAgICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxNjgKICAgICAgICAgICAgY2FzZSAxNzY6IHsKICAgICAgICAgICAgICBzaW5ndWxhckludDMyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDE3NgogICAgICAgICAgICBjYXNlIDE4NDogewogICAgICAgICAgICAgIHNpbmd1bGFySW50NjRfID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8vIGNhc2UgMTg0CiAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgIH0gZmluYWxseSB7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gLy8gZmluYWxseQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMl8gOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogU2luZ3VsYXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBTaW5ndWxhcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogU2luZ3VsYXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzIgdG8gc2V0LgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyKGludCB2YWx1ZSkgewoKICAgICAgb3B0aW9uYWxJbnQzMl8gPSB2YWx1ZTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBTaW5ndWxhcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEludDMyKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgIG9wdGlvbmFsSW50MzJfID0gMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbEludDY0XyA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50NjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDY0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbEludDY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50NjQgdG8gc2V0LgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgIG9wdGlvbmFsSW50NjRfID0gdmFsdWU7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50NjQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgb3B0aW9uYWxJbnQ2NF8gPSAwTDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyXyA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzIgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFVpbnQzMiB0byBzZXQuCiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVWludDMyKGludCB2YWx1ZSkgewoKICAgICAgb3B0aW9uYWxVaW50MzJfID0gdmFsdWU7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50MzIoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgb3B0aW9uYWxVaW50MzJfID0gMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFVpbnQ2NF8gOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50NjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IG9wdGlvbmFsX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsVWludDY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxVaW50NjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsVWludDY0IHRvIHNldC4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgb3B0aW9uYWxVaW50NjRfID0gdmFsdWU7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50NjQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgb3B0aW9uYWxVaW50NjRfID0gMEw7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBwcml2YXRlIGludCBvcHRpb25hbFNpbnQzMl8gOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2ludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTaW50MzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxTaW50MzIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFNpbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBvcHRpb25hbF9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTaW50MzIgdG8gc2V0LgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFNpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgIG9wdGlvbmFsU2ludDMyXyA9IHZhbHVlOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU2ludDMyKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgIG9wdGlvbmFsU2ludDMyXyA9IDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxTaW50NjRfIDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNpbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2ludDY0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBvcHRpb25hbF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbFNpbnQ2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsU2ludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFNpbnQ2NCB0byBzZXQuCiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU2ludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgIG9wdGlvbmFsU2ludDY0XyA9IHZhbHVlOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU2ludDY0KCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgIG9wdGlvbmFsU2ludDY0XyA9IDBMOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxGaXhlZDMyXyA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEZpeGVkMzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZpeGVkMzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZpeGVkMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxGaXhlZDMyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGaXhlZDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRml4ZWQzMiB0byBzZXQuCiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgIG9wdGlvbmFsRml4ZWQzMl8gPSB2YWx1ZTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRml4ZWQzMigpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICBvcHRpb25hbEZpeGVkMzJfID0gMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbEZpeGVkNjRfIDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBvcHRpb25hbF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRml4ZWQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsRml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxGaXhlZDY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGaXhlZDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBvcHRpb25hbF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRml4ZWQ2NCB0byBzZXQuCiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICBvcHRpb25hbEZpeGVkNjRfID0gdmFsdWU7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEZpeGVkNjQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgb3B0aW9uYWxGaXhlZDY0XyA9IDBMOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZml4ZWQzMl8gOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBvcHRpb25hbF9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNmaXhlZDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTZml4ZWQzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBvcHRpb25hbF9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFNmaXhlZDMyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxTZml4ZWQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU2ZpeGVkMzIgdG8gc2V0LgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFNmaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgb3B0aW9uYWxTZml4ZWQzMl8gPSB2YWx1ZTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTZml4ZWQzMigpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICBvcHRpb25hbFNmaXhlZDMyXyA9IDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxTZml4ZWQ2NF8gOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTZml4ZWQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2ZpeGVkNjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbFNmaXhlZDY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxTZml4ZWQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFNmaXhlZDY0IHRvIHNldC4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTZml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICBvcHRpb25hbFNmaXhlZDY0XyA9IHZhbHVlOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTZml4ZWQ2NCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICBvcHRpb25hbFNmaXhlZDY0XyA9IDBMOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgcHJpdmF0ZSBmbG9hdCBvcHRpb25hbEZsb2F0XyA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxGbG9hdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBvcHRpb25hbF9mbG9hdCA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRPcHRpb25hbEZsb2F0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGbG9hdF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEZsb2F0IHRvIHNldC4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgb3B0aW9uYWxGbG9hdF8gPSB2YWx1ZTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRmxvYXQoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgb3B0aW9uYWxGbG9hdF8gPSAwRjsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIHByaXZhdGUgZG91YmxlIG9wdGlvbmFsRG91YmxlXyA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBvcHRpb25hbF9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRG91YmxlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxEb3VibGUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRG91YmxlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldE9wdGlvbmFsRG91YmxlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxEb3VibGVfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgb3B0aW9uYWxfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbERvdWJsZSB0byBzZXQuCiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRG91YmxlKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgb3B0aW9uYWxEb3VibGVfID0gdmFsdWU7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgb3B0aW9uYWxfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRG91YmxlKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgIG9wdGlvbmFsRG91YmxlXyA9IDBEOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgcHJpdmF0ZSBib29sZWFuIG9wdGlvbmFsQm9vbF8gOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQm9vbCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQm9vbCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJvb2wuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldE9wdGlvbmFsQm9vbCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsQm9vbF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxCb29sIHRvIHNldC4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxCb29sKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgIG9wdGlvbmFsQm9vbF8gPSB2YWx1ZTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEJvb2woKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgb3B0aW9uYWxCb29sXyA9IGZhbHNlOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU3RyaW5nKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBzOwogICAgICAgIHJldHVybiBzOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFN0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTdHJpbmcgdG8gc2V0LgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHZhbHVlOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFN0cmluZygpIHsKICAgICAgb3B0aW9uYWxTdHJpbmdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0T3B0aW9uYWxTdHJpbmcoKTsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZyB0byBzZXQuCiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU3RyaW5nQnl0ZXMoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHZhbHVlOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEJ5dGVzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxCeXRlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEJ5dGVzIHRvIHNldC4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxCeXRlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgb3B0aW9uYWxCeXRlc18gPSB2YWx1ZTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsQnl0ZXMoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA0MDAwKTsKICAgICAgb3B0aW9uYWxCeXRlc18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbEJ5dGVzKCk7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxDb3JkXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfY29yZCA9IDE2IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxDb3JkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxDb3JkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkID0gMTYgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxDb3JkLgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbENvcmQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxDb3JkXzsKICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgb3B0aW9uYWxDb3JkXyA9IHM7CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAxNiBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxDb3JkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxDb3JkQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxDb3JkXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBvcHRpb25hbENvcmRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkID0gMTYgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbENvcmQgdG8gc2V0LgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbENvcmQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICBvcHRpb25hbENvcmRfID0gdmFsdWU7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfY29yZCA9IDE2IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbENvcmQoKSB7CiAgICAgIG9wdGlvbmFsQ29yZF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbENvcmQoKTsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDgwMDApOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkID0gMTYgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxDb3JkIHRvIHNldC4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxDb3JkQnl0ZXMoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgIG9wdGlvbmFsQ29yZF8gPSB2YWx1ZTsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkgJiYKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBsYXp5TmVzdGVkTWVzc2FnZV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiBsYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UgbGF6eV9uZXN0ZWRfbWVzc2FnZSA9IDE5IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsYXp5TmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc0xhenlOZXN0ZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBsYXp5X25lc3RlZF9tZXNzYWdlID0gMTkgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsYXp5TmVzdGVkTWVzc2FnZS4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBnZXRMYXp5TmVzdGVkTWVzc2FnZSgpIHsKICAgICAgaWYgKGxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBsYXp5TmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGxhenlOZXN0ZWRNZXNzYWdlXzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gbGF6eU5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIGxhenlfbmVzdGVkX21lc3NhZ2UgPSAxOSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0TGF6eU5lc3RlZE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgIGlmIChsYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGxhenlOZXN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICB9IGVsc2UgewogICAgICAgIGxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBsYXp5X25lc3RlZF9tZXNzYWdlID0gMTkgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldExhenlOZXN0ZWRNZXNzYWdlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICBpZiAobGF6eU5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgbGF6eU5lc3RlZE1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgbGF6eU5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgfQogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIGxhenlfbmVzdGVkX21lc3NhZ2UgPSAxOSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VMYXp5TmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgaWYgKGxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSAmJgogICAgICAgICAgbGF6eU5lc3RlZE1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgIGxhenlOZXN0ZWRNZXNzYWdlXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldExhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGxhenlOZXN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBsYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKGxhenlOZXN0ZWRNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UgbGF6eV9uZXN0ZWRfbWVzc2FnZSA9IDE5IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxhenlOZXN0ZWRNZXNzYWdlKCkgewogICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgIGxhenlOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgIGlmIChsYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBsYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICBsYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBsYXp5X25lc3RlZF9tZXNzYWdlID0gMTkgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRMYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBnZXRMYXp5TmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIGxhenlfbmVzdGVkX21lc3NhZ2UgPSAxOSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRMYXp5TmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgaWYgKGxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiBsYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gbGF6eU5lc3RlZE1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBsYXp5TmVzdGVkTWVzc2FnZV87CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlIGxhenlfbmVzdGVkX21lc3NhZ2UgPSAxOSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0TGF6eU5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgIGlmIChsYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBsYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBnZXRMYXp5TmVzdGVkTWVzc2FnZSgpLAogICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgbGF6eU5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gbGF6eU5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGludCBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE5lc3RlZEVudW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRFbnVtXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIG9wdGlvbmFsTmVzdGVkRW51bSB0byBzZXQuCiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKGludCB2YWx1ZSkgewogICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gdmFsdWU7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZEVudW0gZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtKCkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtLmZvck51bWJlcihvcHRpb25hbE5lc3RlZEVudW1fKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbE5lc3RlZEVudW0gdG8gc2V0LgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbE5lc3RlZEVudW0oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwNDAwMDApOwogICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQoKICAgIHByaXZhdGUgaW50IHNpbmd1bGFySW50MzJfIDsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFkZCBzb21lIG5vbi1vcHRpb25hbCBmaWVsZHMgdG8gdmVyaWZ5IHdlIGNhbiBtaXggdGhlbS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPmludDMyIHNpbmd1bGFyX2ludDMyID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc2luZ3VsYXJJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTaW5ndWxhckludDMyKCkgewogICAgICByZXR1cm4gc2luZ3VsYXJJbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBZGQgc29tZSBub24tb3B0aW9uYWwgZmllbGRzIHRvIHZlcmlmeSB3ZSBjYW4gbWl4IHRoZW0uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5pbnQzMiBzaW5ndWxhcl9pbnQzMiA9IDIyOzwvY29kZT4KICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc2luZ3VsYXJJbnQzMiB0byBzZXQuCiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldFNpbmd1bGFySW50MzIoaW50IHZhbHVlKSB7CgogICAgICBzaW5ndWxhckludDMyXyA9IHZhbHVlOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFkZCBzb21lIG5vbi1vcHRpb25hbCBmaWVsZHMgdG8gdmVyaWZ5IHdlIGNhbiBtaXggdGhlbS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPmludDMyIHNpbmd1bGFyX2ludDMyID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhclNpbmd1bGFySW50MzIoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDgwMDAwKTsKICAgICAgc2luZ3VsYXJJbnQzMl8gPSAwOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgcHJpdmF0ZSBsb25nIHNpbmd1bGFySW50NjRfIDsKICAgIC8qKgogICAgICogPGNvZGU+aW50NjQgc2luZ3VsYXJfaW50NjQgPSAyMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzaW5ndWxhckludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRTaW5ndWxhckludDY0KCkgewogICAgICByZXR1cm4gc2luZ3VsYXJJbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmludDY0IHNpbmd1bGFyX2ludDY0ID0gMjM7PC9jb2RlPgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBzaW5ndWxhckludDY0IHRvIHNldC4KICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0U2luZ3VsYXJJbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICBzaW5ndWxhckludDY0XyA9IHZhbHVlOwogICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+aW50NjQgc2luZ3VsYXJfaW50NjQgPSAyMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU2luZ3VsYXJJbnQ2NCgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAxMDAwMDApOwogICAgICBzaW5ndWxhckludDY0XyA9IDBMOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgIH0KCgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsKQogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbCkKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsIERFRkFVTFRfSU5TVEFOQ0U7CiAgc3RhdGljIHsKICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbCgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFByb3RvM09wdGlvbmFsPgogICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0UHJvdG8zT3B0aW9uYWw+KCkgewogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIFRlc3RQcm90bzNPcHRpb25hbCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgIHRyeSB7CiAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgfQogICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgIH0KICB9OwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQcm90bzNPcHRpb25hbD4gcGFyc2VyKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFByb3RvM09wdGlvbmFsPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgfQoKfQoKUEsDBAoAAAAAAAAAIQCmHIl7y9AAAMvQAABAAAAAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3Byb3RvL1Rlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3Byb3RvM19vcHRpb25hbC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvOwoKLyoqCiAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2V9CiAqLwpwdWJsaWMgZmluYWwgY2xhc3MgVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSBleHRlbmRzCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UpCiAgICBUZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlT3JCdWlsZGVyIHsKcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgLy8gVXNlIFRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICBwcml2YXRlIFRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICBzdXBlcihidWlsZGVyKTsKICB9CiAgcHJpdmF0ZSBUZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlKCkgewogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICByZXR1cm4gbmV3IFRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UoKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlVuaXR0ZXN0UHJvdG8zT3B0aW9uYWwuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2VfZGVzY3JpcHRvcjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Vbml0dGVzdFByb3RvM09wdGlvbmFsLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIHMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgcyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFNCeXRlcygpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBOZXN0ZWRNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSkKICAgICAgTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBOZXN0ZWRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgc18gPSAiIjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBOZXN0ZWRNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlVuaXR0ZXN0UHJvdG8zT3B0aW9uYWwuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Vbml0dGVzdFByb3RvM09wdGlvbmFsLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLmNsYXNzLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHNfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBzID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgc18gPSBzOwogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBzID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICghY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuaXNTdHJpbmdFbXB0eShzXykpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEsIHNfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KHNfKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMSwgc18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2Ugb3RoZXIgPSAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKCFnZXRTKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVW5pdHRlc3RQcm90bzNPcHRpb25hbC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Vbml0dGVzdFByb3RvM09wdGlvbmFsLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5jbGFzcywgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHNfID0gIiI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Vbml0dGVzdFByb3RvM09wdGlvbmFsLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zXyA9IHNfOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoIW90aGVyLmdldFMoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNfID0gb3RoZXIuc187CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgc18gPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc18gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBzID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBzXyA9IHM7CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgcyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igcy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBzID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIHMgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTKCkgewogICAgICAgIHNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0UygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIHMgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkTWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE5lc3RlZE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAxOwogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBuZXN0ZWRNZXNzYWdlXzsKICAvKioKICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG5lc3RlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gaGFzTmVzdGVkTWVzc2FnZSgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBuZXN0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG5lc3RlZE1lc3NhZ2UuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIGdldE5lc3RlZE1lc3NhZ2UoKSB7CiAgICByZXR1cm4gbmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBuZXN0ZWRNZXNzYWdlXzsKICB9CiAgLyoqCiAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBuZXN0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAqLwogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgcmV0dXJuIG5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbmVzdGVkTWVzc2FnZV87CiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAyOwogIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICB9CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZS4KICAgKi8KICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogIH0KICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICovCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICB9CgogIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgZ2V0TmVzdGVkTWVzc2FnZSgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIsIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKICAgIH0KICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgIHNpemUgPSAwOwogICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0TmVzdGVkTWVzc2FnZSgpKTsKICAgIH0KICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIsIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKICAgIH0KICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgcmV0dXJuIHNpemU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlKSkgewogICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICB9CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSBvdGhlciA9IChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSkgb2JqOwoKICAgIGlmIChoYXNOZXN0ZWRNZXNzYWdlKCkgIT0gb3RoZXIuaGFzTmVzdGVkTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoaGFzTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgIGlmICghZ2V0TmVzdGVkTWVzc2FnZSgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE5lc3RlZE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmIChoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSAhPSBvdGhlci5oYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgIGlmICghZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICB9CiAgICBpbnQgaGFzaCA9IDQxOwogICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICBpZiAoaGFzTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE5FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TmVzdGVkTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICB9CiAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgfQogICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgIHJldHVybiBoYXNoOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICBieXRlW10gZGF0YSwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICB9CiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgfQogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICB9CiAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICB9CiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICByZXR1cm4gYnVpbGRlcjsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZU9yQnVpbGRlciB7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVW5pdHRlc3RQcm90bzNPcHRpb25hbC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Vbml0dGVzdFByb3RvM09wdGlvbmFsLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuY2xhc3MsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8vIENvbnN0cnVjdCB1c2luZyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgfQoKICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBzdXBlcihwYXJlbnQpOwogICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICB9CiAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICBnZXROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICBzdXBlci5jbGVhcigpOwogICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgbmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICBpZiAobmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBuZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgIG5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVW5pdHRlc3RQcm90bzNPcHRpb25hbC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlIGJ1aWxkKCkgewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgfQogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlIHJlc3VsdCA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSh0aGlzKTsKICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgb25CdWlsdCgpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlIHJlc3VsdCkgewogICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHJlc3VsdC5uZXN0ZWRNZXNzYWdlXyA9IG5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgID8gbmVzdGVkTWVzc2FnZV8KICAgICAgICAgICAgOiBuZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIH0KICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICByZXN1bHQub3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgPyBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfCiAgICAgICAgICAgIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlKSB7CiAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2Upb3RoZXIpOwogICAgICB9IGVsc2UgewogICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgaWYgKG90aGVyID09IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgaWYgKG90aGVyLmhhc05lc3RlZE1lc3NhZ2UoKSkgewogICAgICAgIG1lcmdlTmVzdGVkTWVzc2FnZShvdGhlci5nZXROZXN0ZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkgewogICAgICAgIG1lcmdlT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKICAgICAgfQogICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHRyeSB7CiAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgIH0gZmluYWxseSB7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIH0gLy8gZmluYWxseQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG5lc3RlZE1lc3NhZ2VfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gbmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG5lc3RlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXN0ZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG5lc3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIGdldE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIGlmIChuZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBuZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG5lc3RlZE1lc3NhZ2VfOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBuZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0TmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgIGlmIChuZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgbmVzdGVkTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgfSBlbHNlIHsKICAgICAgICBuZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0TmVzdGVkTWVzc2FnZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgIGlmIChuZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIG5lc3RlZE1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgbmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICB9CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG5lc3RlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgIGlmIChuZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgbmVzdGVkTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgbmVzdGVkTWVzc2FnZV8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgZ2V0TmVzdGVkTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBuZXN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBuZXN0ZWRNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgfQogICAgICBpZiAobmVzdGVkTWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBuZXN0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgbmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICBpZiAobmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBuZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgIG5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgIH0KICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG5lc3RlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0TmVzdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBnZXROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG5lc3RlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIGlmIChuZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiBuZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBuZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG5lc3RlZE1lc3NhZ2VfOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0TmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgaWYgKG5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgbmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBnZXROZXN0ZWRNZXNzYWdlKCksCiAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICBuZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIG5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgIH0KCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgIH0KICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICBvbkNoYW5nZWQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbE5lc3RlZE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSAmJgogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfICE9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICB9CiAgICAgIG9uQ2hhbmdlZCgpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgb25DaGFuZ2VkKCk7CiAgICAgIHJldHVybiBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgfQoKCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlKQogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UpCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICBzdGF0aWMgewogICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSgpOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2U+CiAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2U+KCkgewogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIFRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICB0cnkgewogICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICB9CiAgfTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICByZXR1cm4gUEFSU0VSOwogIH0KCiAgQGphdmEubGFuZy5PdmVycmlkZQogIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgcmV0dXJuIFBBUlNFUjsKICB9CgogIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogIH0KCn0KClBLAwQKAAAAAAAAACEAMJVlgwgHAAAIBwAASQAAAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9wcm90by9UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlT3JCdWlsZGVyLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcm90bzNfb3B0aW9uYWwucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90bzsKCnB1YmxpYyBpbnRlcmZhY2UgVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZSkKICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogIC8qKgogICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzTmVzdGVkTWVzc2FnZSgpOwogIC8qKgogICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBuZXN0ZWRNZXNzYWdlLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgZ2V0TmVzdGVkTWVzc2FnZSgpOwogIC8qKgogICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKTsKfQpQSwMECgAAAAAAAAAhAGm1ft+nHgAApx4AAEIAAABjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvcHJvdG8vVGVzdFByb3RvM09wdGlvbmFsT3JCdWlsZGVyLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcm90bzNfb3B0aW9uYWwucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90bzsKCnB1YmxpYyBpbnRlcmZhY2UgVGVzdFByb3RvM09wdGlvbmFsT3JCdWlsZGVyIGV4dGVuZHMKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwpCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAvKioKICAgKiA8cHJlPgogICAqIFNpbmd1bGFyCiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyKCk7CiAgLyoqCiAgICogPHByZT4KICAgKiBTaW5ndWxhcgogICAqIDwvcHJlPgogICAqCiAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyLgogICAqLwogIGludCBnZXRPcHRpb25hbEludDMyKCk7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDY0IGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc09wdGlvbmFsSW50NjQoKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NCA9IDI7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjQuCiAgICovCiAgbG9uZyBnZXRPcHRpb25hbEludDY0KCk7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzIgPSAzOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc09wdGlvbmFsVWludDMyKCk7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMiA9IDM7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyLgogICAqLwogIGludCBnZXRPcHRpb25hbFVpbnQzMigpOwoKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQ2NCgpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQ2NC4KICAgKi8KICBsb25nIGdldE9wdGlvbmFsVWludDY0KCk7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBvcHRpb25hbF9zaW50MzIgPSA1OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2ludDMyIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc09wdGlvbmFsU2ludDMyKCk7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ludDMyLgogICAqLwogIGludCBnZXRPcHRpb25hbFNpbnQzMigpOwoKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgb3B0aW9uYWxfc2ludDY0ID0gNjs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNpbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNPcHRpb25hbFNpbnQ2NCgpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBvcHRpb25hbF9zaW50NjQgPSA2OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQ2NC4KICAgKi8KICBsb25nIGdldE9wdGlvbmFsU2ludDY0KCk7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGaXhlZDMyIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc09wdGlvbmFsRml4ZWQzMigpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQzMi4KICAgKi8KICBpbnQgZ2V0T3B0aW9uYWxGaXhlZDMyKCk7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGaXhlZDY0IGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc09wdGlvbmFsRml4ZWQ2NCgpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQ2NC4KICAgKi8KICBsb25nIGdldE9wdGlvbmFsRml4ZWQ2NCgpOwoKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBvcHRpb25hbF9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTZml4ZWQzMiBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNPcHRpb25hbFNmaXhlZDMyKCk7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDMyLgogICAqLwogIGludCBnZXRPcHRpb25hbFNmaXhlZDMyKCk7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTZml4ZWQ2NCBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNPcHRpb25hbFNmaXhlZDY0KCk7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZml4ZWQ2NC4KICAgKi8KICBsb25nIGdldE9wdGlvbmFsU2ZpeGVkNjQoKTsKCiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgb3B0aW9uYWxfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEZsb2F0IGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc09wdGlvbmFsRmxvYXQoKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBvcHRpb25hbF9mbG9hdCA9IDExOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZsb2F0LgogICAqLwogIGZsb2F0IGdldE9wdGlvbmFsRmxvYXQoKTsKCiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRG91YmxlIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc09wdGlvbmFsRG91YmxlKCk7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbERvdWJsZS4KICAgKi8KICBkb3VibGUgZ2V0T3B0aW9uYWxEb3VibGUoKTsKCiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBvcHRpb25hbF9ib29sID0gMTM7PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxCb29sIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc09wdGlvbmFsQm9vbCgpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJvb2wuCiAgICovCiAgYm9vbGVhbiBnZXRPcHRpb25hbEJvb2woKTsKCiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc09wdGlvbmFsU3RyaW5nKCk7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgKi8KICBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nKCk7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgIGdldE9wdGlvbmFsU3RyaW5nQnl0ZXMoKTsKCiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEJ5dGVzIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc09wdGlvbmFsQnl0ZXMoKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHRpb25hbF9ieXRlcyA9IDE1OzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJ5dGVzLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCk7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkID0gMTYgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxDb3JkIGZpZWxkIGlzIHNldC4KICAgKi8KICBib29sZWFuIGhhc09wdGlvbmFsQ29yZCgpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkID0gMTYgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQ29yZC4KICAgKi8KICBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsQ29yZCgpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkID0gMTYgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbENvcmQuCiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgIGdldE9wdGlvbmFsQ29yZEJ5dGVzKCk7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpOwoKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UgbGF6eV9uZXN0ZWRfbWVzc2FnZSA9IDE5IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAqIEByZXR1cm4gV2hldGhlciB0aGUgbGF6eU5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAqLwogIGJvb2xlYW4gaGFzTGF6eU5lc3RlZE1lc3NhZ2UoKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZE1lc3NhZ2UgbGF6eV9uZXN0ZWRfbWVzc2FnZSA9IDE5IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIGxhenlOZXN0ZWRNZXNzYWdlLgogICAqLwogIGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBnZXRMYXp5TmVzdGVkTWVzc2FnZSgpOwogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZSBsYXp5X25lc3RlZF9tZXNzYWdlID0gMTkgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICovCiAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldExhenlOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCk7CgogIC8qKgogICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOzwvY29kZT4KICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkRW51bSBmaWVsZCBpcyBzZXQuCiAgICovCiAgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZEVudW0oKTsKICAvKioKICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbE5lc3RlZEVudW0uCiAgICovCiAgaW50IGdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCk7CiAgLyoqCiAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgKi8KICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVGVzdFByb3RvM09wdGlvbmFsLk5lc3RlZEVudW0gZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtKCk7CgogIC8qKgogICAqIDxwcmU+CiAgICogQWRkIHNvbWUgbm9uLW9wdGlvbmFsIGZpZWxkcyB0byB2ZXJpZnkgd2UgY2FuIG1peCB0aGVtLgogICAqIDwvcHJlPgogICAqCiAgICogPGNvZGU+aW50MzIgc2luZ3VsYXJfaW50MzIgPSAyMjs8L2NvZGU+CiAgICogQHJldHVybiBUaGUgc2luZ3VsYXJJbnQzMi4KICAgKi8KICBpbnQgZ2V0U2luZ3VsYXJJbnQzMigpOwoKICAvKioKICAgKiA8Y29kZT5pbnQ2NCBzaW5ndWxhcl9pbnQ2NCA9IDIzOzwvY29kZT4KICAgKiBAcmV0dXJuIFRoZSBzaW5ndWxhckludDY0LgogICAqLwogIGxvbmcgZ2V0U2luZ3VsYXJJbnQ2NCgpOwp9ClBLAwQKAAAAAAAAACEARsOLccMLAADDCwAAKgAAAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9wcm90by9VSUQuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3Byb3RvM19iYWRfbWFjcm9zLnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG87CgovKioKICogPHByZT4KICogVGhpcyBnZW5lcmF0ZXMgYFVJRF9NQVhgLCB3aGljaCBpcyBhIG1jcm8gaW4gc29tZSBjaXJjdW1zdGFuY2VzLgogKiA8L3ByZT4KICoKICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVUlEfQogKi8KcHVibGljIGVudW0gVUlECiAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgLyoqCiAgICogPGNvZGU+VUlEX1VOVVNFRCA9IDA7PC9jb2RlPgogICAqLwogIFVJRF9VTlVTRUQoMCksCiAgVU5SRUNPR05JWkVEKC0xKSwKICA7CgogIC8qKgogICAqIDxjb2RlPlVJRF9VTlVTRUQgPSAwOzwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVSURfVU5VU0VEX1ZBTFVFID0gMDsKCgogIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgIkNhbid0IGdldCB0aGUgbnVtYmVyIG9mIGFuIHVua25vd24gZW51bSB2YWx1ZS4iKTsKICAgIH0KICAgIHJldHVybiB2YWx1ZTsKICB9CgogIC8qKgogICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgKi8KICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICBwdWJsaWMgc3RhdGljIFVJRCB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgfQoKICAvKioKICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICovCiAgcHVibGljIHN0YXRpYyBVSUQgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgc3dpdGNoICh2YWx1ZSkgewogICAgICBjYXNlIDA6IHJldHVybiBVSURfVU5VU0VEOwogICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgIH0KICB9CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxVSUQ+CiAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgVUlEPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxVSUQ+KCkgewogICAgICAgICAgcHVibGljIFVJRCBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgIHJldHVybiBVSUQuZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICB9CiAgICAgICAgfTsKCiAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oCiAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBkZXNjcmlwdG9yIG9mIGFuIHVucmVjb2duaXplZCBlbnVtIHZhbHVlLiIpOwogICAgfQogICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICB9CiAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogIH0KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uVW5pdHRlc3RQcm90bzNCYWRNYWNyb3MuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgxKTsKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIFVJRFtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICBwdWJsaWMgc3RhdGljIFVJRCB2YWx1ZU9mKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgIH0KICAgIGlmIChkZXNjLmdldEluZGV4KCkgPT0gLTEpIHsKICAgICAgcmV0dXJuIFVOUkVDT0dOSVpFRDsKICAgIH0KICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICB9CgogIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICBwcml2YXRlIFVJRChpbnQgdmFsdWUpIHsKICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlVJRCkKfQoKUEsDBAoAAAAAAAAAIQAAjQOsxgkAAMYJAAA+AAAAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3Byb3RvL1VuaXR0ZXN0UHJvdG8zQmFkTWFjcm9zLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcm90bzNfYmFkX21hY3Jvcy5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvOwoKcHVibGljIGZpbmFsIGNsYXNzIFVuaXR0ZXN0UHJvdG8zQmFkTWFjcm9zIHsKICBwcml2YXRlIFVuaXR0ZXN0UHJvdG8zQmFkTWFjcm9zKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4wZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3Byb3RvM19iYWRfbWEiICsKICAgICAgImNyb3MucHJvdG9cMDIyXDAyMXByb3RvYnVmX3VuaXR0ZXN0KlwwMjVcblwwMDNHSURcMDIyXDAxNlxuXG4iICsKICAgICAgIkdJRF9VTlVTRURcMDIwXDAwMCpcMDI1XG5cMDAzVUlEXDAyMlwwMTZcblxuVUlEX1VOVVNFRFwwMjBcMDAwKlwzNTBcMDAzXG5cMDEwIiArCiAgICAgICJCYWROYW1lc1wwMjJcMDEzXG5cMDA3UEFDS0FHRVwwMjBcMDAwXDAyMlxuXG5cMDA2UEFDS0VEXDAyMFwwMDFcMDIyXHRcblwwMDVsaW4iICsKICAgICAgInV4XDAyMFwwMDJcMDIyXG5cblwwMDZET01BSU5cMDIwXDAwM1wwMjJcMDEwXG5cMDA0VFJVRVwwMjBcMDA0XDAyMlx0XG5cMDA1RkFMU0VcMDIwXDAwNVwwMjJcMDE2XG4iICsKICAgICAgIlxuQ1JFQVRFX05FV1wwMjBcMDA2XDAyMlxuXG5cMDA2REVMRVRFXDAyMFwwMDdcMDIyXDAyMFxuXDAxNERPVUJMRV9DTElDIiArCiAgICAgICJLXDAyMFwwMTBcMDIyXHRcblwwMDVFUlJPUlwwMjBcdFwwMjJcMDE2XG5cbkVSUk9SX0JVU1lcMDIwXG5cMDIyXDAzMFxuXDAyNEVSUk9SXyIgKwogICAgICAiSU5TVEFMTF9GQUlMRURcMDIwXDAxM1wwMjJcMDIzXG5cMDE3RVJST1JfTk9UX0ZPVU5EXDAyMFwwMTRcMDIyXDAyMFxuIiArCiAgICAgICJcMDE0R2V0Q2xhc3NOYW1lXDAyMFxyXDAyMlwwMjJcblwwMTZHZXRDdXJyZW50VGltZVwwMjBcMDE2XDAyMlwwMTZcblxuRyIgKwogICAgICAiZXRNZXNzYWdlXDAyMFwwMTdcMDIyXHJcblx0R2V0T2JqZWN0XDAyMFwwMjBcMDIyXG5cblwwMDZJR05PUkVcMDIwXDAyMVwwMjJcMDA2IiArCiAgICAgICJcblwwMDJJTlwwMjBcMDIyXDAyMlwwMjJcblwwMTZJTlBVVF9LRVlCT0FSRFwwMjBcMDIzXDAyMlwwMTRcblwwMTBOT19FUlJPUlwwMjBcMDI0IiArCiAgICAgICJcMDIyXDAwN1xuXDAwM09VVFwwMjBcMDI1XDAyMlwwMTRcblwwMTBPUFRJT05BTFwwMjBcMDI2XDAyMlwwMTBcblwwMDRORUFSXDAyMFwwMjdcMDIyXDAxM1xuXDAwN05PXyIgKwogICAgICAiREFUQVwwMjBcMDMwXDAyMlwwMjJcblwwMTZSRUFTT05fVU5LTk9XTlwwMjBcMDMxXDAyMlwwMjRcblwwMjBTRVJWSUNFX0RJIiArCiAgICAgICJTQUJMRURcMDIwXDAzMlwwMjJcMDIyXG5cMDE2U0VWRVJJVFlfRVJST1JcMDIwXDAzM1wwMjJcMDIyXG5cMDE2U1RBVFVTX1AiICsKICAgICAgIkVORElOR1wwMjBcMDM0XDAyMlxuXG5cMDA2U1RSSUNUXDAyMFwwMzVcMDIyXHJcblx0VFlQRV9CT09MXDAyMFwwMzZcMDIyXHRcblwwMDVEIiArCiAgICAgICJFQlVHXDAyMFwwMzdCOFxuIWNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wciIgKwogICAgICAib3RvUFwwMDFcMjUyXDAwMlwwMjBQcm90b2J1ZlVuaXR0ZXN0YlwwMDZwcm90bzMiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICB9KTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAMH4VLZtJQAAbSUAAD0AAABjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvcHJvdG8vVW5pdHRlc3RQcm90bzNPcHRpb25hbC5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX29wdGlvbmFsLnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG87CgpwdWJsaWMgZmluYWwgY2xhc3MgVW5pdHRlc3RQcm90bzNPcHRpb25hbCB7CiAgcHJpdmF0ZSBVbml0dGVzdFByb3RvM09wdGlvbmFsKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogICAgcmVnaXN0cnkuYWRkKGNvbS5nb29nbGUucHJvdG9idWYudGVzdGluZy5wcm90by5Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnMuZXh0Tm9PcHRpb25hbCk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucy5leHRXaXRoT3B0aW9uYWwpOwogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsX2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxfZmllbGRBY2Nlc3NvclRhYmxlOwogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Byb3RvM09wdGlvbmFsRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuLmdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcm90bzNfb3B0aW9uIiArCiAgICAgICJhbC5wcm90b1wwMjJcMDIxcHJvdG9idWZfdW5pdHRlc3RcMDMyIGdvb2dsZS9wcm90IiArCiAgICAgICJvYnVmL2Rlc2NyaXB0b3IucHJvdG9cIlwyNjFcblxuXDAyMlRlc3RQcm90bzNPcHRpIiArCiAgICAgICJvbmFsXDAyMlwwMzNcblwwMTZvcHRpb25hbF9pbnQzMlwwMzBcMDAxIFwwMDEoXDAwNUhcMDAwXDIxMFwwMDFcMDAxXDAyMlwwMzNcblwwMTZvcHQiICsKICAgICAgImlvbmFsX2ludDY0XDAzMFwwMDIgXDAwMShcMDAzSFwwMDFcMjEwXDAwMVwwMDFcMDIyXDAzNFxuXDAxN29wdGlvbmFsX3VpbnQzIiArCiAgICAgICIyXDAzMFwwMDMgXDAwMShcckhcMDAyXDIxMFwwMDFcMDAxXDAyMlwwMzRcblwwMTdvcHRpb25hbF91aW50NjRcMDMwXDAwNCBcMDAxKFwwMDRIXDAwM1wyMTAiICsKICAgICAgIlwwMDFcMDAxXDAyMlwwMzRcblwwMTdvcHRpb25hbF9zaW50MzJcMDMwXDAwNSBcMDAxKFwwMjFIXDAwNFwyMTBcMDAxXDAwMVwwMjJcMDM0XG5cMDE3b3B0aSIgKwogICAgICAib25hbF9zaW50NjRcMDMwXDAwNiBcMDAxKFwwMjJIXDAwNVwyMTBcMDAxXDAwMVwwMjJcMDM1XG5cMDIwb3B0aW9uYWxfZml4ZWQiICsKICAgICAgIjMyXDAzMFwwMDcgXDAwMShcMDA3SFwwMDZcMjEwXDAwMVwwMDFcMDIyXDAzNVxuXDAyMG9wdGlvbmFsX2ZpeGVkNjRcMDMwXDAxMCBcMDAxKFwwMDZIIiArCiAgICAgICJcMDA3XDIxMFwwMDFcMDAxXDAyMlwwMzZcblwwMjFvcHRpb25hbF9zZml4ZWQzMlwwMzBcdCBcMDAxKFwwMTdIXDAxMFwyMTBcMDAxXDAwMVwwMjJcMDM2XG5cMDIxIiArCiAgICAgICJvcHRpb25hbF9zZml4ZWQ2NFwwMzBcbiBcMDAxKFwwMjBIXHRcMjEwXDAwMVwwMDFcMDIyXDAzM1xuXDAxNm9wdGlvbmFsIiArCiAgICAgICJfZmxvYXRcMDMwXDAxMyBcMDAxKFwwMDJIXG5cMjEwXDAwMVwwMDFcMDIyXDAzNFxuXDAxN29wdGlvbmFsX2RvdWJsZVwwMzBcMDE0IFwwMDEiICsKICAgICAgIihcMDAxSFwwMTNcMjEwXDAwMVwwMDFcMDIyXDAzMlxuXHJvcHRpb25hbF9ib29sXDAzMFxyIFwwMDEoXDAxMEhcMDE0XDIxMFwwMDFcMDAxXDAyMlwwMzRcblwwMTdvIiArCiAgICAgICJwdGlvbmFsX3N0cmluZ1wwMzBcMDE2IFwwMDEoXHRIXHJcMjEwXDAwMVwwMDFcMDIyXDAzM1xuXDAxNm9wdGlvbmFsX2J5IiArCiAgICAgICJ0ZXNcMDMwXDAxNyBcMDAxKFwwMTRIXDAxNlwyMTBcMDAxXDAwMVwwMjJcMDM2XG5ccm9wdGlvbmFsX2NvcmRcMDMwXDAyMCBcMDAxKFx0QlwwMDJcMDEwIiArCiAgICAgICJcMDAxSFwwMTdcMjEwXDAwMVwwMDFcMDIyWVxuXDAyN29wdGlvbmFsX25lc3RlZF9tZXNzYWdlXDAzMFwwMjIgXDAwMShcMDEzMiIgKwogICAgICAiMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8zT3B0aW9uYWwuTiIgKwogICAgICAiZXN0ZWRNZXNzYWdlSFwwMjBcMjEwXDAwMVwwMDFcMDIyWVxuXDAyM2xhenlfbmVzdGVkX21lc3NhZ2UiICsKICAgICAgIlwwMzBcMDIzIFwwMDEoXDAxMzIzLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcHQiICsKICAgICAgImlvbmFsLk5lc3RlZE1lc3NhZ2VCXDAwMihcMDAxSFwwMjFcMjEwXDAwMVwwMDFcMDIyU1xuXDAyNG9wdGlvbmFsIiArCiAgICAgICJfbmVzdGVkX2VudW1cMDMwXDAyNSBcMDAxKFwwMTYyMC5wcm90b2J1Zl91bml0dGVzdC5UIiArCiAgICAgICJlc3RQcm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtSFwwMjJcMjEwXDAwMVwwMDFcMDIyXDAyNlxuXDAxNnNpbiIgKwogICAgICAiZ3VsYXJfaW50MzJcMDMwXDAyNiBcMDAxKFwwMDVcMDIyXDAyNlxuXDAxNnNpbmd1bGFyX2ludDY0XDAzMFwwMjcgXDAwMSgiICsKICAgICAgIlwwMDNcMDMyXCdcblxyTmVzdGVkTWVzc2FnZVwwMjJcMDE3XG5cMDAyYmJcMDMwXDAwMSBcMDAxKFwwMDVIXDAwMFwyMTBcMDAxXDAwMUJcMDA1XG5cMDAzXyIgKwogICAgICAiYmJcIkpcblxuTmVzdGVkRW51bVwwMjJcMDE3XG5cMDEzVU5TUEVDSUZJRURcMDIwXDAwMFwwMjJcMDA3XG5cMDAzRk9PIiArCiAgICAgICJcMDIwXDAwMVwwMjJcMDA3XG5cMDAzQkFSXDAyMFwwMDJcMDIyXDAwN1xuXDAwM0JBWlwwMjBcMDAzXDAyMlwwMjBcblwwMDNORUdcMDIwXDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDAwMUJcMDIxIiArCiAgICAgICJcblwwMTdfb3B0aW9uYWxfaW50MzJCXDAyMVxuXDAxN19vcHRpb25hbF9pbnQ2NEJcMDIyXG5cMDIwIiArCiAgICAgICJfb3B0aW9uYWxfdWludDMyQlwwMjJcblwwMjBfb3B0aW9uYWxfdWludDY0QlwwMjJcblwwMjAiICsKICAgICAgIl9vcHRpb25hbF9zaW50MzJCXDAyMlxuXDAyMF9vcHRpb25hbF9zaW50NjRCXDAyM1xuXDAyMSIgKwogICAgICAiX29wdGlvbmFsX2ZpeGVkMzJCXDAyM1xuXDAyMV9vcHRpb25hbF9maXhlZDY0QlwwMjQiICsKICAgICAgIlxuXDAyMl9vcHRpb25hbF9zZml4ZWQzMkJcMDI0XG5cMDIyX29wdGlvbmFsX3NmaXhlZCIgKwogICAgICAiNjRCXDAyMVxuXDAxN19vcHRpb25hbF9mbG9hdEJcMDIyXG5cMDIwX29wdGlvbmFsX2RvdWJsIiArCiAgICAgICJlQlwwMjBcblwwMTZfb3B0aW9uYWxfYm9vbEJcMDIyXG5cMDIwX29wdGlvbmFsX3N0cmluZ0IiICsKICAgICAgIlwwMjFcblwwMTdfb3B0aW9uYWxfYnl0ZXNCXDAyMFxuXDAxNl9vcHRpb25hbF9jb3JkQlwwMzJcblwwMzAiICsKICAgICAgIl9vcHRpb25hbF9uZXN0ZWRfbWVzc2FnZUJcMDI2XG5cMDI0X2xhenlfbmVzdGVkIiArCiAgICAgICJfbWVzc2FnZUJcMDI3XG5cMDI1X29wdGlvbmFsX25lc3RlZF9lbnVtXCJcMjExXDAwMlxuXDAzMVRlIiArCiAgICAgICJzdFByb3RvM09wdGlvbmFsTWVzc2FnZVwwMjJSXG5cMDE2bmVzdGVkX21lc3NhZyIgKwogICAgICAiZVwwMzBcMDAxIFwwMDEoXDAxMzI6LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNPcCIgKwogICAgICAidGlvbmFsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlXDAyMmBcblwwMjdvcHRpb25hbF8iICsKICAgICAgIm5lc3RlZF9tZXNzYWdlXDAzMFwwMDIgXDAwMShcMDEzMjoucHJvdG9idWZfdW5pdHRlc3QiICsKICAgICAgIi5UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UiICsKICAgICAgIkhcMDAwXDIxMFwwMDFcMDAxXDAzMlwwMzJcblxyTmVzdGVkTWVzc2FnZVwwMjJcdFxuXDAwMXNcMDMwXDAwMSBcMDAxKFx0QlwwMzJcblwwMzBfb3AiICsKICAgICAgInRpb25hbF9uZXN0ZWRfbWVzc2FnZVwiXDI1MVwwMDFcblwwMzBQcm90bzNPcHRpb25hbCIgKwogICAgICAiRXh0ZW5zaW9uczI8XG5cMDE3ZXh0X25vX29wdGlvbmFsXDAyMlwwMzcuZ29vZ2xlLnAiICsKICAgICAgInJvdG9idWYuTWVzc2FnZU9wdGlvbnNcMDMwXDIxMFwzMTVcMzMxXDI1MVwwMDEgXDAwMShcMDA1MkFcblwwMjFleHRfIiArCiAgICAgICJ3aXRoX29wdGlvbmFsXDAyMlwwMzcuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPIiArCiAgICAgICJwdGlvbnNcMDMwXDIxMVwzMTVcMzMxXDI1MVwwMDEgXDAwMShcMDA1XDIxMFwwMDFcMDAxOlwwMTRcMzAwXDM1MFwzMTRcMzE1XG5cMDEwXDMxMFwzNTBcMzE0XDMxNVxuXDAyMEI4XG4hY29tIiArCiAgICAgICIuZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG9QXDAwMVwyNTJcMDAyXDAyMFByb3RvIiArCiAgICAgICJidWZVbml0dGVzdGJcMDA2cHJvdG8zIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuZ2V0RGVzY3JpcHRvcigpLAogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzNPcHRpb25hbF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbEludDMyIiwgIk9wdGlvbmFsSW50NjQiLCAiT3B0aW9uYWxVaW50MzIiLCAiT3B0aW9uYWxVaW50NjQiLCAiT3B0aW9uYWxTaW50MzIiLCAiT3B0aW9uYWxTaW50NjQiLCAiT3B0aW9uYWxGaXhlZDMyIiwgIk9wdGlvbmFsRml4ZWQ2NCIsICJPcHRpb25hbFNmaXhlZDMyIiwgIk9wdGlvbmFsU2ZpeGVkNjQiLCAiT3B0aW9uYWxGbG9hdCIsICJPcHRpb25hbERvdWJsZSIsICJPcHRpb25hbEJvb2wiLCAiT3B0aW9uYWxTdHJpbmciLCAiT3B0aW9uYWxCeXRlcyIsICJPcHRpb25hbENvcmQiLCAiT3B0aW9uYWxOZXN0ZWRNZXNzYWdlIiwgIkxhenlOZXN0ZWRNZXNzYWdlIiwgIk9wdGlvbmFsTmVzdGVkRW51bSIsICJTaW5ndWxhckludDMyIiwgIlNpbmd1bGFySW50NjQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzNPcHRpb25hbF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzNPcHRpb25hbF9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzNPcHRpb25hbF9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJCYiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJOZXN0ZWRNZXNzYWdlIiwgIk9wdGlvbmFsTmVzdGVkTWVzc2FnZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzNPcHRpb25hbE1lc3NhZ2VfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJTIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Byb3RvM09wdGlvbmFsRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Qcm90bzNPcHRpb25hbEV4dGVuc2lvbnNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5Lm5ld0luc3RhbmNlKCk7CiAgICByZWdpc3RyeS5hZGQoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvLlByb3RvM09wdGlvbmFsRXh0ZW5zaW9ucy5leHROb09wdGlvbmFsKTsKICAgIHJlZ2lzdHJ5LmFkZChjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG8uUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zLmV4dFdpdGhPcHRpb25hbCk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgICAgLmludGVybmFsVXBkYXRlRmlsZURlc2NyaXB0b3IoZGVzY3JpcHRvciwgcmVnaXN0cnkpOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLmdldERlc2NyaXB0b3IoKTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAHXK+hOxlwIAsZcCABgAAABwYi9Vbml0dGVzdEZlYXR1cmVzLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9mZWF0dXJlcy5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcGI7CgpwdWJsaWMgZmluYWwgY2xhc3MgVW5pdHRlc3RGZWF0dXJlcyB7CiAgcHJpdmF0ZSBVbml0dGVzdEZlYXR1cmVzKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogICAgcmVnaXN0cnkuYWRkKHBiLlVuaXR0ZXN0RmVhdHVyZXMudGVzdCk7CiAgICByZWdpc3RyeS5hZGQocGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS50ZXN0TWVzc2FnZSk7CiAgICByZWdpc3RyeS5hZGQocGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5OZXN0ZWQudGVzdE5lc3RlZCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cGIuVGVzdE1lc3NhZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHBiLlRlc3RNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cGIuVGVzdE1lc3NhZ2UpCiAgICAgIFRlc3RNZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RNZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcGIuVW5pdHRlc3RGZWF0dXJlcy5pbnRlcm5hbF9zdGF0aWNfcGJfVGVzdE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwYi5Vbml0dGVzdEZlYXR1cmVzLmludGVybmFsX3N0YXRpY19wYl9UZXN0TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuY2xhc3MsIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBOZXN0ZWRPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwYi5UZXN0TWVzc2FnZS5OZXN0ZWQpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcGIuVGVzdE1lc3NhZ2UuTmVzdGVkfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZCBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cGIuVGVzdE1lc3NhZ2UuTmVzdGVkKQogICAgICAgIE5lc3RlZE9yQnVpbGRlciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgLy8gVXNlIE5lc3RlZC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIE5lc3RlZChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE5lc3RlZCgpIHsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBOZXN0ZWQoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHBiLlVuaXR0ZXN0RmVhdHVyZXMuaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RNZXNzYWdlX05lc3RlZF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwYi5Vbml0dGVzdEZlYXR1cmVzLmludGVybmFsX3N0YXRpY19wYl9UZXN0TWVzc2FnZV9OZXN0ZWRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5OZXN0ZWQuY2xhc3MsIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuTmVzdGVkLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuTmVzdGVkKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZCBvdGhlciA9IChwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZCkgb2JqOwoKICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5OZXN0ZWQgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuTmVzdGVkIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5OZXN0ZWQgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5OZXN0ZWQgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuTmVzdGVkIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuTmVzdGVkIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuTmVzdGVkIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5OZXN0ZWQgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5OZXN0ZWQgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcGIuVGVzdE1lc3NhZ2UuTmVzdGVkfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwYi5UZXN0TWVzc2FnZS5OZXN0ZWQpCiAgICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZE9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwYi5Vbml0dGVzdEZlYXR1cmVzLmludGVybmFsX3N0YXRpY19wYl9UZXN0TWVzc2FnZV9OZXN0ZWRfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHBiLlVuaXR0ZXN0RmVhdHVyZXMuaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RNZXNzYWdlX05lc3RlZF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5OZXN0ZWQuY2xhc3MsIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuTmVzdGVkLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuTmVzdGVkLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcGIuVW5pdHRlc3RGZWF0dXJlcy5pbnRlcm5hbF9zdGF0aWNfcGJfVGVzdE1lc3NhZ2VfTmVzdGVkX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuTmVzdGVkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5OZXN0ZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuTmVzdGVkIGJ1aWxkKCkgewogICAgICAgICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5OZXN0ZWQgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuTmVzdGVkIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuTmVzdGVkIHJlc3VsdCA9IG5ldyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZCh0aGlzKTsKICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZCkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZClvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZCBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuTmVzdGVkLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cGIuVGVzdE1lc3NhZ2UuTmVzdGVkKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cGIuVGVzdE1lc3NhZ2UuTmVzdGVkKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZCBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5OZXN0ZWQoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZD4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE5lc3RlZD4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBOZXN0ZWQgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWQ+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWQ+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5OZXN0ZWQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEVTVF9ORVNURURfRklFTERfTlVNQkVSID0gOTk5NzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZlYXR1cmVTZXQsCiAgICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcz4gdGVzdE5lc3RlZCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLk5lc3RlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSwKICAgICAgICAgICAgMCwKICAgICAgICAgICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuY2xhc3MsCiAgICAgICAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlIG90aGVyID0gKHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwYi5UZXN0TWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnBiLlRlc3RNZXNzYWdlKQogICAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2VPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcGIuVW5pdHRlc3RGZWF0dXJlcy5pbnRlcm5hbF9zdGF0aWNfcGJfVGVzdE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcGIuVW5pdHRlc3RGZWF0dXJlcy5pbnRlcm5hbF9zdGF0aWNfcGJfVGVzdE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5jbGFzcywgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwYi5Vbml0dGVzdEZlYXR1cmVzLmludGVybmFsX3N0YXRpY19wYl9UZXN0TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UgcmVzdWx0ID0gbmV3IHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2UodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cGIuVGVzdE1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnBiLlRlc3RNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0TWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdE1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRFU1RfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSA5OTk4OwogICAgLyoqCiAgICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmVhdHVyZVNldCwKICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcz4gdGVzdE1lc3NhZ2UgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMCwKICAgICAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLmNsYXNzLAogICAgICAgICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0RmVhdHVyZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cGIuVGVzdEZlYXR1cmVzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2ZpbGVfZmVhdHVyZSA9IDEgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklMRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludEZpbGVGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNJbnRGaWxlRmVhdHVyZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZmlsZV9mZWF0dXJlID0gMSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUxFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGludEZpbGVGZWF0dXJlLgogICAgICovCiAgICBpbnQgZ2V0SW50RmlsZUZlYXR1cmUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9leHRlbnNpb25fcmFuZ2VfZmVhdHVyZSA9IDIgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRVhURU5TSU9OX1JBTkdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50RXh0ZW5zaW9uUmFuZ2VGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNJbnRFeHRlbnNpb25SYW5nZUZlYXR1cmUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2V4dGVuc2lvbl9yYW5nZV9mZWF0dXJlID0gMiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50RXh0ZW5zaW9uUmFuZ2VGZWF0dXJlLgogICAgICovCiAgICBpbnQgZ2V0SW50RXh0ZW5zaW9uUmFuZ2VGZWF0dXJlKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfbWVzc2FnZV9mZWF0dXJlID0gMyBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVNTQUdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50TWVzc2FnZUZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ludE1lc3NhZ2VGZWF0dXJlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9tZXNzYWdlX2ZlYXR1cmUgPSAzIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50TWVzc2FnZUZlYXR1cmUuCiAgICAgKi8KICAgIGludCBnZXRJbnRNZXNzYWdlRmVhdHVyZSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2ZpZWxkX2ZlYXR1cmUgPSA0IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50RmllbGRGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNJbnRGaWVsZEZlYXR1cmUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2ZpZWxkX2ZlYXR1cmUgPSA0IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGludEZpZWxkRmVhdHVyZS4KICAgICAqLwogICAgaW50IGdldEludEZpZWxkRmVhdHVyZSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X29uZW9mX2ZlYXR1cmUgPSA1IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50T25lb2ZGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNJbnRPbmVvZkZlYXR1cmUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X29uZW9mX2ZlYXR1cmUgPSA1IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGludE9uZW9mRmVhdHVyZS4KICAgICAqLwogICAgaW50IGdldEludE9uZW9mRmVhdHVyZSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2VudW1fZmVhdHVyZSA9IDYgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludEVudW1GZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNJbnRFbnVtRmVhdHVyZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZW51bV9mZWF0dXJlID0gNiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGludEVudW1GZWF0dXJlLgogICAgICovCiAgICBpbnQgZ2V0SW50RW51bUZlYXR1cmUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9lbnVtX2VudHJ5X2ZlYXR1cmUgPSA3IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU1fRU5UUlksIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRFbnVtRW50cnlGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNJbnRFbnVtRW50cnlGZWF0dXJlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9lbnVtX2VudHJ5X2ZlYXR1cmUgPSA3IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU1fRU5UUlksIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50RW51bUVudHJ5RmVhdHVyZS4KICAgICAqLwogICAgaW50IGdldEludEVudW1FbnRyeUZlYXR1cmUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9zZXJ2aWNlX2ZlYXR1cmUgPSA4IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRTZXJ2aWNlRmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzSW50U2VydmljZUZlYXR1cmUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X3NlcnZpY2VfZmVhdHVyZSA9IDggW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfU0VSVklDRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbnRTZXJ2aWNlRmVhdHVyZS4KICAgICAqLwogICAgaW50IGdldEludFNlcnZpY2VGZWF0dXJlKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfbWV0aG9kX2ZlYXR1cmUgPSA5IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FVEhPRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludE1ldGhvZEZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ludE1ldGhvZEZlYXR1cmUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X21ldGhvZF9mZWF0dXJlID0gOSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50TWV0aG9kRmVhdHVyZS4KICAgICAqLwogICAgaW50IGdldEludE1ldGhvZEZlYXR1cmUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9tdWx0aXBsZV9mZWF0dXJlID0gMTAgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklMRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU0sIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNX0VOVFJZLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfU0VSVklDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FVEhPRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRVhURU5TSU9OX1JBTkdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50TXVsdGlwbGVGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNJbnRNdWx0aXBsZUZlYXR1cmUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X211bHRpcGxlX2ZlYXR1cmUgPSAxMCBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUxFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVNTQUdFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU1fRU5UUlksIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9TRVJWSUNFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVUSE9ELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfT05FT0YsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50TXVsdGlwbGVGZWF0dXJlLgogICAgICovCiAgICBpbnQgZ2V0SW50TXVsdGlwbGVGZWF0dXJlKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGJvb2xfZmllbGRfZmVhdHVyZSA9IDExIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYm9vbEZpZWxkRmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQm9vbEZpZWxkRmVhdHVyZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGJvb2xfZmllbGRfZmVhdHVyZSA9IDExIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJvb2xGaWVsZEZlYXR1cmUuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0Qm9vbEZpZWxkRmVhdHVyZSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZmxvYXRfZmllbGRfZmVhdHVyZSA9IDEyIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmxvYXRGaWVsZEZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0Zsb2F0RmllbGRGZWF0dXJlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGZsb2F0X2ZpZWxkX2ZlYXR1cmUgPSAxMiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmbG9hdEZpZWxkRmVhdHVyZS4KICAgICAqLwogICAgZmxvYXQgZ2V0RmxvYXRGaWVsZEZlYXR1cmUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wYi5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgbWVzc2FnZV9maWVsZF9mZWF0dXJlID0gMTMgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtZXNzYWdlRmllbGRGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNNZXNzYWdlRmllbGRGZWF0dXJlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wYi5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgbWVzc2FnZV9maWVsZF9mZWF0dXJlID0gMTMgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbWVzc2FnZUZpZWxkRmVhdHVyZS4KICAgICAqLwogICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgZ2V0TWVzc2FnZUZpZWxkRmVhdHVyZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucGIuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIG1lc3NhZ2VfZmllbGRfZmVhdHVyZSA9IDEzIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmVPckJ1aWxkZXIgZ2V0TWVzc2FnZUZpZWxkRmVhdHVyZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnBiLlRlc3RGZWF0dXJlcy5FbnVtRmVhdHVyZSBlbnVtX2ZpZWxkX2ZlYXR1cmUgPSAxNCBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGVudW1GaWVsZEZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0VudW1GaWVsZEZlYXR1cmUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnBiLlRlc3RGZWF0dXJlcy5FbnVtRmVhdHVyZSBlbnVtX2ZpZWxkX2ZlYXR1cmUgPSAxNCBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtRmllbGRGZWF0dXJlLgogICAgICovCiAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5FbnVtRmVhdHVyZSBnZXRFbnVtRmllbGRGZWF0dXJlKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfc291cmNlX2ZlYXR1cmUgPSAxNSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1NPVVJDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludFNvdXJjZUZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ludFNvdXJjZUZlYXR1cmUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X3NvdXJjZV9mZWF0dXJlID0gMTUgW3JldGVudGlvbiA9IFJFVEVOVElPTl9TT1VSQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUxFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVNTQUdFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU1fRU5UUlksIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9TRVJWSUNFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVUSE9ELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfT05FT0YsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50U291cmNlRmVhdHVyZS4KICAgICAqLwogICAgaW50IGdldEludFNvdXJjZUZlYXR1cmUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfc291cmNlX2ZlYXR1cmUgPSAxNiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1NPVVJDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cmluZ1NvdXJjZUZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cmluZ1NvdXJjZUZlYXR1cmUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19zb3VyY2VfZmVhdHVyZSA9IDE2IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fU09VUkNFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklMRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU0sIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNX0VOVFJZLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfU0VSVklDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FVEhPRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRVhURU5TSU9OX1JBTkdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ1NvdXJjZUZlYXR1cmUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nU291cmNlRmVhdHVyZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX3NvdXJjZV9mZWF0dXJlID0gMTYgW3JldGVudGlvbiA9IFJFVEVOVElPTl9TT1VSQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUxFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVNTQUdFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU1fRU5UUlksIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9TRVJWSUNFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVUSE9ELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfT05FT0YsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cmluZ1NvdXJjZUZlYXR1cmUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cmluZ1NvdXJjZUZlYXR1cmVCeXRlcygpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwYi5UZXN0RmVhdHVyZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0RmVhdHVyZXMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cGIuVGVzdEZlYXR1cmVzKQogICAgICBUZXN0RmVhdHVyZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RGZWF0dXJlcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0RmVhdHVyZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0RmVhdHVyZXMoKSB7CiAgICAgIGVudW1GaWVsZEZlYXR1cmVfID0gMDsKICAgICAgc3RyaW5nU291cmNlRmVhdHVyZV8gPSAiIjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0RmVhdHVyZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwYi5Vbml0dGVzdEZlYXR1cmVzLmludGVybmFsX3N0YXRpY19wYl9UZXN0RmVhdHVyZXNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwYi5Vbml0dGVzdEZlYXR1cmVzLmludGVybmFsX3N0YXRpY19wYl9UZXN0RmVhdHVyZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5jbGFzcywgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwYi5UZXN0RmVhdHVyZXMuRW51bUZlYXR1cmV9CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIEVudW1GZWF0dXJlCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgICAvKioKICAgICAgICogPGNvZGU+VEVTVF9FTlVNX0ZFQVRVUkVfVU5LTk9XTiA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgVEVTVF9FTlVNX0ZFQVRVUkVfVU5LTk9XTigwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkVOVU1fVkFMVUUxID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBFTlVNX1ZBTFVFMSgxKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkVOVU1fVkFMVUUyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBFTlVNX1ZBTFVFMigyKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkVOVU1fVkFMVUUzID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBFTlVNX1ZBTFVFMygzKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkVOVU1fVkFMVUU0ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBFTlVNX1ZBTFVFNCg0KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkVOVU1fVkFMVUU1ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBFTlVNX1ZBTFVFNSg1KSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlRFU1RfRU5VTV9GRUFUVVJFX1VOS05PV04gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRFU1RfRU5VTV9GRUFUVVJFX1VOS05PV05fVkFMVUUgPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+RU5VTV9WQUxVRTEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fVkFMVUUxX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkVOVU1fVkFMVUUyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX1ZBTFVFMl9WQUxVRSA9IDI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5FTlVNX1ZBTFVFMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9WQUxVRTNfVkFMVUUgPSAzOwogICAgICAvKioKICAgICAgICogPGNvZGU+RU5VTV9WQUxVRTQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fVkFMVUU0X1ZBTFVFID0gNDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkVOVU1fVkFMVUU1ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX1ZBTFVFNV9WQUxVRSA9IDU7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBFbnVtRmVhdHVyZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgRW51bUZlYXR1cmUgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIFRFU1RfRU5VTV9GRUFUVVJFX1VOS05PV047CiAgICAgICAgICBjYXNlIDE6IHJldHVybiBFTlVNX1ZBTFVFMTsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIEVOVU1fVkFMVUUyOwogICAgICAgICAgY2FzZSAzOiByZXR1cm4gRU5VTV9WQUxVRTM7CiAgICAgICAgICBjYXNlIDQ6IHJldHVybiBFTlVNX1ZBTFVFNDsKICAgICAgICAgIGNhc2UgNTogcmV0dXJuIEVOVU1fVkFMVUU1OwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8RW51bUZlYXR1cmU+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBFbnVtRmVhdHVyZT4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPEVudW1GZWF0dXJlPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgRW51bUZlYXR1cmUgZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIEVudW1GZWF0dXJlLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgICB9CiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRW51bUZlYXR1cmVbXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgRW51bUZlYXR1cmUgdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBFbnVtRmVhdHVyZShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnBiLlRlc3RGZWF0dXJlcy5FbnVtRmVhdHVyZSkKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIE1lc3NhZ2VGZWF0dXJlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cGIuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBib29sX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYm9vbEZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzQm9vbEZpZWxkKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGJvb2xfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYm9vbEZpZWxkLgogICAgICAgKi8KICAgICAgYm9vbGVhbiBnZXRCb29sRmllbGQoKTsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc0ludEZpZWxkKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgaW50RmllbGQuCiAgICAgICAqLwogICAgICBpbnQgZ2V0SW50RmllbGQoKTsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmbG9hdF9maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZsb2F0RmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNGbG9hdEZpZWxkKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmbG9hdF9maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmbG9hdEZpZWxkLgogICAgICAgKi8KICAgICAgZmxvYXQgZ2V0RmxvYXRGaWVsZCgpOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfZmllbGQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc1N0cmluZ0ZpZWxkKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ0ZpZWxkLgogICAgICAgKi8KICAgICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHJpbmdGaWVsZCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyaW5nRmllbGQuCiAgICAgICAqLwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFN0cmluZ0ZpZWxkQnl0ZXMoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcGIuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE1lc3NhZ2VGZWF0dXJlIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwYi5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUpCiAgICAgICAgTWVzc2FnZUZlYXR1cmVPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBNZXNzYWdlRmVhdHVyZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIE1lc3NhZ2VGZWF0dXJlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgTWVzc2FnZUZlYXR1cmUoKSB7CiAgICAgICAgc3RyaW5nRmllbGRfID0gIiI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgTWVzc2FnZUZlYXR1cmUoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHBiLlVuaXR0ZXN0RmVhdHVyZXMuaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RGZWF0dXJlc19NZXNzYWdlRmVhdHVyZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwYi5Vbml0dGVzdEZlYXR1cmVzLmludGVybmFsX3N0YXRpY19wYl9UZXN0RmVhdHVyZXNfTWVzc2FnZUZlYXR1cmVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUuY2xhc3MsIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCT09MX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgYm9vbGVhbiBib29sRmllbGRfID0gZmFsc2U7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGJvb2xfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBib29sRmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNCb29sRmllbGQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGJvb2xfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYm9vbEZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRCb29sRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGJvb2xGaWVsZF87CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVF9GSUVMRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgICBwcml2YXRlIGludCBpbnRGaWVsZF8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50RmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbnRGaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBpbnRGaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnRGaWVsZCgpIHsKICAgICAgICByZXR1cm4gaW50RmllbGRfOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGTE9BVF9GSUVMRF9GSUVMRF9OVU1CRVIgPSAzOwogICAgICBwcml2YXRlIGZsb2F0IGZsb2F0RmllbGRfID0gMEY7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmbG9hdF9maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZsb2F0RmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGbG9hdEZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZmxvYXRfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmxvYXRGaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZsb2F0RmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGZsb2F0RmllbGRfOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJTkdfRklFTERfRklFTERfTlVNQkVSID0gNDsKICAgICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBzdHJpbmdGaWVsZF8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfZmllbGQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cmluZ0ZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmdGaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nRmllbGQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJpbmdGaWVsZF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIHN0cmluZ0ZpZWxkXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfZmllbGQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cmluZ0ZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHJpbmdGaWVsZEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nRmllbGRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgc3RyaW5nRmllbGRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZUJvb2woMSwgYm9vbEZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMiwgaW50RmllbGRfKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVGbG9hdCgzLCBmbG9hdEZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA0LCBzdHJpbmdGaWVsZF8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDEsIGJvb2xGaWVsZF8pOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgyLCBpbnRGaWVsZF8pOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUZsb2F0U2l6ZSgzLCBmbG9hdEZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSg0LCBzdHJpbmdGaWVsZF8pOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgb3RoZXIgPSAocGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUpIG9iajsKCiAgICAgICAgaWYgKGhhc0Jvb2xGaWVsZCgpICE9IG90aGVyLmhhc0Jvb2xGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc0Jvb2xGaWVsZCgpKSB7CiAgICAgICAgICBpZiAoZ2V0Qm9vbEZpZWxkKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRCb29sRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzSW50RmllbGQoKSAhPSBvdGhlci5oYXNJbnRGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc0ludEZpZWxkKCkpIHsKICAgICAgICAgIGlmIChnZXRJbnRGaWVsZCgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0SW50RmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzRmxvYXRGaWVsZCgpICE9IG90aGVyLmhhc0Zsb2F0RmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNGbG9hdEZpZWxkKCkpIHsKICAgICAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0RmxvYXRGaWVsZCgpKQogICAgICAgICAgICAgICE9IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgICAgICAgb3RoZXIuZ2V0RmxvYXRGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzU3RyaW5nRmllbGQoKSAhPSBvdGhlci5oYXNTdHJpbmdGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc1N0cmluZ0ZpZWxkKCkpIHsKICAgICAgICAgIGlmICghZ2V0U3RyaW5nRmllbGQoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyaW5nRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNCb29sRmllbGQoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQk9PTF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKAogICAgICAgICAgICAgIGdldEJvb2xGaWVsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc0ludEZpZWxkKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElOVF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRJbnRGaWVsZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzRmxvYXRGaWVsZCgpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGTE9BVF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgZ2V0RmxvYXRGaWVsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc1N0cmluZ0ZpZWxkKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHJpbmdGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgICAgfQogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHBiLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cGIuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlKQogICAgICAgICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmVPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcGIuVW5pdHRlc3RGZWF0dXJlcy5pbnRlcm5hbF9zdGF0aWNfcGJfVGVzdEZlYXR1cmVzX01lc3NhZ2VGZWF0dXJlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwYi5Vbml0dGVzdEZlYXR1cmVzLmludGVybmFsX3N0YXRpY19wYl9UZXN0RmVhdHVyZXNfTWVzc2FnZUZlYXR1cmVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlLmNsYXNzLCBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZS5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGJvb2xGaWVsZF8gPSBmYWxzZTsKICAgICAgICAgIGludEZpZWxkXyA9IDA7CiAgICAgICAgICBmbG9hdEZpZWxkXyA9IDBGOwogICAgICAgICAgc3RyaW5nRmllbGRfID0gIiI7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHBiLlVuaXR0ZXN0RmVhdHVyZXMuaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RGZWF0dXJlc19NZXNzYWdlRmVhdHVyZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBidWlsZCgpIHsKICAgICAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSByZXN1bHQgPSBuZXcgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQuYm9vbEZpZWxkXyA9IGJvb2xGaWVsZF87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5pbnRGaWVsZF8gPSBpbnRGaWVsZF87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIH0KICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5mbG9hdEZpZWxkXyA9IGZsb2F0RmllbGRfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQuc3RyaW5nRmllbGRfID0gc3RyaW5nRmllbGRfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUpb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzQm9vbEZpZWxkKCkpIHsKICAgICAgICAgICAgc2V0Qm9vbEZpZWxkKG90aGVyLmdldEJvb2xGaWVsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChvdGhlci5oYXNJbnRGaWVsZCgpKSB7CiAgICAgICAgICAgIHNldEludEZpZWxkKG90aGVyLmdldEludEZpZWxkKCkpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKG90aGVyLmhhc0Zsb2F0RmllbGQoKSkgewogICAgICAgICAgICBzZXRGbG9hdEZpZWxkKG90aGVyLmdldEZsb2F0RmllbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAob3RoZXIuaGFzU3RyaW5nRmllbGQoKSkgewogICAgICAgICAgICBzdHJpbmdGaWVsZF8gPSBvdGhlci5zdHJpbmdGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgICAgYm9vbEZpZWxkXyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgICBpbnRGaWVsZF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgICAgY2FzZSAyOTogewogICAgICAgICAgICAgICAgICBmbG9hdEZpZWxkXyA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5CiAgICAgICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgICAgIHN0cmluZ0ZpZWxkXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGJvb2xlYW4gYm9vbEZpZWxkXyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBib29sX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBib29sRmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNCb29sRmllbGQoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgYm9vbF9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGJvb2xGaWVsZC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gZ2V0Qm9vbEZpZWxkKCkgewogICAgICAgICAgcmV0dXJuIGJvb2xGaWVsZF87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgYm9vbF9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYm9vbEZpZWxkIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Qm9vbEZpZWxkKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgICBib29sRmllbGRfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGJvb2xfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJCb29sRmllbGQoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBib29sRmllbGRfID0gZmFsc2U7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBpbnQgaW50RmllbGRfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludEZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzSW50RmllbGQoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9maWVsZCA9IDI7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGludEZpZWxkLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldEludEZpZWxkKCkgewogICAgICAgICAgcmV0dXJuIGludEZpZWxkXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBpbnRGaWVsZCB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEludEZpZWxkKGludCB2YWx1ZSkgewoKICAgICAgICAgIGludEZpZWxkXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50RmllbGQoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICBpbnRGaWVsZF8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgZmxvYXQgZmxvYXRGaWVsZF8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGZsb2F0X2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmbG9hdEZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmxvYXRGaWVsZCgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZmxvYXRfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBmbG9hdEZpZWxkLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmxvYXQgZ2V0RmxvYXRGaWVsZCgpIHsKICAgICAgICAgIHJldHVybiBmbG9hdEZpZWxkXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZmxvYXRfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZsb2F0RmllbGQgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGbG9hdEZpZWxkKGZsb2F0IHZhbHVlKSB7CgogICAgICAgICAgZmxvYXRGaWVsZF8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGZsb2F0X2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmxvYXRGaWVsZCgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICAgIGZsb2F0RmllbGRfID0gMEY7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHN0cmluZ0ZpZWxkXyA9ICIiOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfZmllbGQgPSA0OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cmluZ0ZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHJpbmdGaWVsZCgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19maWVsZCA9IDQ7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ0ZpZWxkLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ0ZpZWxkKCkgewogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJpbmdGaWVsZF87CiAgICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgICBzdHJpbmdGaWVsZF8gPSBzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfZmllbGQgPSA0OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyaW5nRmllbGQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgICBnZXRTdHJpbmdGaWVsZEJ5dGVzKCkgewogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJpbmdGaWVsZF87CiAgICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgICBzdHJpbmdGaWVsZF8gPSBiOwogICAgICAgICAgICByZXR1cm4gYjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfZmllbGQgPSA0OzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cmluZ0ZpZWxkIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyaW5nRmllbGQoCiAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgICBzdHJpbmdGaWVsZF8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfZmllbGQgPSA0OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdHJpbmdGaWVsZCgpIHsKICAgICAgICAgIHN0cmluZ0ZpZWxkXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cmluZ0ZpZWxkKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igc3RyaW5nRmllbGQgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHJpbmdGaWVsZEJ5dGVzKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgICBzdHJpbmdGaWVsZF8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cGIuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cGIuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2VGZWF0dXJlPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TWVzc2FnZUZlYXR1cmU+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTWVzc2FnZUZlYXR1cmUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNZXNzYWdlRmVhdHVyZT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2VGZWF0dXJlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVF9GSUxFX0ZFQVRVUkVfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IGludEZpbGVGZWF0dXJlXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9maWxlX2ZlYXR1cmUgPSAxIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRGaWxlRmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ludEZpbGVGZWF0dXJlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9maWxlX2ZlYXR1cmUgPSAxIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50RmlsZUZlYXR1cmUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50RmlsZUZlYXR1cmUoKSB7CiAgICAgIHJldHVybiBpbnRGaWxlRmVhdHVyZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UX0VYVEVOU0lPTl9SQU5HRV9GRUFUVVJFX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGludCBpbnRFeHRlbnNpb25SYW5nZUZlYXR1cmVfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2V4dGVuc2lvbl9yYW5nZV9mZWF0dXJlID0gMiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRFeHRlbnNpb25SYW5nZUZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbnRFeHRlbnNpb25SYW5nZUZlYXR1cmUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2V4dGVuc2lvbl9yYW5nZV9mZWF0dXJlID0gMiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50RXh0ZW5zaW9uUmFuZ2VGZWF0dXJlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEludEV4dGVuc2lvblJhbmdlRmVhdHVyZSgpIHsKICAgICAgcmV0dXJuIGludEV4dGVuc2lvblJhbmdlRmVhdHVyZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UX01FU1NBR0VfRkVBVFVSRV9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBpbnQgaW50TWVzc2FnZUZlYXR1cmVfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X21lc3NhZ2VfZmVhdHVyZSA9IDMgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludE1lc3NhZ2VGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzSW50TWVzc2FnZUZlYXR1cmUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X21lc3NhZ2VfZmVhdHVyZSA9IDMgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbnRNZXNzYWdlRmVhdHVyZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnRNZXNzYWdlRmVhdHVyZSgpIHsKICAgICAgcmV0dXJuIGludE1lc3NhZ2VGZWF0dXJlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlRfRklFTERfRkVBVFVSRV9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBpbnQgaW50RmllbGRGZWF0dXJlXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9maWVsZF9mZWF0dXJlID0gNCBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludEZpZWxkRmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ludEZpZWxkRmVhdHVyZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZmllbGRfZmVhdHVyZSA9IDQgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50RmllbGRGZWF0dXJlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEludEZpZWxkRmVhdHVyZSgpIHsKICAgICAgcmV0dXJuIGludEZpZWxkRmVhdHVyZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UX09ORU9GX0ZFQVRVUkVfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgaW50IGludE9uZW9mRmVhdHVyZV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfb25lb2ZfZmVhdHVyZSA9IDUgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfT05FT0YsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRPbmVvZkZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbnRPbmVvZkZlYXR1cmUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X29uZW9mX2ZlYXR1cmUgPSA1IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGludE9uZW9mRmVhdHVyZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnRPbmVvZkZlYXR1cmUoKSB7CiAgICAgIHJldHVybiBpbnRPbmVvZkZlYXR1cmVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVF9FTlVNX0ZFQVRVUkVfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgaW50IGludEVudW1GZWF0dXJlXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9lbnVtX2ZlYXR1cmUgPSA2IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU0sIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRFbnVtRmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ludEVudW1GZWF0dXJlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9lbnVtX2ZlYXR1cmUgPSA2IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU0sIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW50RW51bUZlYXR1cmUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50RW51bUZlYXR1cmUoKSB7CiAgICAgIHJldHVybiBpbnRFbnVtRmVhdHVyZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UX0VOVU1fRU5UUllfRkVBVFVSRV9GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBpbnQgaW50RW51bUVudHJ5RmVhdHVyZV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZW51bV9lbnRyeV9mZWF0dXJlID0gNyBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNX0VOVFJZLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50RW51bUVudHJ5RmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ludEVudW1FbnRyeUZlYXR1cmUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2VudW1fZW50cnlfZmVhdHVyZSA9IDcgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbnRFbnVtRW50cnlGZWF0dXJlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEludEVudW1FbnRyeUZlYXR1cmUoKSB7CiAgICAgIHJldHVybiBpbnRFbnVtRW50cnlGZWF0dXJlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTlRfU0VSVklDRV9GRUFUVVJFX0ZJRUxEX05VTUJFUiA9IDg7CiAgICBwcml2YXRlIGludCBpbnRTZXJ2aWNlRmVhdHVyZV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfc2VydmljZV9mZWF0dXJlID0gOCBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9TRVJWSUNFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50U2VydmljZUZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbnRTZXJ2aWNlRmVhdHVyZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfc2VydmljZV9mZWF0dXJlID0gOCBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9TRVJWSUNFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGludFNlcnZpY2VGZWF0dXJlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEludFNlcnZpY2VGZWF0dXJlKCkgewogICAgICByZXR1cm4gaW50U2VydmljZUZlYXR1cmVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVF9NRVRIT0RfRkVBVFVSRV9GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBpbnQgaW50TWV0aG9kRmVhdHVyZV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfbWV0aG9kX2ZlYXR1cmUgPSA5IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FVEhPRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludE1ldGhvZEZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbnRNZXRob2RGZWF0dXJlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9tZXRob2RfZmVhdHVyZSA9IDkgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVUSE9ELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGludE1ldGhvZEZlYXR1cmUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50TWV0aG9kRmVhdHVyZSgpIHsKICAgICAgcmV0dXJuIGludE1ldGhvZEZlYXR1cmVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVF9NVUxUSVBMRV9GRUFUVVJFX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgcHJpdmF0ZSBpbnQgaW50TXVsdGlwbGVGZWF0dXJlXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9tdWx0aXBsZV9mZWF0dXJlID0gMTAgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklMRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU0sIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNX0VOVFJZLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfU0VSVklDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FVEhPRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRVhURU5TSU9OX1JBTkdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50TXVsdGlwbGVGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzSW50TXVsdGlwbGVGZWF0dXJlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9tdWx0aXBsZV9mZWF0dXJlID0gMTAgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklMRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU0sIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNX0VOVFJZLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfU0VSVklDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FVEhPRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRVhURU5TSU9OX1JBTkdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGludE11bHRpcGxlRmVhdHVyZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnRNdWx0aXBsZUZlYXR1cmUoKSB7CiAgICAgIHJldHVybiBpbnRNdWx0aXBsZUZlYXR1cmVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJPT0xfRklFTERfRkVBVFVSRV9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIHByaXZhdGUgYm9vbGVhbiBib29sRmllbGRGZWF0dXJlXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGJvb2xfZmllbGRfZmVhdHVyZSA9IDExIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYm9vbEZpZWxkRmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0Jvb2xGaWVsZEZlYXR1cmUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBib29sX2ZpZWxkX2ZlYXR1cmUgPSAxMSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBib29sRmllbGRGZWF0dXJlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRCb29sRmllbGRGZWF0dXJlKCkgewogICAgICByZXR1cm4gYm9vbEZpZWxkRmVhdHVyZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRkxPQVRfRklFTERfRkVBVFVSRV9GSUVMRF9OVU1CRVIgPSAxMjsKICAgIHByaXZhdGUgZmxvYXQgZmxvYXRGaWVsZEZlYXR1cmVfID0gMEY7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGZsb2F0X2ZpZWxkX2ZlYXR1cmUgPSAxMiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZsb2F0RmllbGRGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmxvYXRGaWVsZEZlYXR1cmUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZmxvYXRfZmllbGRfZmVhdHVyZSA9IDEyIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZsb2F0RmllbGRGZWF0dXJlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0RmxvYXRGaWVsZEZlYXR1cmUoKSB7CiAgICAgIHJldHVybiBmbG9hdEZpZWxkRmVhdHVyZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUVTU0FHRV9GSUVMRF9GRUFUVVJFX0ZJRUxEX05VTUJFUiA9IDEzOwogICAgcHJpdmF0ZSBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBtZXNzYWdlRmllbGRGZWF0dXJlXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnBiLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBtZXNzYWdlX2ZpZWxkX2ZlYXR1cmUgPSAxMyBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1lc3NhZ2VGaWVsZEZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNNZXNzYWdlRmllbGRGZWF0dXJlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wYi5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgbWVzc2FnZV9maWVsZF9mZWF0dXJlID0gMTMgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbWVzc2FnZUZpZWxkRmVhdHVyZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIGdldE1lc3NhZ2VGaWVsZEZlYXR1cmUoKSB7CiAgICAgIHJldHVybiBtZXNzYWdlRmllbGRGZWF0dXJlXyA9PSBudWxsID8gcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlRmllbGRGZWF0dXJlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnBiLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBtZXNzYWdlX2ZpZWxkX2ZlYXR1cmUgPSAxMyBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZU9yQnVpbGRlciBnZXRNZXNzYWdlRmllbGRGZWF0dXJlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gbWVzc2FnZUZpZWxkRmVhdHVyZV8gPT0gbnVsbCA/IHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZUZpZWxkRmVhdHVyZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9GSUVMRF9GRUFUVVJFX0ZJRUxEX05VTUJFUiA9IDE0OwogICAgcHJpdmF0ZSBpbnQgZW51bUZpZWxkRmVhdHVyZV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucGIuVGVzdEZlYXR1cmVzLkVudW1GZWF0dXJlIGVudW1fZmllbGRfZmVhdHVyZSA9IDE0IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZW51bUZpZWxkRmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzRW51bUZpZWxkRmVhdHVyZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucGIuVGVzdEZlYXR1cmVzLkVudW1GZWF0dXJlIGVudW1fZmllbGRfZmVhdHVyZSA9IDE0IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGVudW1GaWVsZEZlYXR1cmUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLkVudW1GZWF0dXJlIGdldEVudW1GaWVsZEZlYXR1cmUoKSB7CiAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLkVudW1GZWF0dXJlIHJlc3VsdCA9IHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLkVudW1GZWF0dXJlLmZvck51bWJlcihlbnVtRmllbGRGZWF0dXJlXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLkVudW1GZWF0dXJlLlRFU1RfRU5VTV9GRUFUVVJFX1VOS05PV04gOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UX1NPVVJDRV9GRUFUVVJFX0ZJRUxEX05VTUJFUiA9IDE1OwogICAgcHJpdmF0ZSBpbnQgaW50U291cmNlRmVhdHVyZV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfc291cmNlX2ZlYXR1cmUgPSAxNSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1NPVVJDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludFNvdXJjZUZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbnRTb3VyY2VGZWF0dXJlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9zb3VyY2VfZmVhdHVyZSA9IDE1IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fU09VUkNFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklMRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU0sIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNX0VOVFJZLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfU0VSVklDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FVEhPRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRVhURU5TSU9OX1JBTkdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGludFNvdXJjZUZlYXR1cmUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50U291cmNlRmVhdHVyZSgpIHsKICAgICAgcmV0dXJuIGludFNvdXJjZUZlYXR1cmVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklOR19TT1VSQ0VfRkVBVFVSRV9GSUVMRF9OVU1CRVIgPSAxNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cmluZ1NvdXJjZUZlYXR1cmVfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfc291cmNlX2ZlYXR1cmUgPSAxNiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1NPVVJDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cmluZ1NvdXJjZUZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHJpbmdTb3VyY2VGZWF0dXJlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfc291cmNlX2ZlYXR1cmUgPSAxNiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1NPVVJDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmdTb3VyY2VGZWF0dXJlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHJpbmdTb3VyY2VGZWF0dXJlKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cmluZ1NvdXJjZUZlYXR1cmVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cmluZ1NvdXJjZUZlYXR1cmVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19zb3VyY2VfZmVhdHVyZSA9IDE2IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fU09VUkNFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklMRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU0sIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNX0VOVFJZLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfU0VSVklDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FVEhPRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRVhURU5TSU9OX1JBTkdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHJpbmdTb3VyY2VGZWF0dXJlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyaW5nU291cmNlRmVhdHVyZUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cmluZ1NvdXJjZUZlYXR1cmVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHJpbmdTb3VyY2VGZWF0dXJlXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgaW50RmlsZUZlYXR1cmVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyLCBpbnRFeHRlbnNpb25SYW5nZUZlYXR1cmVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigzLCBpbnRNZXNzYWdlRmVhdHVyZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDQsIGludEZpZWxkRmVhdHVyZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDUsIGludE9uZW9mRmVhdHVyZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDYsIGludEVudW1GZWF0dXJlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNywgaW50RW51bUVudHJ5RmVhdHVyZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDgsIGludFNlcnZpY2VGZWF0dXJlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoOSwgaW50TWV0aG9kRmVhdHVyZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEwLCBpbnRNdWx0aXBsZUZlYXR1cmVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDExLCBib29sRmllbGRGZWF0dXJlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMTIsIGZsb2F0RmllbGRGZWF0dXJlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxMywgZ2V0TWVzc2FnZUZpZWxkRmVhdHVyZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDE0LCBlbnVtRmllbGRGZWF0dXJlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMTUsIGludFNvdXJjZUZlYXR1cmVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDE2LCBzdHJpbmdTb3VyY2VGZWF0dXJlXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgaW50RmlsZUZlYXR1cmVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIsIGludEV4dGVuc2lvblJhbmdlRmVhdHVyZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMywgaW50TWVzc2FnZUZlYXR1cmVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDQsIGludEZpZWxkRmVhdHVyZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNSwgaW50T25lb2ZGZWF0dXJlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg2LCBpbnRFbnVtRmVhdHVyZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNywgaW50RW51bUVudHJ5RmVhdHVyZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoOCwgaW50U2VydmljZUZlYXR1cmVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDksIGludE1ldGhvZEZlYXR1cmVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEwLCBpbnRNdWx0aXBsZUZlYXR1cmVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQm9vbFNpemUoMTEsIGJvb2xGaWVsZEZlYXR1cmVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRmxvYXRTaXplKDEyLCBmbG9hdEZpZWxkRmVhdHVyZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMywgZ2V0TWVzc2FnZUZpZWxkRmVhdHVyZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMTQsIGVudW1GaWVsZEZlYXR1cmVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDE1LCBpbnRTb3VyY2VGZWF0dXJlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxNiwgc3RyaW5nU291cmNlRmVhdHVyZV8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcyBvdGhlciA9IChwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcykgb2JqOwoKICAgICAgaWYgKGhhc0ludEZpbGVGZWF0dXJlKCkgIT0gb3RoZXIuaGFzSW50RmlsZUZlYXR1cmUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzSW50RmlsZUZlYXR1cmUoKSkgewogICAgICAgIGlmIChnZXRJbnRGaWxlRmVhdHVyZSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEludEZpbGVGZWF0dXJlKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzSW50RXh0ZW5zaW9uUmFuZ2VGZWF0dXJlKCkgIT0gb3RoZXIuaGFzSW50RXh0ZW5zaW9uUmFuZ2VGZWF0dXJlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ludEV4dGVuc2lvblJhbmdlRmVhdHVyZSgpKSB7CiAgICAgICAgaWYgKGdldEludEV4dGVuc2lvblJhbmdlRmVhdHVyZSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEludEV4dGVuc2lvblJhbmdlRmVhdHVyZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ludE1lc3NhZ2VGZWF0dXJlKCkgIT0gb3RoZXIuaGFzSW50TWVzc2FnZUZlYXR1cmUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzSW50TWVzc2FnZUZlYXR1cmUoKSkgewogICAgICAgIGlmIChnZXRJbnRNZXNzYWdlRmVhdHVyZSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEludE1lc3NhZ2VGZWF0dXJlKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzSW50RmllbGRGZWF0dXJlKCkgIT0gb3RoZXIuaGFzSW50RmllbGRGZWF0dXJlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ludEZpZWxkRmVhdHVyZSgpKSB7CiAgICAgICAgaWYgKGdldEludEZpZWxkRmVhdHVyZSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEludEZpZWxkRmVhdHVyZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ludE9uZW9mRmVhdHVyZSgpICE9IG90aGVyLmhhc0ludE9uZW9mRmVhdHVyZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNJbnRPbmVvZkZlYXR1cmUoKSkgewogICAgICAgIGlmIChnZXRJbnRPbmVvZkZlYXR1cmUoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRJbnRPbmVvZkZlYXR1cmUoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNJbnRFbnVtRmVhdHVyZSgpICE9IG90aGVyLmhhc0ludEVudW1GZWF0dXJlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ludEVudW1GZWF0dXJlKCkpIHsKICAgICAgICBpZiAoZ2V0SW50RW51bUZlYXR1cmUoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRJbnRFbnVtRmVhdHVyZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ludEVudW1FbnRyeUZlYXR1cmUoKSAhPSBvdGhlci5oYXNJbnRFbnVtRW50cnlGZWF0dXJlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ludEVudW1FbnRyeUZlYXR1cmUoKSkgewogICAgICAgIGlmIChnZXRJbnRFbnVtRW50cnlGZWF0dXJlKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0SW50RW51bUVudHJ5RmVhdHVyZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ludFNlcnZpY2VGZWF0dXJlKCkgIT0gb3RoZXIuaGFzSW50U2VydmljZUZlYXR1cmUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzSW50U2VydmljZUZlYXR1cmUoKSkgewogICAgICAgIGlmIChnZXRJbnRTZXJ2aWNlRmVhdHVyZSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEludFNlcnZpY2VGZWF0dXJlKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzSW50TWV0aG9kRmVhdHVyZSgpICE9IG90aGVyLmhhc0ludE1ldGhvZEZlYXR1cmUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzSW50TWV0aG9kRmVhdHVyZSgpKSB7CiAgICAgICAgaWYgKGdldEludE1ldGhvZEZlYXR1cmUoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRJbnRNZXRob2RGZWF0dXJlKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzSW50TXVsdGlwbGVGZWF0dXJlKCkgIT0gb3RoZXIuaGFzSW50TXVsdGlwbGVGZWF0dXJlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ludE11bHRpcGxlRmVhdHVyZSgpKSB7CiAgICAgICAgaWYgKGdldEludE11bHRpcGxlRmVhdHVyZSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEludE11bHRpcGxlRmVhdHVyZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0Jvb2xGaWVsZEZlYXR1cmUoKSAhPSBvdGhlci5oYXNCb29sRmllbGRGZWF0dXJlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0Jvb2xGaWVsZEZlYXR1cmUoKSkgewogICAgICAgIGlmIChnZXRCb29sRmllbGRGZWF0dXJlKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0Qm9vbEZpZWxkRmVhdHVyZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0Zsb2F0RmllbGRGZWF0dXJlKCkgIT0gb3RoZXIuaGFzRmxvYXRGaWVsZEZlYXR1cmUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmxvYXRGaWVsZEZlYXR1cmUoKSkgewogICAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0RmxvYXRGaWVsZEZlYXR1cmUoKSkKICAgICAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICAgICAgb3RoZXIuZ2V0RmxvYXRGaWVsZEZlYXR1cmUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzTWVzc2FnZUZpZWxkRmVhdHVyZSgpICE9IG90aGVyLmhhc01lc3NhZ2VGaWVsZEZlYXR1cmUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTWVzc2FnZUZpZWxkRmVhdHVyZSgpKSB7CiAgICAgICAgaWYgKCFnZXRNZXNzYWdlRmllbGRGZWF0dXJlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRNZXNzYWdlRmllbGRGZWF0dXJlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0VudW1GaWVsZEZlYXR1cmUoKSAhPSBvdGhlci5oYXNFbnVtRmllbGRGZWF0dXJlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0VudW1GaWVsZEZlYXR1cmUoKSkgewogICAgICAgIGlmIChlbnVtRmllbGRGZWF0dXJlXyAhPSBvdGhlci5lbnVtRmllbGRGZWF0dXJlXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNJbnRTb3VyY2VGZWF0dXJlKCkgIT0gb3RoZXIuaGFzSW50U291cmNlRmVhdHVyZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNJbnRTb3VyY2VGZWF0dXJlKCkpIHsKICAgICAgICBpZiAoZ2V0SW50U291cmNlRmVhdHVyZSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEludFNvdXJjZUZlYXR1cmUoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHJpbmdTb3VyY2VGZWF0dXJlKCkgIT0gb3RoZXIuaGFzU3RyaW5nU291cmNlRmVhdHVyZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTdHJpbmdTb3VyY2VGZWF0dXJlKCkpIHsKICAgICAgICBpZiAoIWdldFN0cmluZ1NvdXJjZUZlYXR1cmUoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFN0cmluZ1NvdXJjZUZlYXR1cmUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNJbnRGaWxlRmVhdHVyZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UX0ZJTEVfRkVBVFVSRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0SW50RmlsZUZlYXR1cmUoKTsKICAgICAgfQogICAgICBpZiAoaGFzSW50RXh0ZW5zaW9uUmFuZ2VGZWF0dXJlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlRfRVhURU5TSU9OX1JBTkdFX0ZFQVRVUkVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEludEV4dGVuc2lvblJhbmdlRmVhdHVyZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNJbnRNZXNzYWdlRmVhdHVyZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UX01FU1NBR0VfRkVBVFVSRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0SW50TWVzc2FnZUZlYXR1cmUoKTsKICAgICAgfQogICAgICBpZiAoaGFzSW50RmllbGRGZWF0dXJlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlRfRklFTERfRkVBVFVSRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0SW50RmllbGRGZWF0dXJlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ludE9uZW9mRmVhdHVyZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UX09ORU9GX0ZFQVRVUkVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEludE9uZW9mRmVhdHVyZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNJbnRFbnVtRmVhdHVyZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UX0VOVU1fRkVBVFVSRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0SW50RW51bUZlYXR1cmUoKTsKICAgICAgfQogICAgICBpZiAoaGFzSW50RW51bUVudHJ5RmVhdHVyZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UX0VOVU1fRU5UUllfRkVBVFVSRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0SW50RW51bUVudHJ5RmVhdHVyZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNJbnRTZXJ2aWNlRmVhdHVyZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UX1NFUlZJQ0VfRkVBVFVSRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0SW50U2VydmljZUZlYXR1cmUoKTsKICAgICAgfQogICAgICBpZiAoaGFzSW50TWV0aG9kRmVhdHVyZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UX01FVEhPRF9GRUFUVVJFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRJbnRNZXRob2RGZWF0dXJlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ludE11bHRpcGxlRmVhdHVyZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UX01VTFRJUExFX0ZFQVRVUkVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEludE11bHRpcGxlRmVhdHVyZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNCb29sRmllbGRGZWF0dXJlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCT09MX0ZJRUxEX0ZFQVRVUkVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldEJvb2xGaWVsZEZlYXR1cmUoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0Zsb2F0RmllbGRGZWF0dXJlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGTE9BVF9GSUVMRF9GRUFUVVJFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgIGdldEZsb2F0RmllbGRGZWF0dXJlKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNNZXNzYWdlRmllbGRGZWF0dXJlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNRVNTQUdFX0ZJRUxEX0ZFQVRVUkVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE1lc3NhZ2VGaWVsZEZlYXR1cmUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNFbnVtRmllbGRGZWF0dXJlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBFTlVNX0ZJRUxEX0ZFQVRVUkVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGVudW1GaWVsZEZlYXR1cmVfOwogICAgICB9CiAgICAgIGlmIChoYXNJbnRTb3VyY2VGZWF0dXJlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTlRfU09VUkNFX0ZFQVRVUkVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEludFNvdXJjZUZlYXR1cmUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyaW5nU291cmNlRmVhdHVyZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSSU5HX1NPVVJDRV9GRUFUVVJFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHJpbmdTb3VyY2VGZWF0dXJlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwYi5UZXN0RmVhdHVyZXN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwYi5UZXN0RmVhdHVyZXMpCiAgICAgICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcGIuVW5pdHRlc3RGZWF0dXJlcy5pbnRlcm5hbF9zdGF0aWNfcGJfVGVzdEZlYXR1cmVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHBiLlVuaXR0ZXN0RmVhdHVyZXMuaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RGZWF0dXJlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5jbGFzcywgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRNZXNzYWdlRmllbGRGZWF0dXJlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRGaWxlRmVhdHVyZV8gPSAwOwogICAgICAgIGludEV4dGVuc2lvblJhbmdlRmVhdHVyZV8gPSAwOwogICAgICAgIGludE1lc3NhZ2VGZWF0dXJlXyA9IDA7CiAgICAgICAgaW50RmllbGRGZWF0dXJlXyA9IDA7CiAgICAgICAgaW50T25lb2ZGZWF0dXJlXyA9IDA7CiAgICAgICAgaW50RW51bUZlYXR1cmVfID0gMDsKICAgICAgICBpbnRFbnVtRW50cnlGZWF0dXJlXyA9IDA7CiAgICAgICAgaW50U2VydmljZUZlYXR1cmVfID0gMDsKICAgICAgICBpbnRNZXRob2RGZWF0dXJlXyA9IDA7CiAgICAgICAgaW50TXVsdGlwbGVGZWF0dXJlXyA9IDA7CiAgICAgICAgYm9vbEZpZWxkRmVhdHVyZV8gPSBmYWxzZTsKICAgICAgICBmbG9hdEZpZWxkRmVhdHVyZV8gPSAwRjsKICAgICAgICBtZXNzYWdlRmllbGRGZWF0dXJlXyA9IG51bGw7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZEZlYXR1cmVCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBtZXNzYWdlRmllbGRGZWF0dXJlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgbWVzc2FnZUZpZWxkRmVhdHVyZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZW51bUZpZWxkRmVhdHVyZV8gPSAwOwogICAgICAgIGludFNvdXJjZUZlYXR1cmVfID0gMDsKICAgICAgICBzdHJpbmdTb3VyY2VGZWF0dXJlXyA9ICIiOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwYi5Vbml0dGVzdEZlYXR1cmVzLmludGVybmFsX3N0YXRpY19wYl9UZXN0RmVhdHVyZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzIGJ1aWxkKCkgewogICAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzIHJlc3VsdCA9IG5ldyBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnRGaWxlRmVhdHVyZV8gPSBpbnRGaWxlRmVhdHVyZV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaW50RXh0ZW5zaW9uUmFuZ2VGZWF0dXJlXyA9IGludEV4dGVuc2lvblJhbmdlRmVhdHVyZV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaW50TWVzc2FnZUZlYXR1cmVfID0gaW50TWVzc2FnZUZlYXR1cmVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludEZpZWxkRmVhdHVyZV8gPSBpbnRGaWVsZEZlYXR1cmVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludE9uZW9mRmVhdHVyZV8gPSBpbnRPbmVvZkZlYXR1cmVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludEVudW1GZWF0dXJlXyA9IGludEVudW1GZWF0dXJlXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnRFbnVtRW50cnlGZWF0dXJlXyA9IGludEVudW1FbnRyeUZlYXR1cmVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludFNlcnZpY2VGZWF0dXJlXyA9IGludFNlcnZpY2VGZWF0dXJlXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnRNZXRob2RGZWF0dXJlXyA9IGludE1ldGhvZEZlYXR1cmVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludE11bHRpcGxlRmVhdHVyZV8gPSBpbnRNdWx0aXBsZUZlYXR1cmVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmJvb2xGaWVsZEZlYXR1cmVfID0gYm9vbEZpZWxkRmVhdHVyZV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmxvYXRGaWVsZEZlYXR1cmVfID0gZmxvYXRGaWVsZEZlYXR1cmVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1lc3NhZ2VGaWVsZEZlYXR1cmVfID0gbWVzc2FnZUZpZWxkRmVhdHVyZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG1lc3NhZ2VGaWVsZEZlYXR1cmVfCiAgICAgICAgICAgICAgOiBtZXNzYWdlRmllbGRGZWF0dXJlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5lbnVtRmllbGRGZWF0dXJlXyA9IGVudW1GaWVsZEZlYXR1cmVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmludFNvdXJjZUZlYXR1cmVfID0gaW50U291cmNlRmVhdHVyZV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyaW5nU291cmNlRmVhdHVyZV8gPSBzdHJpbmdTb3VyY2VGZWF0dXJlXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0ludEZpbGVGZWF0dXJlKCkpIHsKICAgICAgICAgIHNldEludEZpbGVGZWF0dXJlKG90aGVyLmdldEludEZpbGVGZWF0dXJlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzSW50RXh0ZW5zaW9uUmFuZ2VGZWF0dXJlKCkpIHsKICAgICAgICAgIHNldEludEV4dGVuc2lvblJhbmdlRmVhdHVyZShvdGhlci5nZXRJbnRFeHRlbnNpb25SYW5nZUZlYXR1cmUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNJbnRNZXNzYWdlRmVhdHVyZSgpKSB7CiAgICAgICAgICBzZXRJbnRNZXNzYWdlRmVhdHVyZShvdGhlci5nZXRJbnRNZXNzYWdlRmVhdHVyZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ludEZpZWxkRmVhdHVyZSgpKSB7CiAgICAgICAgICBzZXRJbnRGaWVsZEZlYXR1cmUob3RoZXIuZ2V0SW50RmllbGRGZWF0dXJlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzSW50T25lb2ZGZWF0dXJlKCkpIHsKICAgICAgICAgIHNldEludE9uZW9mRmVhdHVyZShvdGhlci5nZXRJbnRPbmVvZkZlYXR1cmUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNJbnRFbnVtRmVhdHVyZSgpKSB7CiAgICAgICAgICBzZXRJbnRFbnVtRmVhdHVyZShvdGhlci5nZXRJbnRFbnVtRmVhdHVyZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ludEVudW1FbnRyeUZlYXR1cmUoKSkgewogICAgICAgICAgc2V0SW50RW51bUVudHJ5RmVhdHVyZShvdGhlci5nZXRJbnRFbnVtRW50cnlGZWF0dXJlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzSW50U2VydmljZUZlYXR1cmUoKSkgewogICAgICAgICAgc2V0SW50U2VydmljZUZlYXR1cmUob3RoZXIuZ2V0SW50U2VydmljZUZlYXR1cmUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNJbnRNZXRob2RGZWF0dXJlKCkpIHsKICAgICAgICAgIHNldEludE1ldGhvZEZlYXR1cmUob3RoZXIuZ2V0SW50TWV0aG9kRmVhdHVyZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ludE11bHRpcGxlRmVhdHVyZSgpKSB7CiAgICAgICAgICBzZXRJbnRNdWx0aXBsZUZlYXR1cmUob3RoZXIuZ2V0SW50TXVsdGlwbGVGZWF0dXJlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzQm9vbEZpZWxkRmVhdHVyZSgpKSB7CiAgICAgICAgICBzZXRCb29sRmllbGRGZWF0dXJlKG90aGVyLmdldEJvb2xGaWVsZEZlYXR1cmUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGbG9hdEZpZWxkRmVhdHVyZSgpKSB7CiAgICAgICAgICBzZXRGbG9hdEZpZWxkRmVhdHVyZShvdGhlci5nZXRGbG9hdEZpZWxkRmVhdHVyZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc01lc3NhZ2VGaWVsZEZlYXR1cmUoKSkgewogICAgICAgICAgbWVyZ2VNZXNzYWdlRmllbGRGZWF0dXJlKG90aGVyLmdldE1lc3NhZ2VGaWVsZEZlYXR1cmUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNFbnVtRmllbGRGZWF0dXJlKCkpIHsKICAgICAgICAgIHNldEVudW1GaWVsZEZlYXR1cmUob3RoZXIuZ2V0RW51bUZpZWxkRmVhdHVyZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ludFNvdXJjZUZlYXR1cmUoKSkgewogICAgICAgICAgc2V0SW50U291cmNlRmVhdHVyZShvdGhlci5nZXRJbnRTb3VyY2VGZWF0dXJlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyaW5nU291cmNlRmVhdHVyZSgpKSB7CiAgICAgICAgICBzdHJpbmdTb3VyY2VGZWF0dXJlXyA9IG90aGVyLnN0cmluZ1NvdXJjZUZlYXR1cmVfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgaW50RmlsZUZlYXR1cmVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIGludEV4dGVuc2lvblJhbmdlRmVhdHVyZV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMjQ6IHsKICAgICAgICAgICAgICAgIGludE1lc3NhZ2VGZWF0dXJlXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgICAgY2FzZSAzMjogewogICAgICAgICAgICAgICAgaW50RmllbGRGZWF0dXJlXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyCiAgICAgICAgICAgICAgY2FzZSA0MDogewogICAgICAgICAgICAgICAgaW50T25lb2ZGZWF0dXJlXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQwCiAgICAgICAgICAgICAgY2FzZSA0ODogewogICAgICAgICAgICAgICAgaW50RW51bUZlYXR1cmVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDgKICAgICAgICAgICAgICBjYXNlIDU2OiB7CiAgICAgICAgICAgICAgICBpbnRFbnVtRW50cnlGZWF0dXJlXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU2CiAgICAgICAgICAgICAgY2FzZSA2NDogewogICAgICAgICAgICAgICAgaW50U2VydmljZUZlYXR1cmVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjQKICAgICAgICAgICAgICBjYXNlIDcyOiB7CiAgICAgICAgICAgICAgICBpbnRNZXRob2RGZWF0dXJlXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDcyCiAgICAgICAgICAgICAgY2FzZSA4MDogewogICAgICAgICAgICAgICAgaW50TXVsdGlwbGVGZWF0dXJlXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwCiAgICAgICAgICAgICAgY2FzZSA4ODogewogICAgICAgICAgICAgICAgYm9vbEZpZWxkRmVhdHVyZV8gPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDg4CiAgICAgICAgICAgICAgY2FzZSAxMDE6IHsKICAgICAgICAgICAgICAgIGZsb2F0RmllbGRGZWF0dXJlXyA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwMQogICAgICAgICAgICAgIGNhc2UgMTA2OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRNZXNzYWdlRmllbGRGZWF0dXJlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDYKICAgICAgICAgICAgICBjYXNlIDExMjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5FbnVtRmVhdHVyZSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuRW51bUZlYXR1cmUuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxNCwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVudW1GaWVsZEZlYXR1cmVfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTEyCiAgICAgICAgICAgICAgY2FzZSAxMjA6IHsKICAgICAgICAgICAgICAgIGludFNvdXJjZUZlYXR1cmVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIwCiAgICAgICAgICAgICAgY2FzZSAxMzA6IHsKICAgICAgICAgICAgICAgIHN0cmluZ1NvdXJjZUZlYXR1cmVfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTMwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGludEZpbGVGZWF0dXJlXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZmlsZV9mZWF0dXJlID0gMSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUxFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRGaWxlRmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ludEZpbGVGZWF0dXJlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2ZpbGVfZmVhdHVyZSA9IDEgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklMRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGludEZpbGVGZWF0dXJlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludEZpbGVGZWF0dXJlKCkgewogICAgICAgIHJldHVybiBpbnRGaWxlRmVhdHVyZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9maWxlX2ZlYXR1cmUgPSAxIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGludEZpbGVGZWF0dXJlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SW50RmlsZUZlYXR1cmUoaW50IHZhbHVlKSB7CgogICAgICAgIGludEZpbGVGZWF0dXJlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2ZpbGVfZmVhdHVyZSA9IDEgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklMRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50RmlsZUZlYXR1cmUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludEZpbGVGZWF0dXJlXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGludEV4dGVuc2lvblJhbmdlRmVhdHVyZV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2V4dGVuc2lvbl9yYW5nZV9mZWF0dXJlID0gMiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludEV4dGVuc2lvblJhbmdlRmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ludEV4dGVuc2lvblJhbmdlRmVhdHVyZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9leHRlbnNpb25fcmFuZ2VfZmVhdHVyZSA9IDIgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRVhURU5TSU9OX1JBTkdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgaW50RXh0ZW5zaW9uUmFuZ2VGZWF0dXJlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludEV4dGVuc2lvblJhbmdlRmVhdHVyZSgpIHsKICAgICAgICByZXR1cm4gaW50RXh0ZW5zaW9uUmFuZ2VGZWF0dXJlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2V4dGVuc2lvbl9yYW5nZV9mZWF0dXJlID0gMiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGludEV4dGVuc2lvblJhbmdlRmVhdHVyZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEludEV4dGVuc2lvblJhbmdlRmVhdHVyZShpbnQgdmFsdWUpIHsKCiAgICAgICAgaW50RXh0ZW5zaW9uUmFuZ2VGZWF0dXJlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2V4dGVuc2lvbl9yYW5nZV9mZWF0dXJlID0gMiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludEV4dGVuc2lvblJhbmdlRmVhdHVyZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50RXh0ZW5zaW9uUmFuZ2VGZWF0dXJlXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGludE1lc3NhZ2VGZWF0dXJlXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfbWVzc2FnZV9mZWF0dXJlID0gMyBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVNTQUdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRNZXNzYWdlRmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ludE1lc3NhZ2VGZWF0dXJlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X21lc3NhZ2VfZmVhdHVyZSA9IDMgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGludE1lc3NhZ2VGZWF0dXJlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludE1lc3NhZ2VGZWF0dXJlKCkgewogICAgICAgIHJldHVybiBpbnRNZXNzYWdlRmVhdHVyZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9tZXNzYWdlX2ZlYXR1cmUgPSAzIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGludE1lc3NhZ2VGZWF0dXJlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SW50TWVzc2FnZUZlYXR1cmUoaW50IHZhbHVlKSB7CgogICAgICAgIGludE1lc3NhZ2VGZWF0dXJlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X21lc3NhZ2VfZmVhdHVyZSA9IDMgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50TWVzc2FnZUZlYXR1cmUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGludE1lc3NhZ2VGZWF0dXJlXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGludEZpZWxkRmVhdHVyZV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2ZpZWxkX2ZlYXR1cmUgPSA0IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRGaWVsZEZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbnRGaWVsZEZlYXR1cmUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZmllbGRfZmVhdHVyZSA9IDQgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBpbnRGaWVsZEZlYXR1cmUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50RmllbGRGZWF0dXJlKCkgewogICAgICAgIHJldHVybiBpbnRGaWVsZEZlYXR1cmVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZmllbGRfZmVhdHVyZSA9IDQgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGludEZpZWxkRmVhdHVyZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEludEZpZWxkRmVhdHVyZShpbnQgdmFsdWUpIHsKCiAgICAgICAgaW50RmllbGRGZWF0dXJlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2ZpZWxkX2ZlYXR1cmUgPSA0IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnRGaWVsZEZlYXR1cmUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGludEZpZWxkRmVhdHVyZV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBpbnRPbmVvZkZlYXR1cmVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9vbmVvZl9mZWF0dXJlID0gNSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50T25lb2ZGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzSW50T25lb2ZGZWF0dXJlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X29uZW9mX2ZlYXR1cmUgPSA1IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgaW50T25lb2ZGZWF0dXJlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludE9uZW9mRmVhdHVyZSgpIHsKICAgICAgICByZXR1cm4gaW50T25lb2ZGZWF0dXJlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X29uZW9mX2ZlYXR1cmUgPSA1IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBpbnRPbmVvZkZlYXR1cmUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRJbnRPbmVvZkZlYXR1cmUoaW50IHZhbHVlKSB7CgogICAgICAgIGludE9uZW9mRmVhdHVyZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9vbmVvZl9mZWF0dXJlID0gNSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50T25lb2ZGZWF0dXJlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRPbmVvZkZlYXR1cmVfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgaW50RW51bUZlYXR1cmVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9lbnVtX2ZlYXR1cmUgPSA2IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU0sIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludEVudW1GZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzSW50RW51bUZlYXR1cmUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZW51bV9mZWF0dXJlID0gNiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgaW50RW51bUZlYXR1cmUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50RW51bUZlYXR1cmUoKSB7CiAgICAgICAgcmV0dXJuIGludEVudW1GZWF0dXJlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2VudW1fZmVhdHVyZSA9IDYgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgaW50RW51bUZlYXR1cmUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRJbnRFbnVtRmVhdHVyZShpbnQgdmFsdWUpIHsKCiAgICAgICAgaW50RW51bUZlYXR1cmVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZW51bV9mZWF0dXJlID0gNiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnRFbnVtRmVhdHVyZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50RW51bUZlYXR1cmVfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgaW50RW51bUVudHJ5RmVhdHVyZV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2VudW1fZW50cnlfZmVhdHVyZSA9IDcgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50RW51bUVudHJ5RmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ludEVudW1FbnRyeUZlYXR1cmUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZW51bV9lbnRyeV9mZWF0dXJlID0gNyBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNX0VOVFJZLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgaW50RW51bUVudHJ5RmVhdHVyZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnRFbnVtRW50cnlGZWF0dXJlKCkgewogICAgICAgIHJldHVybiBpbnRFbnVtRW50cnlGZWF0dXJlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X2VudW1fZW50cnlfZmVhdHVyZSA9IDcgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgaW50RW51bUVudHJ5RmVhdHVyZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEludEVudW1FbnRyeUZlYXR1cmUoaW50IHZhbHVlKSB7CgogICAgICAgIGludEVudW1FbnRyeUZlYXR1cmVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfZW51bV9lbnRyeV9mZWF0dXJlID0gNyBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNX0VOVFJZLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnRFbnVtRW50cnlGZWF0dXJlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRFbnVtRW50cnlGZWF0dXJlXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGludFNlcnZpY2VGZWF0dXJlXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfc2VydmljZV9mZWF0dXJlID0gOCBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9TRVJWSUNFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRTZXJ2aWNlRmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ludFNlcnZpY2VGZWF0dXJlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X3NlcnZpY2VfZmVhdHVyZSA9IDggW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfU0VSVklDRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGludFNlcnZpY2VGZWF0dXJlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEludFNlcnZpY2VGZWF0dXJlKCkgewogICAgICAgIHJldHVybiBpbnRTZXJ2aWNlRmVhdHVyZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9zZXJ2aWNlX2ZlYXR1cmUgPSA4IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGludFNlcnZpY2VGZWF0dXJlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SW50U2VydmljZUZlYXR1cmUoaW50IHZhbHVlKSB7CgogICAgICAgIGludFNlcnZpY2VGZWF0dXJlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X3NlcnZpY2VfZmVhdHVyZSA9IDggW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfU0VSVklDRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50U2VydmljZUZlYXR1cmUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludFNlcnZpY2VGZWF0dXJlXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGludE1ldGhvZEZlYXR1cmVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9tZXRob2RfZmVhdHVyZSA9IDkgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVUSE9ELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRNZXRob2RGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzSW50TWV0aG9kRmVhdHVyZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9tZXRob2RfZmVhdHVyZSA9IDkgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVUSE9ELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgaW50TWV0aG9kRmVhdHVyZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnRNZXRob2RGZWF0dXJlKCkgewogICAgICAgIHJldHVybiBpbnRNZXRob2RGZWF0dXJlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X21ldGhvZF9mZWF0dXJlID0gOSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGludE1ldGhvZEZlYXR1cmUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRJbnRNZXRob2RGZWF0dXJlKGludCB2YWx1ZSkgewoKICAgICAgICBpbnRNZXRob2RGZWF0dXJlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X21ldGhvZF9mZWF0dXJlID0gOSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckludE1ldGhvZEZlYXR1cmUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludE1ldGhvZEZlYXR1cmVfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgaW50TXVsdGlwbGVGZWF0dXJlXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfbXVsdGlwbGVfZmVhdHVyZSA9IDEwIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50TXVsdGlwbGVGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzSW50TXVsdGlwbGVGZWF0dXJlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaW50X211bHRpcGxlX2ZlYXR1cmUgPSAxMCBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUxFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVNTQUdFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU1fRU5UUlksIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9TRVJWSUNFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVUSE9ELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfT05FT0YsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBpbnRNdWx0aXBsZUZlYXR1cmUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50TXVsdGlwbGVGZWF0dXJlKCkgewogICAgICAgIHJldHVybiBpbnRNdWx0aXBsZUZlYXR1cmVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfbXVsdGlwbGVfZmVhdHVyZSA9IDEwIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgaW50TXVsdGlwbGVGZWF0dXJlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SW50TXVsdGlwbGVGZWF0dXJlKGludCB2YWx1ZSkgewoKICAgICAgICBpbnRNdWx0aXBsZUZlYXR1cmVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfbXVsdGlwbGVfZmVhdHVyZSA9IDEwIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50TXVsdGlwbGVGZWF0dXJlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRNdWx0aXBsZUZlYXR1cmVfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBib29sZWFuIGJvb2xGaWVsZEZlYXR1cmVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgYm9vbF9maWVsZF9mZWF0dXJlID0gMTEgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJvb2xGaWVsZEZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNCb29sRmllbGRGZWF0dXJlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBib29sX2ZpZWxkX2ZlYXR1cmUgPSAxMSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJvb2xGaWVsZEZlYXR1cmUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldEJvb2xGaWVsZEZlYXR1cmUoKSB7CiAgICAgICAgcmV0dXJuIGJvb2xGaWVsZEZlYXR1cmVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGJvb2xfZmllbGRfZmVhdHVyZSA9IDExIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBib29sRmllbGRGZWF0dXJlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Qm9vbEZpZWxkRmVhdHVyZShib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGJvb2xGaWVsZEZlYXR1cmVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGJvb2xfZmllbGRfZmVhdHVyZSA9IDExIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJCb29sRmllbGRGZWF0dXJlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBib29sRmllbGRGZWF0dXJlXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IGZsb2F0RmllbGRGZWF0dXJlXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmbG9hdF9maWVsZF9mZWF0dXJlID0gMTIgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZsb2F0RmllbGRGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmxvYXRGaWVsZEZlYXR1cmUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmbG9hdF9maWVsZF9mZWF0dXJlID0gMTIgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmbG9hdEZpZWxkRmVhdHVyZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEZsb2F0RmllbGRGZWF0dXJlKCkgewogICAgICAgIHJldHVybiBmbG9hdEZpZWxkRmVhdHVyZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGZsb2F0X2ZpZWxkX2ZlYXR1cmUgPSAxMiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmxvYXRGaWVsZEZlYXR1cmUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGbG9hdEZpZWxkRmVhdHVyZShmbG9hdCB2YWx1ZSkgewoKICAgICAgICBmbG9hdEZpZWxkRmVhdHVyZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGZsb2F0X2ZpZWxkX2ZlYXR1cmUgPSAxMiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmxvYXRGaWVsZEZlYXR1cmUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGZsb2F0RmllbGRGZWF0dXJlXyA9IDBGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIG1lc3NhZ2VGaWVsZEZlYXR1cmVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSwgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUuQnVpbGRlciwgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmVPckJ1aWxkZXI+IG1lc3NhZ2VGaWVsZEZlYXR1cmVCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wYi5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgbWVzc2FnZV9maWVsZF9mZWF0dXJlID0gMTMgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1lc3NhZ2VGaWVsZEZlYXR1cmUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTWVzc2FnZUZpZWxkRmVhdHVyZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wYi5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgbWVzc2FnZV9maWVsZF9mZWF0dXJlID0gMTMgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlRmllbGRGZWF0dXJlLgogICAgICAgKi8KICAgICAgcHVibGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIGdldE1lc3NhZ2VGaWVsZEZlYXR1cmUoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZEZlYXR1cmVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkRmVhdHVyZV8gPT0gbnVsbCA/IHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZUZpZWxkRmVhdHVyZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlRmllbGRGZWF0dXJlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnBiLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBtZXNzYWdlX2ZpZWxkX2ZlYXR1cmUgPSAxMyBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNZXNzYWdlRmllbGRGZWF0dXJlKHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZEZlYXR1cmVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG1lc3NhZ2VGaWVsZEZlYXR1cmVfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZEZlYXR1cmVCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucGIuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIG1lc3NhZ2VfZmllbGRfZmVhdHVyZSA9IDEzIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE1lc3NhZ2VGaWVsZEZlYXR1cmUoCiAgICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChtZXNzYWdlRmllbGRGZWF0dXJlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZUZpZWxkRmVhdHVyZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUZpZWxkRmVhdHVyZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wYi5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgbWVzc2FnZV9maWVsZF9mZWF0dXJlID0gMTMgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VNZXNzYWdlRmllbGRGZWF0dXJlKHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZEZlYXR1cmVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgbWVzc2FnZUZpZWxkRmVhdHVyZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBtZXNzYWdlRmllbGRGZWF0dXJlXyAhPSBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRNZXNzYWdlRmllbGRGZWF0dXJlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBtZXNzYWdlRmllbGRGZWF0dXJlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlRmllbGRGZWF0dXJlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZEZlYXR1cmVfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnBiLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBtZXNzYWdlX2ZpZWxkX2ZlYXR1cmUgPSAxMyBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1lc3NhZ2VGaWVsZEZlYXR1cmUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG1lc3NhZ2VGaWVsZEZlYXR1cmVfID0gbnVsbDsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkRmVhdHVyZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZEZlYXR1cmVCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBtZXNzYWdlRmllbGRGZWF0dXJlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnBiLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZSBtZXNzYWdlX2ZpZWxkX2ZlYXR1cmUgPSAxMyBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUuQnVpbGRlciBnZXRNZXNzYWdlRmllbGRGZWF0dXJlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE1lc3NhZ2VGaWVsZEZlYXR1cmVGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wYi5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUgbWVzc2FnZV9maWVsZF9mZWF0dXJlID0gMTMgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlT3JCdWlsZGVyIGdldE1lc3NhZ2VGaWVsZEZlYXR1cmVPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZEZlYXR1cmVCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkRmVhdHVyZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VGaWVsZEZlYXR1cmVfID09IG51bGwgPwogICAgICAgICAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZUZpZWxkRmVhdHVyZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucGIuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlIG1lc3NhZ2VfZmllbGRfZmVhdHVyZSA9IDEzIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlLCBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZS5CdWlsZGVyLCBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5NZXNzYWdlRmVhdHVyZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRNZXNzYWdlRmllbGRGZWF0dXJlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChtZXNzYWdlRmllbGRGZWF0dXJlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZUZpZWxkRmVhdHVyZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuTWVzc2FnZUZlYXR1cmUsIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlLkJ1aWxkZXIsIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLk1lc3NhZ2VGZWF0dXJlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZUZpZWxkRmVhdHVyZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgbWVzc2FnZUZpZWxkRmVhdHVyZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkRmVhdHVyZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBlbnVtRmllbGRGZWF0dXJlXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucGIuVGVzdEZlYXR1cmVzLkVudW1GZWF0dXJlIGVudW1fZmllbGRfZmVhdHVyZSA9IDE0IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBlbnVtRmllbGRGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzRW51bUZpZWxkRmVhdHVyZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wYi5UZXN0RmVhdHVyZXMuRW51bUZlYXR1cmUgZW51bV9maWVsZF9mZWF0dXJlID0gMTQgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtRmllbGRGZWF0dXJlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMuRW51bUZlYXR1cmUgZ2V0RW51bUZpZWxkRmVhdHVyZSgpIHsKICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5FbnVtRmVhdHVyZSByZXN1bHQgPSBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5FbnVtRmVhdHVyZS5mb3JOdW1iZXIoZW51bUZpZWxkRmVhdHVyZV8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLkVudW1GZWF0dXJlLlRFU1RfRU5VTV9GRUFUVVJFX1VOS05PV04gOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wYi5UZXN0RmVhdHVyZXMuRW51bUZlYXR1cmUgZW51bV9maWVsZF9mZWF0dXJlID0gMTQgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW1GaWVsZEZlYXR1cmUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRFbnVtRmllbGRGZWF0dXJlKHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzLkVudW1GZWF0dXJlIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgZW51bUZpZWxkRmVhdHVyZV8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnBiLlRlc3RGZWF0dXJlcy5FbnVtRmVhdHVyZSBlbnVtX2ZpZWxkX2ZlYXR1cmUgPSAxNCBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRW51bUZpZWxkRmVhdHVyZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgZW51bUZpZWxkRmVhdHVyZV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBpbnRTb3VyY2VGZWF0dXJlXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfc291cmNlX2ZlYXR1cmUgPSAxNSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1NPVVJDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW50U291cmNlRmVhdHVyZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ludFNvdXJjZUZlYXR1cmUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpbnRfc291cmNlX2ZlYXR1cmUgPSAxNSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1NPVVJDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGludFNvdXJjZUZlYXR1cmUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0SW50U291cmNlRmVhdHVyZSgpIHsKICAgICAgICByZXR1cm4gaW50U291cmNlRmVhdHVyZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9zb3VyY2VfZmVhdHVyZSA9IDE1IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fU09VUkNFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklMRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU0sIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNX0VOVFJZLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfU0VSVklDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FVEhPRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRVhURU5TSU9OX1JBTkdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBpbnRTb3VyY2VGZWF0dXJlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SW50U291cmNlRmVhdHVyZShpbnQgdmFsdWUpIHsKCiAgICAgICAgaW50U291cmNlRmVhdHVyZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGludF9zb3VyY2VfZmVhdHVyZSA9IDE1IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fU09VUkNFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklMRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU0sIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNX0VOVFJZLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfU0VSVklDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FVEhPRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRVhURU5TSU9OX1JBTkdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbnRTb3VyY2VGZWF0dXJlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBpbnRTb3VyY2VGZWF0dXJlXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBzdHJpbmdTb3VyY2VGZWF0dXJlXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19zb3VyY2VfZmVhdHVyZSA9IDE2IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fU09VUkNFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklMRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU0sIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNX0VOVFJZLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfU0VSVklDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FVEhPRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRVhURU5TSU9OX1JBTkdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdTb3VyY2VGZWF0dXJlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cmluZ1NvdXJjZUZlYXR1cmUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX3NvdXJjZV9mZWF0dXJlID0gMTYgW3JldGVudGlvbiA9IFJFVEVOVElPTl9TT1VSQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUxFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVNTQUdFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU1fRU5UUlksIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9TRVJWSUNFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVUSE9ELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfT05FT0YsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmdTb3VyY2VGZWF0dXJlLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nU291cmNlRmVhdHVyZSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cmluZ1NvdXJjZUZlYXR1cmVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgc3RyaW5nU291cmNlRmVhdHVyZV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19zb3VyY2VfZmVhdHVyZSA9IDE2IFtyZXRlbnRpb24gPSBSRVRFTlRJT05fU09VUkNFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklMRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVTU0FHRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU0sIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNX0VOVFJZLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfU0VSVklDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FVEhPRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX09ORU9GLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRVhURU5TSU9OX1JBTkdFLCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cmluZ1NvdXJjZUZlYXR1cmUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHJpbmdTb3VyY2VGZWF0dXJlQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJpbmdTb3VyY2VGZWF0dXJlXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgc3RyaW5nU291cmNlRmVhdHVyZV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX3NvdXJjZV9mZWF0dXJlID0gMTYgW3JldGVudGlvbiA9IFJFVEVOVElPTl9TT1VSQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUxFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVNTQUdFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VOVU1fRU5UUlksIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9TRVJWSUNFLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfTUVUSE9ELCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfT05FT0YsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cmluZ1NvdXJjZUZlYXR1cmUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHJpbmdTb3VyY2VGZWF0dXJlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyaW5nU291cmNlRmVhdHVyZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfc291cmNlX2ZlYXR1cmUgPSAxNiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1NPVVJDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyaW5nU291cmNlRmVhdHVyZSgpIHsKICAgICAgICBzdHJpbmdTb3VyY2VGZWF0dXJlXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cmluZ1NvdXJjZUZlYXR1cmUoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfc291cmNlX2ZlYXR1cmUgPSAxNiBbcmV0ZW50aW9uID0gUkVURU5USU9OX1NPVVJDRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJTEUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX01FU1NBR0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9FTlVNLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRU5VTV9FTlRSWSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX1NFUlZJQ0UsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9NRVRIT0QsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9PTkVPRiwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRSwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cmluZ1NvdXJjZUZlYXR1cmUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHJpbmdTb3VyY2VGZWF0dXJlQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cmluZ1NvdXJjZUZlYXR1cmVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnBiLlRlc3RGZWF0dXJlcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cGIuVGVzdEZlYXR1cmVzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcGIuVW5pdHRlc3RGZWF0dXJlcy5UZXN0RmVhdHVyZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEZlYXR1cmVzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RGZWF0dXJlcz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RGZWF0dXJlcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RGZWF0dXJlcz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RmVhdHVyZXM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRFU1RfRklFTERfTlVNQkVSID0gOTk5OTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0IHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZlYXR1cmVTZXQsCiAgICAgIHBiLlVuaXR0ZXN0RmVhdHVyZXMuVGVzdEZlYXR1cmVzPiB0ZXN0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5jbGFzcywKICAgICAgICBwYi5Vbml0dGVzdEZlYXR1cmVzLlRlc3RGZWF0dXJlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcGJfVGVzdE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcGJfVGVzdE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RNZXNzYWdlX05lc3RlZF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wYl9UZXN0TWVzc2FnZV9OZXN0ZWRfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RGZWF0dXJlc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wYl9UZXN0RmVhdHVyZXNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RGZWF0dXJlc19NZXNzYWdlRmVhdHVyZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wYl9UZXN0RmVhdHVyZXNfTWVzc2FnZUZlYXR1cmVfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcblwnZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ZlYXR1cmVzLnByb3QiICsKICAgICAgIm9cMDIyXDAwMnBiXDAzMiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90b1wiIiArCiAgICAgICJcMjQyXDAwMVxuXDAxM1Rlc3RNZXNzYWdlXDAzMk1cblwwMDZOZXN0ZWQyQ1xuXDAxM3Rlc3RfbmVzdGVkIiArCiAgICAgICJcMDIyXDAzMy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldFwwMzBcMjE1TiBcMDAxKFwwMTMyXDAyMC5wIiArCiAgICAgICJiLlRlc3RGZWF0dXJlczJEXG5cMDE0dGVzdF9tZXNzYWdlXDAyMlwwMzMuZ29vZ2xlLiIgKwogICAgICAicHJvdG9idWYuRmVhdHVyZVNldFwwMzBcMjE2TiBcMDAxKFwwMTMyXDAyMC5wYi5UZXN0RmVhdCIgKwogICAgICAidXJlc1wiXDM3NVxuXG5cMDE0VGVzdEZlYXR1cmVzXDAyMlFcblwwMjBpbnRfZmlsZV9mZWF0dXIiICsKICAgICAgImVcMDMwXDAwMSBcMDAxKFwwMDVCN1wyMTBcMDAxXDAwMVwyMzBcMDAxXDAwMVwyNDJcMDAxXDAwN1wwMjJcMDAyLTJcMDMwXDM0NlwwMDdcMjQyXDAwMVwwMDdcMDIyXDAwMi0zXDAzMFwzNDdcMDA3XDI0MlwwMDFcMDA2XDAyMlwwMDEiICsKICAgICAgIjFcMDMwXDM1MFwwMDdcMjQyXDAwMVwwMDdcMDIyXDAwMTJcMDMwXDIzNVwyMTVcMDA2XDI0MlwwMDFcMDA3XDAyMlwwMDEzXDAzMFwyMzZcMjE1XDAwNlwwMjI0XG5cMDMzaW50X2V4dGVuc2lvIiArCiAgICAgICJuX3JhbmdlX2ZlYXR1cmVcMDMwXDAwMiBcMDAxKFwwMDVCXDAxN1wyMTBcMDAxXDAwMVwyMzBcMDAxXDAwMlwyNDJcMDAxXDAwNlwwMjJcMDAxMVwwMzBcMzQ2XDAwN1wwMjIsIiArCiAgICAgICJcblwwMjNpbnRfbWVzc2FnZV9mZWF0dXJlXDAzMFwwMDMgXDAwMShcMDA1QlwwMTdcMjEwXDAwMVwwMDFcMjMwXDAwMVwwMDNcMjQyXDAwMVwwMDZcMDIyXDAwMSIgKwogICAgICAiMVwwMzBcMzQ2XDAwN1wwMjIqXG5cMDIxaW50X2ZpZWxkX2ZlYXR1cmVcMDMwXDAwNCBcMDAxKFwwMDVCXDAxN1wyMTBcMDAxXDAwMVwyMzBcMDAxXDAwNFwyNDIiICsKICAgICAgIlwwMDFcMDA2XDAyMlwwMDExXDAzMFwzNDZcMDA3XDAyMipcblwwMjFpbnRfb25lb2ZfZmVhdHVyZVwwMzBcMDA1IFwwMDEoXDAwNUJcMDE3XDIxMFwwMDFcMDAxIiArCiAgICAgICJcMjMwXDAwMVwwMDVcMjQyXDAwMVwwMDZcMDIyXDAwMTFcMDMwXDM0NlwwMDdcMDIyKVxuXDAyMGludF9lbnVtX2ZlYXR1cmVcMDMwXDAwNiBcMDAxKFwwMDVCXDAxNyIgKwogICAgICAiXDIxMFwwMDFcMDAxXDIzMFwwMDFcMDA2XDI0MlwwMDFcMDA2XDAyMlwwMDExXDAzMFwzNDZcMDA3XDAyMi9cblwwMjZpbnRfZW51bV9lbnRyeV9mZWF0dXIiICsKICAgICAgImVcMDMwXDAwNyBcMDAxKFwwMDVCXDAxN1wyMTBcMDAxXDAwMVwyMzBcMDAxXDAwN1wyNDJcMDAxXDAwNlwwMjJcMDAxMVwwMzBcMzQ2XDAwN1wwMjIsXG5cMDIzaW50X3NlcnZpY2VfIiArCiAgICAgICJmZWF0dXJlXDAzMFwwMTAgXDAwMShcMDA1QlwwMTdcMjEwXDAwMVwwMDFcMjMwXDAwMVwwMTBcMjQyXDAwMVwwMDZcMDIyXDAwMTFcMDMwXDM0NlwwMDdcMDIyK1xuXDAyMmludF9tZSIgKwogICAgICAidGhvZF9mZWF0dXJlXDAzMFx0IFwwMDEoXDAwNUJcMDE3XDIxMFwwMDFcMDAxXDIzMFwwMDFcdFwyNDJcMDAxXDAwNlwwMjJcMDAxMVwwMzBcMzQ2XDAwN1wwMjJFXG5cMDI0aSIgKwogICAgICAibnRfbXVsdGlwbGVfZmVhdHVyZVwwMzBcbiBcMDAxKFwwMDVCXCdcMjEwXDAwMVwwMDFcMjMwXDAwMVwwMDFcMjMwXDAwMVwwMDRcMjMwXDAwMVwwMDNcMjMwIiArCiAgICAgICJcMDAxXDAwNlwyMzBcMDAxXDAwN1wyMzBcMDAxXDAxMFwyMzBcMDAxXHRcMjMwXDAwMVwwMDVcMjMwXDAwMVwwMDJcMjQyXDAwMVwwMDZcMDIyXDAwMTFcMDMwXDM0NlwwMDdcMDIyPFxuXDAyMmJvb2xfZmllbGQiICsKICAgICAgIl9mZWF0dXJlXDAzMFwwMTMgXDAwMShcMDEwQiBcMjEwXDAwMVwwMDFcMjMwXDAwMVwwMDRcMjQyXDAwMVxuXDAyMlwwMDVmYWxzZVwwMzBcMzQ2XDAwN1wyNDJcMDAxXG5cMDIyXDAwNCIgKwogICAgICAidHJ1ZVwwMzBcMjM1XDIxNVwwMDZcMDIyOlxuXDAyM2Zsb2F0X2ZpZWxkX2ZlYXR1cmVcMDMwXDAxNCBcMDAxKFwwMDJCXDAzNVwyMTAiICsKICAgICAgIlwwMDFcMDAxXDIzMFwwMDFcMDA0XDI0MlwwMDFcMDEwXDAyMlwwMDMxLjFcMDMwXDM0NlwwMDdcMjQyXDAwMVx0XDAyMlwwMDMxLjJcMDMwXDIzNVwyMTVcMDA2XDAyMlwzMTRcMDAxXG5cMDI1bWVzc2FnZSIgKwogICAgICAiX2ZpZWxkX2ZlYXR1cmVcMDMwXHIgXDAwMShcMDEzMlwwMzcucGIuVGVzdEZlYXR1cmVzLk0iICsKICAgICAgImVzc2FnZUZlYXR1cmVCXDIxM1wwMDFcMjEwXDAwMVwwMDFcMjMwXDAwMVwwMDRcMjQyXDAwMVwwMjJcMDIyXDAxNGludF9maWVsZDogMlwwMzAiICsKICAgICAgIlwyMzVcMjE1XDAwNlwyNDJcMDAxXDAzMlwwMjJcMDI0c3RyaW5nX2ZpZWxkOiBcJzIwMjRcJ1wwMzBcMjM2XDIxNVwwMDZcMjQyXDAwMUhcMDIyQ2JvbyIgKwogICAgICAibF9maWVsZDogdHJ1ZSBpbnRfZmllbGQ6IDEgZmxvYXRfZmllbGQ6ICIgKwogICAgICAiMS41IHN0cmluZ19maWVsZDogXCcyMDIzXCdcMDMwXDM1MFwwMDdcMjQyXDAwMVwwMDVcMDIyXDAwMFwwMzBcMzQ2XDAwN1wwMjJcMjM0XDAwMVxuXDAyMiIgKwogICAgICAiZW51bV9maWVsZF9mZWF0dXJlXDAzMFwwMTYgXDAwMShcMDE2MlwwMzQucGIuVGVzdEZlYXR1ciIgKwogICAgICAiZXMuRW51bUZlYXR1cmVCYlwyMTBcMDAxXDAwMVwyMzBcMDAxXDAwNFwyNDJcMDAxXDAzNlwwMjJcMDMxVEVTVF9FTlVNX0ZFQSIgKwogICAgICAiVFVSRV9VTktOT1dOXDAzMFwzNDZcMDA3XDI0MlwwMDFcMDIwXDAyMlwwMTNFTlVNX1ZBTFVFMVwwMzBcMzUwXDAwN1wyNDJcMDAxXDAyMVwwMjJcMDEzRSIgKwogICAgICAiTlVNX1ZBTFVFMlwwMzBcMjM1XDIxNVwwMDZcMjQyXDAwMVwwMjFcMDIyXDAxM0VOVU1fVkFMVUUzXDAzMFwyMzZcMjE1XDAwNlwwMjJDXG5cMDIyaW4iICsKICAgICAgInRfc291cmNlX2ZlYXR1cmVcMDMwXDAxNyBcMDAxKFwwMDVCXCdcMjEwXDAwMVwwMDJcMjMwXDAwMVwwMDFcMjMwXDAwMVwwMDRcMjMwXDAwMVwwMDNcMjMwXDAwMVwwMDZcMjMwIiArCiAgICAgICJcMDAxXDAwN1wyMzBcMDAxXDAxMFwyMzBcMDAxXHRcMjMwXDAwMVwwMDVcMjMwXDAwMVwwMDJcMjQyXDAwMVwwMDZcMDIyXDAwMTFcMDMwXDM0NlwwMDdcMDIyS1xuXDAyNXN0cmluZ19zb3VyY2UiICsKICAgICAgIl9mZWF0dXJlXDAzMFwwMjAgXDAwMShcdEIsXDIxMFwwMDFcMDAyXDIzMFwwMDFcMDAxXDIzMFwwMDFcMDA0XDIzMFwwMDFcMDAzXDIzMFwwMDFcMDA2XDIzMFwwMDFcMDA3XDIzMFwwMDFcMDEwXDIzMFwwMDFcdCIgKwogICAgICAiXDIzMFwwMDFcMDA1XDIzMFwwMDFcMDAyXDI0MlwwMDFcMDEzXDAyMlwwMDZcJzIwMjNcJ1wwMzBcMzQ2XDAwN1wwMzJiXG5cMDE2TWVzc2FnZUZlYXR1cmVcMDIyXDAyMiIgKwogICAgICAiXG5cbmJvb2xfZmllbGRcMDMwXDAwMSBcMDAxKFwwMTBcMDIyXDAyMVxuXHRpbnRfZmllbGRcMDMwXDAwMiBcMDAxKFwwMDVcMDIyXDAyM1xuIiArCiAgICAgICJcMDEzZmxvYXRfZmllbGRcMDMwXDAwMyBcMDAxKFwwMDJcMDIyXDAyNFxuXDAxNHN0cmluZ19maWVsZFwwMzBcMDA0IFwwMDEoXHQiICsKICAgICAgIlwiXDIwMVwwMDFcblwwMTNFbnVtRmVhdHVyZVwwMjJcMDM1XG5cMDMxVEVTVF9FTlVNX0ZFQVRVUkVfVU4iICsKICAgICAgIktOT1dOXDAyMFwwMDBcMDIyXDAxN1xuXDAxM0VOVU1fVkFMVUUxXDAyMFwwMDFcMDIyXDAxN1xuXDAxM0VOVU1fVkFMVUUyXDAyMCIgKwogICAgICAiXDAwMlwwMjJcMDE3XG5cMDEzRU5VTV9WQUxVRTNcMDIwXDAwM1wwMjJcMDE3XG5cMDEzRU5VTV9WQUxVRTRcMDIwXDAwNFwwMjJcMDE3XG5cMDEzRSIgKwogICAgICAiTlVNX1ZBTFVFNVwwMjBcMDA1OjxcblwwMDR0ZXN0XDAyMlwwMzMuZ29vZ2xlLnByb3RvYnVmLkYiICsKICAgICAgImVhdHVyZVNldFwwMzBcMjE3TiBcMDAxKFwwMTMyXDAyMC5wYi5UZXN0RmVhdHVyZXMiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5nZXREZXNjcmlwdG9yKCksCiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcGJfVGVzdE1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcGJfVGVzdE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcGJfVGVzdE1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcGJfVGVzdE1lc3NhZ2VfTmVzdGVkX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcGJfVGVzdE1lc3NhZ2VfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wYl9UZXN0TWVzc2FnZV9OZXN0ZWRfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcGJfVGVzdE1lc3NhZ2VfTmVzdGVkX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RGZWF0dXJlc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wYl9UZXN0RmVhdHVyZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcGJfVGVzdEZlYXR1cmVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJJbnRGaWxlRmVhdHVyZSIsICJJbnRFeHRlbnNpb25SYW5nZUZlYXR1cmUiLCAiSW50TWVzc2FnZUZlYXR1cmUiLCAiSW50RmllbGRGZWF0dXJlIiwgIkludE9uZW9mRmVhdHVyZSIsICJJbnRFbnVtRmVhdHVyZSIsICJJbnRFbnVtRW50cnlGZWF0dXJlIiwgIkludFNlcnZpY2VGZWF0dXJlIiwgIkludE1ldGhvZEZlYXR1cmUiLCAiSW50TXVsdGlwbGVGZWF0dXJlIiwgIkJvb2xGaWVsZEZlYXR1cmUiLCAiRmxvYXRGaWVsZEZlYXR1cmUiLCAiTWVzc2FnZUZpZWxkRmVhdHVyZSIsICJFbnVtRmllbGRGZWF0dXJlIiwgIkludFNvdXJjZUZlYXR1cmUiLCAiU3RyaW5nU291cmNlRmVhdHVyZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RGZWF0dXJlc19NZXNzYWdlRmVhdHVyZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RGZWF0dXJlc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RGZWF0dXJlc19NZXNzYWdlRmVhdHVyZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wYl9UZXN0RmVhdHVyZXNfTWVzc2FnZUZlYXR1cmVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkJvb2xGaWVsZCIsICJJbnRGaWVsZCIsICJGbG9hdEZpZWxkIiwgIlN0cmluZ0ZpZWxkIiwgfSk7CiAgICB0ZXN0LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMCkpOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLmdldERlc2NyaXB0b3IoKTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAM71lVJVYwAAVWMAAB8AAABwYi9Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW52YWxpZF9mZWF0dXJlcy5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcGI7CgpwdWJsaWMgZmluYWwgY2xhc3MgVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMgewogIHByaXZhdGUgVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMoKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RyeS5hZGQocGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMudGVzdEludmFsaWQpOwogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RJbnZhbGlkRmVhdHVyZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cGIuVGVzdEludmFsaWRGZWF0dXJlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ZlYXR1cmUgPSAxIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRmVhdHVyZS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkRmVhdHVyZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfZmVhdHVyZSA9IDEgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGZWF0dXJlLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGZWF0dXJlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfZmVhdHVyZSA9IDEgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZlYXR1cmUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGZWF0dXJlKGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHBiLlRlc3RJbnZhbGlkRmVhdHVyZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0SW52YWxpZEZlYXR1cmVzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnBiLlRlc3RJbnZhbGlkRmVhdHVyZXMpCiAgICAgIFRlc3RJbnZhbGlkRmVhdHVyZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RJbnZhbGlkRmVhdHVyZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdEludmFsaWRGZWF0dXJlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RJbnZhbGlkRmVhdHVyZXMoKSB7CiAgICAgIHJlcGVhdGVkRmVhdHVyZV8gPSBlbXB0eUludExpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0SW52YWxpZEZlYXR1cmVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RJbnZhbGlkRmVhdHVyZXNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5pbnRlcm5hbF9zdGF0aWNfcGJfVGVzdEludmFsaWRGZWF0dXJlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHBiLlVuaXR0ZXN0SW52YWxpZEZlYXR1cmVzLlRlc3RJbnZhbGlkRmVhdHVyZXMuY2xhc3MsIHBiLlVuaXR0ZXN0SW52YWxpZEZlYXR1cmVzLlRlc3RJbnZhbGlkRmVhdHVyZXMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRkVBVFVSRV9GSUVMRF9OVU1CRVIgPSAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEZlYXR1cmVfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfZmVhdHVyZSA9IDEgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGZWF0dXJlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRGZWF0dXJlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRmVhdHVyZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ZlYXR1cmUgPSAxIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmVhdHVyZS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZlYXR1cmVDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRmVhdHVyZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9mZWF0dXJlID0gMSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmVhdHVyZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGZWF0dXJlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGZWF0dXJlXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZlYXR1cmVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgcmVwZWF0ZWRGZWF0dXJlXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRmVhdHVyZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhyZXBlYXRlZEZlYXR1cmVfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRGZWF0dXJlTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIG90aGVyID0gKHBiLlVuaXR0ZXN0SW52YWxpZEZlYXR1cmVzLlRlc3RJbnZhbGlkRmVhdHVyZXMpIG9iajsKCiAgICAgIGlmICghZ2V0UmVwZWF0ZWRGZWF0dXJlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRmVhdHVyZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoZ2V0UmVwZWF0ZWRGZWF0dXJlQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GRUFUVVJFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZlYXR1cmVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuVGVzdEludmFsaWRGZWF0dXJlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuVGVzdEludmFsaWRGZWF0dXJlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuVGVzdEludmFsaWRGZWF0dXJlcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0SW52YWxpZEZlYXR1cmVzLlRlc3RJbnZhbGlkRmVhdHVyZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuVGVzdEludmFsaWRGZWF0dXJlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHBiLlRlc3RJbnZhbGlkRmVhdHVyZXN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwYi5UZXN0SW52YWxpZEZlYXR1cmVzKQogICAgICAgIHBiLlVuaXR0ZXN0SW52YWxpZEZlYXR1cmVzLlRlc3RJbnZhbGlkRmVhdHVyZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RJbnZhbGlkRmVhdHVyZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RJbnZhbGlkRmVhdHVyZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuVGVzdEludmFsaWRGZWF0dXJlcy5jbGFzcywgcGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuVGVzdEludmFsaWRGZWF0dXJlcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHBiLlVuaXR0ZXN0SW52YWxpZEZlYXR1cmVzLlRlc3RJbnZhbGlkRmVhdHVyZXMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHJlcGVhdGVkRmVhdHVyZV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RJbnZhbGlkRmVhdHVyZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuVGVzdEludmFsaWRGZWF0dXJlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIGJ1aWxkKCkgewogICAgICAgIHBiLlVuaXR0ZXN0SW52YWxpZEZlYXR1cmVzLlRlc3RJbnZhbGlkRmVhdHVyZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIHJlc3VsdCA9IG5ldyBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHBiLlVuaXR0ZXN0SW52YWxpZEZlYXR1cmVzLlRlc3RJbnZhbGlkRmVhdHVyZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmVhdHVyZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRmVhdHVyZV8gPSByZXBlYXRlZEZlYXR1cmVfOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHBiLlVuaXR0ZXN0SW52YWxpZEZlYXR1cmVzLlRlc3RJbnZhbGlkRmVhdHVyZXMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHBiLlVuaXR0ZXN0SW52YWxpZEZlYXR1cmVzLlRlc3RJbnZhbGlkRmVhdHVyZXMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuVGVzdEludmFsaWRGZWF0dXJlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRmVhdHVyZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGZWF0dXJlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGZWF0dXJlXyA9IG90aGVyLnJlcGVhdGVkRmVhdHVyZV87CiAgICAgICAgICAgIHJlcGVhdGVkRmVhdHVyZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZlYXR1cmVJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGZWF0dXJlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGZWF0dXJlXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGZWF0dXJlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZlYXR1cmVfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZlYXR1cmVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGZWF0dXJlXy5hZGRJbnQoaW5wdXQucmVhZEludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkRmVhdHVyZV8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRmVhdHVyZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRmVhdHVyZV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmVhdHVyZV8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGZWF0dXJlXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfZmVhdHVyZSA9IDEgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZlYXR1cmUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZEZlYXR1cmVMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRmVhdHVyZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZlYXR1cmVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9mZWF0dXJlID0gMSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmVhdHVyZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGZWF0dXJlQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmVhdHVyZV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9mZWF0dXJlID0gMSBbcmV0ZW50aW9uID0gUkVURU5USU9OX1JVTlRJTUUsIHRhcmdldHMgPSBUQVJHRVRfVFlQRV9GSUVMRCwgZWRpdGlvbl9kZWZhdWx0cyA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZlYXR1cmUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZlYXR1cmUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmVhdHVyZV8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfZmVhdHVyZSA9IDEgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGZWF0dXJlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGZWF0dXJlKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGZWF0dXJlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGZWF0dXJlXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ZlYXR1cmUgPSAxIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZlYXR1cmUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZlYXR1cmUoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRmVhdHVyZUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRmVhdHVyZV8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ZlYXR1cmUgPSAxIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRSwgdGFyZ2V0cyA9IFRBUkdFVF9UWVBFX0ZJRUxELCBlZGl0aW9uX2RlZmF1bHRzID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGZWF0dXJlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGZWF0dXJlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGZWF0dXJlSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRmVhdHVyZV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfZmVhdHVyZSA9IDEgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FLCB0YXJnZXRzID0gVEFSR0VUX1RZUEVfRklFTEQsIGVkaXRpb25fZGVmYXVsdHMgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRmVhdHVyZSgpIHsKICAgICAgICByZXBlYXRlZEZlYXR1cmVfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnBiLlRlc3RJbnZhbGlkRmVhdHVyZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnBiLlRlc3RJbnZhbGlkRmVhdHVyZXMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHBiLlVuaXR0ZXN0SW52YWxpZEZlYXR1cmVzLlRlc3RJbnZhbGlkRmVhdHVyZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHBiLlVuaXR0ZXN0SW52YWxpZEZlYXR1cmVzLlRlc3RJbnZhbGlkRmVhdHVyZXMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0SW52YWxpZEZlYXR1cmVzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RJbnZhbGlkRmVhdHVyZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0SW52YWxpZEZlYXR1cmVzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEludmFsaWRGZWF0dXJlcz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0SW52YWxpZEZlYXR1cmVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwYi5Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5UZXN0SW52YWxpZEZlYXR1cmVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRFU1RfSU5WQUxJRF9GSUVMRF9OVU1CRVIgPSA5OTk2OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmVhdHVyZVNldCwKICAgICAgcGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuVGVzdEludmFsaWRGZWF0dXJlcz4gdGVzdEludmFsaWQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHBiLlVuaXR0ZXN0SW52YWxpZEZlYXR1cmVzLlRlc3RJbnZhbGlkRmVhdHVyZXMuY2xhc3MsCiAgICAgICAgcGIuVW5pdHRlc3RJbnZhbGlkRmVhdHVyZXMuVGVzdEludmFsaWRGZWF0dXJlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcGJfVGVzdEludmFsaWRGZWF0dXJlc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wYl9UZXN0SW52YWxpZEZlYXR1cmVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4vZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X2ludmFsaWRfZmVhdHUiICsKICAgICAgInJlcy5wcm90b1wwMjJcMDAycGJcMDMyIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG8iICsKICAgICAgInIucHJvdG9cIkBcblwwMjNUZXN0SW52YWxpZEZlYXR1cmVzXDAyMilcblwwMjByZXBlYXQiICsKICAgICAgImVkX2ZlYXR1cmVcMDMwXDAwMSBcMDAzKFwwMDVCXDAxN1wyMTBcMDAxXDAwMVwyMzBcMDAxXDAwNFwyNDJcMDAxXDAwNlwwMjJcMDAxM1wwMzBcMzUwXDAwNzpLXG5cMDE0dGVzIiArCiAgICAgICJ0X2ludmFsaWRcMDIyXDAzMy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldFwwMzBcMjE0IiArCiAgICAgICJOIFwwMDEoXDAxMzJcMDI3LnBiLlRlc3RJbnZhbGlkRmVhdHVyZXMiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5nZXREZXNjcmlwdG9yKCksCiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcGJfVGVzdEludmFsaWRGZWF0dXJlc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wYl9UZXN0SW52YWxpZEZlYXR1cmVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3BiX1Rlc3RJbnZhbGlkRmVhdHVyZXNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlJlcGVhdGVkRmVhdHVyZSIsIH0pOwogICAgdGVzdEludmFsaWQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgwKSk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuZ2V0RGVzY3JpcHRvcigpOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEAFDZYSey5AADsuQAANgAAAHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0L1VuaXR0ZXN0TXNldFdpcmVGb3JtYXQuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X21zZXRfd2lyZV9mb3JtYXQucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIFVuaXR0ZXN0TXNldFdpcmVGb3JtYXQgewogIHByaXZhdGUgVW5pdHRlc3RNc2V0V2lyZUZvcm1hdCgpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBUZXN0TWVzc2FnZVNldE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxUZXN0TWVzc2FnZVNldD4gewogIH0KICAvKioKICAgKiA8cHJlPgogICAqIEEgbWVzc2FnZSB3aXRoIG1lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0LgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXR9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0TWVzc2FnZVNldCBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVNZXNzYWdlPAogICAgICAgIFRlc3RNZXNzYWdlU2V0PiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQpCiAgICAgIFRlc3RNZXNzYWdlU2V0T3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TWVzc2FnZVNldC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TWVzc2FnZVNldChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjxwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TWVzc2FnZVNldCgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TWVzc2FnZVNldCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0X2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LmNsYXNzLCBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLkV4dGVuZGFibGVNZXNzYWdlPHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQ+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3TWVzc2FnZVNldEV4dGVuc2lvbldyaXRlcigpOwogICAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCgyMTQ3NDgzNjQ3LCBvdXRwdXQpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVBc01lc3NhZ2VTZXRUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBleHRlbnNpb25zU2VyaWFsaXplZFNpemVBc01lc3NhZ2VTZXQoKTsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemVBc01lc3NhZ2VTZXQoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCBvdGhlciA9IChwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0KSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEV4dGVuc2lvbkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRFeHRlbnNpb25GaWVsZHMoKSkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSBoYXNoRmllbGRzKGhhc2gsIGdldEV4dGVuc2lvbkZpZWxkcygpKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQSBtZXNzYWdlIHdpdGggbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQsIEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0KQogICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5jbGFzcywgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LmludGVybmFsX3N0YXRpY19wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdF9UZXN0TWVzc2FnZVNldF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgYnVpbGQoKSB7CiAgICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgcmVzdWx0ID0gbmV3IHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQsIFR5cGU+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LCBUPiBleHRlbnNpb24pIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0KSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0KW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0IERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZVNldD4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0TWVzc2FnZVNldD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RNZXNzYWdlU2V0IHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2VTZXQ+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2VTZXQ+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1lc3NhZ2VTZXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc01lc3NhZ2VTZXQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlU2V0LgogICAgICovCiAgICBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0IGdldE1lc3NhZ2VTZXQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRPckJ1aWxkZXIgZ2V0TWVzc2FnZVNldE9yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXJ9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyKQogICAgICBUZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXJPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdENvbnRhaW5lci5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIuY2xhc3MsIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX1NFVF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2VTZXRfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZVNldCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc01lc3NhZ2VTZXQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlU2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCBnZXRNZXNzYWdlU2V0KCkgewogICAgICByZXR1cm4gbWVzc2FnZVNldF8gPT0gbnVsbCA/IHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlU2V0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0T3JCdWlsZGVyIGdldE1lc3NhZ2VTZXRPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBtZXNzYWdlU2V0XyA9PSBudWxsID8gcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1lc3NhZ2VTZXRfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmIChoYXNNZXNzYWdlU2V0KCkpIHsKICAgICAgICBpZiAoIWdldE1lc3NhZ2VTZXQoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRNZXNzYWdlU2V0KCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0TWVzc2FnZVNldCgpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdENvbnRhaW5lcikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIgb3RoZXIgPSAocHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIpIG9iajsKCiAgICAgIGlmIChoYXNNZXNzYWdlU2V0KCkgIT0gb3RoZXIuaGFzTWVzc2FnZVNldCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNNZXNzYWdlU2V0KCkpIHsKICAgICAgICBpZiAoIWdldE1lc3NhZ2VTZXQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE1lc3NhZ2VTZXQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNNZXNzYWdlU2V0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNRVNTQUdFX1NFVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TWVzc2FnZVNldCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdENvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdENvbnRhaW5lciBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyKQogICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdENvbnRhaW5lcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LmludGVybmFsX3N0YXRpY19wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdF9UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIuY2xhc3MsIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0TWVzc2FnZVNldEZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgbWVzc2FnZVNldF8gPSBudWxsOwogICAgICAgIGlmIChtZXNzYWdlU2V0QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZVNldEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG1lc3NhZ2VTZXRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LmludGVybmFsX3N0YXRpY19wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdF9UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyIGJ1aWxkKCkgewogICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyIHJlc3VsdCA9IG5ldyBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdENvbnRhaW5lcih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdENvbnRhaW5lciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5tZXNzYWdlU2V0XyA9IG1lc3NhZ2VTZXRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBtZXNzYWdlU2V0XwogICAgICAgICAgICAgIDogbWVzc2FnZVNldEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdENvbnRhaW5lcikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNNZXNzYWdlU2V0KCkpIHsKICAgICAgICAgIG1lcmdlTWVzc2FnZVNldChvdGhlci5nZXRNZXNzYWdlU2V0KCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKGhhc01lc3NhZ2VTZXQoKSkgewogICAgICAgICAgaWYgKCFnZXRNZXNzYWdlU2V0KCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRNZXNzYWdlU2V0RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgbWVzc2FnZVNldF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQsIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQuQnVpbGRlciwgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldE9yQnVpbGRlcj4gbWVzc2FnZVNldEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZVNldCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNZXNzYWdlU2V0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VTZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCBnZXRNZXNzYWdlU2V0KCkgewogICAgICAgIGlmIChtZXNzYWdlU2V0QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VTZXRfID09IG51bGwgPyBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZVNldF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlU2V0QnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNZXNzYWdlU2V0KHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgdmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZVNldEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgbWVzc2FnZVNldF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZVNldEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCBtZXNzYWdlX3NldCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TWVzc2FnZVNldCgKICAgICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZVNldEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VTZXRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VTZXRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlTWVzc2FnZVNldChwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0IHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VTZXRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgbWVzc2FnZVNldF8gIT0gbnVsbCAmJgogICAgICAgICAgICBtZXNzYWdlU2V0XyAhPSBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE1lc3NhZ2VTZXRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1lc3NhZ2VTZXRfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VTZXRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAobWVzc2FnZVNldF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWVzc2FnZVNldCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgbWVzc2FnZVNldF8gPSBudWxsOwogICAgICAgIGlmIChtZXNzYWdlU2V0QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZVNldEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG1lc3NhZ2VTZXRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LkJ1aWxkZXIgZ2V0TWVzc2FnZVNldEJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRNZXNzYWdlU2V0RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0T3JCdWlsZGVyIGdldE1lc3NhZ2VTZXRPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VTZXRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZVNldEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VTZXRfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlU2V0XzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCBtZXNzYWdlX3NldCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCwgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5CdWlsZGVyLCBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0T3JCdWlsZGVyPiAKICAgICAgICAgIGdldE1lc3NhZ2VTZXRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VTZXRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBtZXNzYWdlU2V0QnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LCBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LkJ1aWxkZXIsIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRNZXNzYWdlU2V0KCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBtZXNzYWdlU2V0XyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtZXNzYWdlU2V0QnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdENvbnRhaW5lciBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdENvbnRhaW5lcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXI+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdENvbnRhaW5lcj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdENvbnRhaW5lcl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdF9UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXJfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcbi9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbXNldF93aXJlX2ZvciIgKwogICAgICAibWF0LnByb3RvXDAyMlwwMzJwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdFwiLFxuIiArCiAgICAgICJcMDE2VGVzdE1lc3NhZ2VTZXQqXDAxMFwwMTBcMDA0XDAyMFwyMDBcMzIxXDMzNFwzNzRcMDAxKlwwMTRcMDEwXDIwMFwzMjFcMzM0XDM3NFwwMDFcMDIwXDM3N1wzNzdcMzc3XDM3N1wwMDc6IiArCiAgICAgICJcMDAyXDAxMFwwMDFcImRcbiFUZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXIiICsKICAgICAgIlwwMjI/XG5cMDEzbWVzc2FnZV9zZXRcMDMwXDAwMSBcMDAxKFwwMTMyKi5wcm90bzJfd2lyZWZvcm1hIiArCiAgICAgICJ0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0QilIXDAwMVwzNzBcMDAxXDAwMVwyNTJcMDAyIUdvb2dsIiArCiAgICAgICJlLlByb3RvY29sQnVmZmVycy5UZXN0UHJvdG9zIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRXaXJlRm9ybWF0Q29udGFpbmVyX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0V2lyZUZvcm1hdENvbnRhaW5lcl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdF9UZXN0TWVzc2FnZVNldFdpcmVGb3JtYXRDb250YWluZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk1lc3NhZ2VTZXQiLCB9KTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAKI9/B3GzgoAxs4KADcAAABwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC9Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2FyZW5hX2xpdGUucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIFVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlIHsKICBwcml2YXRlIFVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bX0KICAgKi8KICBwdWJsaWMgZW51bSBGb3JlaWduRW51bQogICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAvKioKICAgICAqIDxjb2RlPkZPUkVJR05fWkVSTyA9IDA7PC9jb2RlPgogICAgICovCiAgICBGT1JFSUdOX1pFUk8oMCksCiAgICAvKioKICAgICAqIDxjb2RlPkZPUkVJR05fRk9PID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEZPUkVJR05fRk9PKDQpLAogICAgLyoqCiAgICAgKiA8Y29kZT5GT1JFSUdOX0JBUiA9IDU7PC9jb2RlPgogICAgICovCiAgICBGT1JFSUdOX0JBUig1KSwKICAgIC8qKgogICAgICogPGNvZGU+Rk9SRUlHTl9CQVogPSA2OzwvY29kZT4KICAgICAqLwogICAgRk9SRUlHTl9CQVooNiksCiAgICBVTlJFQ09HTklaRUQoLTEpLAogICAgOwoKICAgIC8qKgogICAgICogPGNvZGU+Rk9SRUlHTl9aRVJPID0gMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPUkVJR05fWkVST19WQUxVRSA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPkZPUkVJR05fRk9PID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPUkVJR05fRk9PX1ZBTFVFID0gNDsKICAgIC8qKgogICAgICogPGNvZGU+Rk9SRUlHTl9CQVIgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9SRUlHTl9CQVJfVkFMVUUgPSA1OwogICAgLyoqCiAgICAgKiA8Y29kZT5GT1JFSUdOX0JBWiA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT1JFSUdOX0JBWl9WQUxVRSA9IDY7CgoKICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgbnVtYmVyIG9mIGFuIHVua25vd24gZW51bSB2YWx1ZS4iKTsKICAgICAgfQogICAgICByZXR1cm4gdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBzdGF0aWMgRm9yZWlnbkVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBGb3JlaWduRW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICBjYXNlIDA6IHJldHVybiBGT1JFSUdOX1pFUk87CiAgICAgICAgY2FzZSA0OiByZXR1cm4gRk9SRUlHTl9GT087CiAgICAgICAgY2FzZSA1OiByZXR1cm4gRk9SRUlHTl9CQVI7CiAgICAgICAgY2FzZSA2OiByZXR1cm4gRk9SRUlHTl9CQVo7CiAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8Rm9yZWlnbkVudW0+CiAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgIEZvcmVpZ25FbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPEZvcmVpZ25FbnVtPigpIHsKICAgICAgICAgICAgcHVibGljIEZvcmVpZ25FbnVtIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gRm9yZWlnbkVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oCiAgICAgICAgICAgICJDYW4ndCBnZXQgdGhlIGRlc2NyaXB0b3Igb2YgYW4gdW5yZWNvZ25pemVkIGVudW0gdmFsdWUuIik7CiAgICAgIH0KICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgIH0KICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGb3JlaWduRW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgIHB1YmxpYyBzdGF0aWMgRm9yZWlnbkVudW0gdmFsdWVPZigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgfQogICAgICBpZiAoZGVzYy5nZXRJbmRleCgpID09IC0xKSB7CiAgICAgICAgcmV0dXJuIFVOUkVDT0dOSVpFRDsKICAgICAgfQogICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgcHJpdmF0ZSBGb3JlaWduRW51bShpbnQgdmFsdWUpIHsKICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtKQogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFNpbmd1bGFyCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5pbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDY0LgogICAgICovCiAgICBsb25nIGdldE9wdGlvbmFsSW50NjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBvcHRpb25hbF91aW50MzIgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxVaW50MzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDY0LgogICAgICovCiAgICBsb25nIGdldE9wdGlvbmFsVWludDY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQzMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsU2ludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50NjQgb3B0aW9uYWxfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbFNpbnQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZpeGVkMzIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEZpeGVkMzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGaXhlZDY0LgogICAgICovCiAgICBsb25nIGdldE9wdGlvbmFsRml4ZWQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ZpeGVkMzIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbFNmaXhlZDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ZpeGVkNjQuCiAgICAgKi8KICAgIGxvbmcgZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+ZmxvYXQgb3B0aW9uYWxfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZsb2F0LgogICAgICovCiAgICBmbG9hdCBnZXRPcHRpb25hbEZsb2F0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5kb3VibGUgb3B0aW9uYWxfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxEb3VibGUuCiAgICAgKi8KICAgIGRvdWJsZSBnZXRPcHRpb25hbERvdWJsZSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+Ym9vbCBvcHRpb25hbF9ib29sID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCb29sLgogICAgICovCiAgICBib29sZWFuIGdldE9wdGlvbmFsQm9vbCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsU3RyaW5nQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlcy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9wdGlvbmFsQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICovCiAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEltcG9ydE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEltcG9ydE1lc3NhZ2UuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgKi8KICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxGb3JlaWduRW51bS4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsRm9yZWlnbkVudW1WYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGb3JlaWduRW51bS4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbkVudW0gZ2V0T3B0aW9uYWxGb3JlaWduRW51bSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmdQaWVjZS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZ1BpZWNlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZ1BpZWNlLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFN0cmluZ1BpZWNlQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxDb3JkLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsQ29yZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbENvcmQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsQ29yZEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxMYXp5TWVzc2FnZS4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBSZXBlYXRlZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZEludDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50NjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkSW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkVWludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFVpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkVWludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDY0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UmVwZWF0ZWRVaW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkU2ludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU2ludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDY0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UmVwZWF0ZWRTaW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkNjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRSZXBlYXRlZEZpeGVkNjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNmaXhlZDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkU2ZpeGVkNjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGbG9hdC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PiBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmxvYXQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEZsb2F0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBmbG9hdCBnZXRSZXBlYXRlZEZsb2F0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWREb3VibGUuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+IGdldFJlcGVhdGVkRG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWREb3VibGUuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZERvdWJsZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZG91YmxlIGdldFJlcGVhdGVkRG91YmxlKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2wuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPiBnZXRSZXBlYXRlZEJvb2xMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQm9vbENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2woaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCeXRlcy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEJ5dGVzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQnl0ZXMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gCiAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2U+IAogICAgICAgIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2U+IAogICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IGdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRSZXBlYXRlZE5lc3RlZEVudW0oaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGb3JlaWduRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbkVudW0+IGdldFJlcGVhdGVkRm9yZWlnbkVudW1MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRm9yZWlnbkVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bSBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFJlcGVhdGVkRm9yZWlnbkVudW1WYWx1ZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZEZvcmVpZ25FbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRm9yZWlnbkVudW1WYWx1ZShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmdQaWVjZS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZ1BpZWNlLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZENvcmQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQ29yZC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQ29yZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZENvcmQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkQ29yZChpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZENvcmQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZENvcmRCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gCiAgICAgICAgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRSZXBlYXRlZExhenlNZXNzYWdlKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZExhenlNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZVaW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09uZW9mVWludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZVaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRPbmVvZlVpbnQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPbmVvZk5lc3RlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mTmVzdGVkTWVzc2FnZS4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9uZW9mTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPbmVvZlN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mU3RyaW5nLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9uZW9mU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9uZW9mU3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPbmVvZlN0cmluZ0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDExNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09uZW9mQnl0ZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZCeXRlcy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9uZW9mQnl0ZXMoKTsKCiAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuT25lb2ZGaWVsZENhc2UgZ2V0T25lb2ZGaWVsZENhc2UoKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUaGlzIHByb3RvIGluY2x1ZGVzIGV2ZXJ5IHR5cGUgb2YgZmllbGQgaW4gYm90aCBzaW5ndWxhciBhbmQgcmVwZWF0ZWQKICAgKiBmb3Jtcy4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RBbGxUeXBlcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMpCiAgICAgIFRlc3RBbGxUeXBlc09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RBbGxUeXBlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RBbGxUeXBlcygpIHsKICAgICAgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgIG9wdGlvbmFsQnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgICAgb3B0aW9uYWxGb3JlaWduRW51bV8gPSAwOwogICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9ICIiOwogICAgICBvcHRpb25hbENvcmRfID0gIiI7CiAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZ18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZEJ5dGVzXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRDb3JkXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RBbGxUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLmNsYXNzLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bX0KICAgICAqLwogICAgcHVibGljIGVudW0gTmVzdGVkRW51bQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlpFUk8gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIFpFUk8oMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEZPTygxKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQkFSKDIpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QkFaID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVooMyksCiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBJbnRlbnRpb25hbGx5IG5lZ2F0aXZlLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+TkVHID0gLTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgTkVHKC0xKSwKICAgICAgVU5SRUNPR05JWkVEKC0xKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlpFUk8gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFpFUk9fVkFMVUUgPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+Rk9PID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fVkFMVUUgPSAxOwogICAgICAvKioKICAgICAgICogPGNvZGU+QkFSID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVJfVkFMVUUgPSAyOwogICAgICAvKioKICAgICAgICogPGNvZGU+QkFaID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVpfVkFMVUUgPSAzOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogSW50ZW50aW9uYWxseSBuZWdhdGl2ZS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPk5FRyA9IC0xOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5FR19WQUxVRSA9IC0xOwoKCiAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgbnVtYmVyIG9mIGFuIHVua25vd24gZW51bSB2YWx1ZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBaRVJPOwogICAgICAgICAgY2FzZSAxOiByZXR1cm4gRk9POwogICAgICAgICAgY2FzZSAyOiByZXR1cm4gQkFSOwogICAgICAgICAgY2FzZSAzOiByZXR1cm4gQkFaOwogICAgICAgICAgY2FzZSAtMTogcmV0dXJuIE5FRzsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE5lc3RlZEVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBOZXN0ZWRFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIE5lc3RlZEVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIE5lc3RlZEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgZGVzY3JpcHRvciBvZiBhbiB1bnJlY29nbml6ZWQgZW51bSB2YWx1ZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBOZXN0ZWRFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICBpZiAoZGVzYy5nZXRJbmRleCgpID09IC0xKSB7CiAgICAgICAgICByZXR1cm4gVU5SRUNPR05JWkVEOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBOZXN0ZWRFbnVtKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0pCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPmludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJiLgogICAgICAgKi8KICAgICAgaW50IGdldEJiKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZE1lc3NhZ2UgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKQogICAgICAgIE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBOZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgTmVzdGVkTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJCX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgaW50IGJiXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPmludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJiLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEJiKCkgewogICAgICAgIHJldHVybiBiYl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGJiXyAhPSAwKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBiYl8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoYmJfICE9IDApIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBiYl8pOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9iajsKCiAgICAgICAgaWYgKGdldEJiKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QmIoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCQl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QmIoKTsKICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuY2xhc3MsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgYmJfID0gMDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5iYl8gPSBiYl87CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSlvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5nZXRCYigpICE9IDApIHsKICAgICAgICAgICAgc2V0QmIob3RoZXIuZ2V0QmIoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgICAgYmJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBpbnQgYmJfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIDxjb2RlPmludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgYmIuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0QmIoKSB7CiAgICAgICAgICByZXR1cm4gYmJfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIDxjb2RlPmludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBiYiB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJiKGludCB2YWx1ZSkgewoKICAgICAgICAgIGJiXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPHByZT4KICAgICAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICAgICAqIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCiAgICAgICAgICogVGhpcyBmaWxlIG5lZWRzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIHRvIHRlc3QgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICoKICAgICAgICAgKiA8Y29kZT5pbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJiKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgYmJfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkTWVzc2FnZT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBOZXN0ZWRNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHJpdmF0ZSBpbnQgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9uZW9mRmllbGRfOwogICAgcHVibGljIGVudW0gT25lb2ZGaWVsZENhc2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkludGVybmFsT25lT2ZFbnVtIHsKICAgICAgT05FT0ZfVUlOVDMyKDExMSksCiAgICAgIE9ORU9GX05FU1RFRF9NRVNTQUdFKDExMiksCiAgICAgIE9ORU9GX1NUUklORygxMTMpLAogICAgICBPTkVPRl9CWVRFUygxMTQpLAogICAgICBPTkVPRkZJRUxEX05PVF9TRVQoMCk7CiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwogICAgICBwcml2YXRlIE9uZW9mRmllbGRDYXNlKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1iZXIgb2YgdGhlIGVudW0gdG8gbG9vayBmb3IuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1iZXIuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgT25lb2ZGaWVsZENhc2UgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBPbmVvZkZpZWxkQ2FzZSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAxMTE6IHJldHVybiBPTkVPRl9VSU5UMzI7CiAgICAgICAgICBjYXNlIDExMjogcmV0dXJuIE9ORU9GX05FU1RFRF9NRVNTQUdFOwogICAgICAgICAgY2FzZSAxMTM6IHJldHVybiBPTkVPRl9TVFJJTkc7CiAgICAgICAgICBjYXNlIDExNDogcmV0dXJuIE9ORU9GX0JZVEVTOwogICAgICAgICAgY2FzZSAwOiByZXR1cm4gT05FT0ZGSUVMRF9OT1RfU0VUOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB0aGlzLnZhbHVlOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBPbmVvZkZpZWxkQ2FzZQogICAgZ2V0T25lb2ZGaWVsZENhc2UoKSB7CiAgICAgIHJldHVybiBPbmVvZkZpZWxkQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8pOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyXyA9IDA7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBTaW5ndWxhcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+aW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxJbnQ2NF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+aW50NjQgb3B0aW9uYWxfaW50NjQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UMzJfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBvcHRpb25hbF91aW50MzIgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxVaW50MzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VJTlQ2NF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsVWludDY0XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT51aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxVaW50NjQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFVpbnQ2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0lOVDMyX0ZJRUxEX05VTUJFUiA9IDU7CiAgICBwcml2YXRlIGludCBvcHRpb25hbFNpbnQzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFNpbnQzMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsU2ludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TSU5UNjRfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFNpbnQ2NF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+c2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsU2ludDY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxTaW50NjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0ZJWEVEMzJfRklFTERfTlVNQkVSID0gNzsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsRml4ZWQzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbEZpeGVkMzIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEZpeGVkMzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0ZJWEVENjRfRklFTERfTlVNQkVSID0gODsKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbEZpeGVkNjRfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGaXhlZDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbEZpeGVkNjQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEZpeGVkNjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NGSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIGludCBvcHRpb25hbFNmaXhlZDMyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsU2ZpeGVkMzIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFNmaXhlZDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSAxMDsKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFNmaXhlZDY0XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ZpeGVkNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsU2ZpeGVkNjQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFNmaXhlZDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9GTE9BVF9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIHByaXZhdGUgZmxvYXQgb3B0aW9uYWxGbG9hdF8gPSAwRjsKICAgIC8qKgogICAgICogPGNvZGU+ZmxvYXQgb3B0aW9uYWxfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZsb2F0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0T3B0aW9uYWxGbG9hdCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsRmxvYXRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0RPVUJMRV9GSUVMRF9OVU1CRVIgPSAxMjsKICAgIHByaXZhdGUgZG91YmxlIG9wdGlvbmFsRG91YmxlXyA9IDBEOwogICAgLyoqCiAgICAgKiA8Y29kZT5kb3VibGUgb3B0aW9uYWxfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxEb3VibGUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0T3B0aW9uYWxEb3VibGUoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbERvdWJsZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQk9PTF9GSUVMRF9OVU1CRVIgPSAxMzsKICAgIHByaXZhdGUgYm9vbGVhbiBvcHRpb25hbEJvb2xfID0gZmFsc2U7CiAgICAvKioKICAgICAqIDxjb2RlPmJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQm9vbC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0T3B0aW9uYWxCb29sKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxCb29sXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TVFJJTkdfRklFTERfTlVNQkVSID0gMTQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFN0cmluZ18gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBzOwogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFN0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQllURVNfRklFTERfTlVNQkVSID0gMTU7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJ5dGVzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9wdGlvbmFsQnl0ZXMoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEJ5dGVzXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAxODsKICAgIHByaXZhdGUgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRk9SRUlHTl9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDE5OwogICAgcHJpdmF0ZSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGb3JlaWduTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxGb3JlaWduTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxGb3JlaWduTWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU1QT1JUX01FU1NBR0VfRklFTERfTlVNQkVSID0gMjA7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxJbXBvcnRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEltcG9ydE1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUiA9IDIxOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxOZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtVmFsdWUoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZEVudW1fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVzdWx0ID0gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZm9yTnVtYmVyKG9wdGlvbmFsTmVzdGVkRW51bV8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRk9SRUlHTl9FTlVNX0ZJRUxEX05VTUJFUiA9IDIyOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxGb3JlaWduRW51bV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxGb3JlaWduRW51bVZhbHVlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduRW51bV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bSBnZXRPcHRpb25hbEZvcmVpZ25FbnVtKCkgewogICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bSByZXN1bHQgPSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bS5mb3JOdW1iZXIob3B0aW9uYWxGb3JlaWduRW51bV8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU1RSSU5HX1BJRUNFX0ZJRUxEX05VTUJFUiA9IDI0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmdQaWVjZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ1BpZWNlXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gczsKICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmdQaWVjZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsU3RyaW5nUGllY2VCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ1BpZWNlXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9DT1JEX0ZJRUxEX05VTUJFUiA9IDI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxDb3JkXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQ29yZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxDb3JkKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsQ29yZF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBvcHRpb25hbENvcmRfID0gczsKICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbENvcmQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbENvcmRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbENvcmRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBvcHRpb25hbENvcmRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfUFVCTElDX0lNUE9SVF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDI2OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9MQVpZX01FU1NBR0VfRklFTERfTlVNQkVSID0gMjc7CiAgICBwcml2YXRlIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbExhenlNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlXyA9PSBudWxsID8gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAzMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRJbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUmVwZWF0ZWQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkSW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBSZXBlYXRlZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDMyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRJbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+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+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdldFJlcGVhdGVkQm9vbChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDQ0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZ18gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZy4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZ0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQllURVNfRklFTERfTlVNQkVSID0gNDU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiByZXBlYXRlZEJ5dGVzXyA9CiAgICAgICAgZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCeXRlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCeXRlc0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCeXRlcyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gNDg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0ZPUkVJR05fTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSA0OTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZT4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZT4gZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lNUE9SVF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDUwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlPiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVIgPSA1MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlc3VsdCA9IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+KHJlcGVhdGVkTmVzdGVkRW51bV8sIHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHJlcGVhdGVkTmVzdGVkRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemU7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRk9SRUlHTl9FTlVNX0ZJRUxEX05VTUJFUiA9IDUyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZEZvcmVpZ25FbnVtXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bT4gcmVwZWF0ZWRGb3JlaWduRW51bV9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25FbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbkVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bSByZXN1bHQgPSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGb3JlaWduRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25FbnVtPiBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25FbnVtPihyZXBlYXRlZEZvcmVpZ25FbnVtXywgcmVwZWF0ZWRGb3JlaWduRW51bV9jb252ZXJ0ZXJfKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25FbnVtIGdldFJlcGVhdGVkRm9yZWlnbkVudW0oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25FbnVtX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZEZvcmVpZ25FbnVtXy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFJlcGVhdGVkRm9yZWlnbkVudW1WYWx1ZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25FbnVtXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZEZvcmVpZ25FbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25FbnVtXy5nZXQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWRGb3JlaWduRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemU7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HX1BJRUNFX0ZJRUxEX05VTUJFUiA9IDU0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZ1BpZWNlXyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZ1BpZWNlLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nUGllY2VDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0NPUkRfRklFTERfTlVNQkVSID0gNTU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkQ29yZF8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZENvcmQuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkQ29yZExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZENvcmRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQ29yZC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZENvcmRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRDb3JkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRDb3JkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZENvcmQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRDb3JkQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZENvcmRfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0xBWllfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSA1NzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gcmVwZWF0ZWRMYXp5TWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiBnZXRSZXBlYXRlZExhenlNZXNzYWdlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZExhenlNZXNzYWdlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZExhenlNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9VSU5UMzJfRklFTERfTlVNQkVSID0gMTExOwogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZVaW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlVpbnQzMigpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTE7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZVaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T25lb2ZVaW50MzIoKSB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTExKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FT0ZfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTEyOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZk5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZk5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCkgewogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICByZXR1cm4gKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXzsKICAgICAgfQogICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPbmVvZk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgIHJldHVybiAocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9TVFJJTkdfRklFTERfTlVNQkVSID0gMTEzOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlN0cmluZygpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZTdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9uZW9mU3RyaW5nKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvbmVvZlN0cmluZy4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9uZW9mU3RyaW5nQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX0JZVEVTX0ZJRUxEX05VTUJFUiA9IDExNDsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZkJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZCeXRlcygpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTQ7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mQnl0ZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T25lb2ZCeXRlcygpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTQpIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIGlmIChvcHRpb25hbEludDMyXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgb3B0aW9uYWxJbnQzMl8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEludDY0XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDIsIG9wdGlvbmFsSW50NjRfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxVaW50MzJfICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoMywgb3B0aW9uYWxVaW50MzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxVaW50NjRfICE9IDBMKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDY0KDQsIG9wdGlvbmFsVWludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ludDMyXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyKDUsIG9wdGlvbmFsU2ludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ludDY0XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NCg2LCBvcHRpb25hbFNpbnQ2NF8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEZpeGVkMzJfICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDMyKDcsIG9wdGlvbmFsRml4ZWQzMl8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEZpeGVkNjRfICE9IDBMKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NCg4LCBvcHRpb25hbEZpeGVkNjRfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxTZml4ZWQzMl8gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyKDksIG9wdGlvbmFsU2ZpeGVkMzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxTZml4ZWQ2NF8gIT0gMEwpIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQ2NCgxMCwgb3B0aW9uYWxTZml4ZWQ2NF8pOwogICAgICB9CiAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMob3B0aW9uYWxGbG9hdF8pICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdCgxMSwgb3B0aW9uYWxGbG9hdF8pOwogICAgICB9CiAgICAgIGlmIChqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMob3B0aW9uYWxEb3VibGVfKSAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKDEyLCBvcHRpb25hbERvdWJsZV8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEJvb2xfICE9IGZhbHNlKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgxMywgb3B0aW9uYWxCb29sXyk7CiAgICAgIH0KICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KG9wdGlvbmFsU3RyaW5nXykpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDE0LCBvcHRpb25hbFN0cmluZ18pOwogICAgICB9CiAgICAgIGlmICghb3B0aW9uYWxCeXRlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMTUsIG9wdGlvbmFsQnl0ZXNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDE4LCBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxOSwgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIwLCBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkRW51bV8gIT0gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uWkVSTy5nZXROdW1iZXIoKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMjEsIG9wdGlvbmFsTmVzdGVkRW51bV8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25FbnVtXyAhPSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bS5GT1JFSUdOX1pFUk8uZ2V0TnVtYmVyKCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDIyLCBvcHRpb25hbEZvcmVpZ25FbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KG9wdGlvbmFsU3RyaW5nUGllY2VfKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjQsIG9wdGlvbmFsU3RyaW5nUGllY2VfKTsKICAgICAgfQogICAgICBpZiAoIWNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmlzU3RyaW5nRW1wdHkob3B0aW9uYWxDb3JkXykpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDI1LCBvcHRpb25hbENvcmRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDI2LCBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyNywgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjUwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyTm9UYWcocmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjU4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDY0Tm9UYWcocmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkVWludDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyNjYpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkVWludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI3NCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRVaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NE5vVGFnKHJlcGVhdGVkVWludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI4Mik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRTaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQzMk5vVGFnKHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjkwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZFNpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0Tm9UYWcocmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI5OCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRGaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZpeGVkMzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMk5vVGFnKHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMDYpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkRml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjROb1RhZyhyZXBlYXRlZEZpeGVkNjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMTQpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkU2ZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ZpeGVkMzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzJOb1RhZyhyZXBlYXRlZFNmaXhlZDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMjIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkU2ZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ZpeGVkNjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjROb1RhZyhyZXBlYXRlZFNmaXhlZDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzMwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEZsb2F0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZsb2F0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0Tm9UYWcocmVwZWF0ZWRGbG9hdF8uZ2V0RmxvYXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzM4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZERvdWJsZU1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWREb3VibGVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlTm9UYWcocmVwZWF0ZWREb3VibGVfLmdldERvdWJsZShpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQm9vbExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzQ2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQm9vbF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sTm9UYWcocmVwZWF0ZWRCb29sXy5nZXRCb29sZWFuKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNDQsIHJlcGVhdGVkU3RyaW5nXy5nZXRSYXcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcyg0NSwgcmVwZWF0ZWRCeXRlc18uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDQ4LCByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNDksIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg1MCwgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDQxMCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWROZXN0ZWRFbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bU5vVGFnKHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNDE4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEZvcmVpZ25FbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZvcmVpZ25FbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW1Ob1RhZyhyZXBlYXRlZEZvcmVpZ25FbnVtXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDU0LCByZXBlYXRlZFN0cmluZ1BpZWNlXy5nZXRSYXcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRDb3JkXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNTUsIHJlcGVhdGVkQ29yZF8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTGF6eU1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg1NywgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigKICAgICAgICAgICAgMTExLCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfKSk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDExMiwgKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDExMywgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0KSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoCiAgICAgICAgICAgIDExNCwgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAob3B0aW9uYWxJbnQzMl8gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgb3B0aW9uYWxJbnQzMl8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEludDY0XyAhPSAwTCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemUoMiwgb3B0aW9uYWxJbnQ2NF8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbFVpbnQzMl8gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKDMsIG9wdGlvbmFsVWludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsVWludDY0XyAhPSAwTCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplKDQsIG9wdGlvbmFsVWludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ludDMyXyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemUoNSwgb3B0aW9uYWxTaW50MzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxTaW50NjRfICE9IDBMKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemUoNiwgb3B0aW9uYWxTaW50NjRfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxGaXhlZDMyXyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkMzJTaXplKDcsIG9wdGlvbmFsRml4ZWQzMl8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEZpeGVkNjRfICE9IDBMKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkNjRTaXplKDgsIG9wdGlvbmFsRml4ZWQ2NF8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbFNmaXhlZDMyXyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDMyU2l6ZSg5LCBvcHRpb25hbFNmaXhlZDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ZpeGVkNjRfICE9IDBMKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDY0U2l6ZSgxMCwgb3B0aW9uYWxTZml4ZWQ2NF8pOwogICAgICB9CiAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMob3B0aW9uYWxGbG9hdF8pICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRmxvYXRTaXplKDExLCBvcHRpb25hbEZsb2F0Xyk7CiAgICAgIH0KICAgICAgaWYgKGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9SYXdMb25nQml0cyhvcHRpb25hbERvdWJsZV8pICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRG91YmxlU2l6ZSgxMiwgb3B0aW9uYWxEb3VibGVfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxCb29sXyAhPSBmYWxzZSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSgxMywgb3B0aW9uYWxCb29sXyk7CiAgICAgIH0KICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KG9wdGlvbmFsU3RyaW5nXykpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDE0LCBvcHRpb25hbFN0cmluZ18pOwogICAgICB9CiAgICAgIGlmICghb3B0aW9uYWxCeXRlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgxNSwgb3B0aW9uYWxCeXRlc18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOCwgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOSwgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAsIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxOZXN0ZWRFbnVtXyAhPSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5aRVJPLmdldE51bWJlcigpKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDIxLCBvcHRpb25hbE5lc3RlZEVudW1fKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxGb3JlaWduRW51bV8gIT0gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbkVudW0uRk9SRUlHTl9aRVJPLmdldE51bWJlcigpKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDIyLCBvcHRpb25hbEZvcmVpZ25FbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KG9wdGlvbmFsU3RyaW5nUGllY2VfKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMjQsIG9wdGlvbmFsU3RyaW5nUGllY2VfKTsKICAgICAgfQogICAgICBpZiAoIWNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmlzU3RyaW5nRW1wdHkob3B0aW9uYWxDb3JkXykpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDI1LCBvcHRpb25hbENvcmRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjYsIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjcsIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKHJlcGVhdGVkSW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkSW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZU5vVGFnKHJlcGVhdGVkSW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZEludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKHJlcGVhdGVkVWludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRVaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplTm9UYWcocmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRVaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50MzJTaXplTm9UYWcocmVwZWF0ZWRTaW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZFNpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZFNpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZEZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZFNmaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZEZsb2F0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkRmxvYXRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZERvdWJsZU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDEgKiBnZXRSZXBlYXRlZEJvb2xMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZEJvb2xMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRCb29sTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkU3RyaW5nTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQnl0ZXNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplTm9UYWcocmVwZWF0ZWRCeXRlc18uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDgsIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQ5LCByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MCwgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpLmlzRW1wdHkoKSkgeyAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9cmVwZWF0ZWROZXN0ZWRFbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGb3JlaWduRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHJlcGVhdGVkRm9yZWlnbkVudW1fLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZEZvcmVpZ25FbnVtTGlzdCgpLmlzRW1wdHkoKSkgeyAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9cmVwZWF0ZWRGb3JlaWduRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nUGllY2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nUGllY2VfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZENvcmRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkQ29yZF8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZENvcmRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNTcsIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTEpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSgKICAgICAgICAgICAgICAxMTEsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF8pKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTIsIChwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxMTMsIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemUoCiAgICAgICAgICAgICAgMTE0LCAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMgb3RoZXIgPSAocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzKSBvYmo7CgogICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMigpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsSW50NjQoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQzMigpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFVpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQ2NCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFVpbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbFNpbnQzMigpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFNpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbFNpbnQ2NCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFNpbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbEZpeGVkMzIoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxGaXhlZDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsRml4ZWQ2NCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEZpeGVkNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0T3B0aW9uYWxTZml4ZWQzMigpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFNmaXhlZDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsU2ZpeGVkNjQoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0T3B0aW9uYWxGbG9hdCgpKQogICAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICAgIG90aGVyLmdldE9wdGlvbmFsRmxvYXQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRPcHRpb25hbERvdWJsZSgpKQogICAgICAgICAgIT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKAogICAgICAgICAgICAgIG90aGVyLmdldE9wdGlvbmFsRG91YmxlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbEJvb2woKQogICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxCb29sKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRPcHRpb25hbFN0cmluZygpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsU3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0T3B0aW9uYWxCeXRlcygpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsQnl0ZXMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxOZXN0ZWRFbnVtXyAhPSBvdGhlci5vcHRpb25hbE5lc3RlZEVudW1fKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25FbnVtXyAhPSBvdGhlci5vcHRpb25hbEZvcmVpZ25FbnVtXykgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldE9wdGlvbmFsU3RyaW5nUGllY2UoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbFN0cmluZ1BpZWNlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0T3B0aW9uYWxDb3JkKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxDb3JkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSAhPSBvdGhlci5oYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSAhPSBvdGhlci5oYXNPcHRpb25hbExhenlNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkSW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZsb2F0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRmxvYXRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRCb29sTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQm9vbExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZ0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQnl0ZXNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFyZXBlYXRlZE5lc3RlZEVudW1fLmVxdWFscyhvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXJlcGVhdGVkRm9yZWlnbkVudW1fLmVxdWFscyhvdGhlci5yZXBlYXRlZEZvcmVpZ25FbnVtXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nUGllY2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQ29yZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZExhenlNZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkTGF6eU1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0T25lb2ZGaWVsZENhc2UoKS5lcXVhbHMob3RoZXIuZ2V0T25lb2ZGaWVsZENhc2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgc3dpdGNoIChvbmVvZkZpZWxkQ2FzZV8pIHsKICAgICAgICBjYXNlIDExMToKICAgICAgICAgIGlmIChnZXRPbmVvZlVpbnQzMigpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T25lb2ZVaW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMTI6CiAgICAgICAgICBpZiAoIWdldE9uZW9mTmVzdGVkTWVzc2FnZSgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTEzOgogICAgICAgICAgaWYgKCFnZXRPbmVvZlN0cmluZygpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPbmVvZlN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMTQ6CiAgICAgICAgICBpZiAoIWdldE9uZW9mQnl0ZXMoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T25lb2ZCeXRlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzIoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0T3B0aW9uYWxJbnQ2NCgpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxVaW50MzIoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgIGdldE9wdGlvbmFsVWludDY0KCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TSU5UMzJfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFNpbnQzMigpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TSU5UNjRfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0T3B0aW9uYWxTaW50NjQoKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEZpeGVkMzIoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBnZXRPcHRpb25hbEZpeGVkNjQoKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1NGSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxTZml4ZWQzMigpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBnZXRPcHRpb25hbFNmaXhlZDY0KCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9GTE9BVF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgIGdldE9wdGlvbmFsRmxvYXQoKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0T3B0aW9uYWxEb3VibGUoKSkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9CT09MX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgIGdldE9wdGlvbmFsQm9vbCgpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9CWVRFU19GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRk9SRUlHTl9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIG9wdGlvbmFsTmVzdGVkRW51bV87CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0ZPUkVJR05fRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIG9wdGlvbmFsRm9yZWlnbkVudW1fOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TVFJJTkdfUElFQ0VfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFN0cmluZ1BpZWNlKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfQ09SRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsQ29yZCgpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1BVQkxJQ19JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRCb29sQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9CT09MX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEJvb2xMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmdDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmdMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRCeXRlc0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQllURVNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkQnl0ZXNMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZPUkVJR05fTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0lNUE9SVF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcmVwZWF0ZWROZXN0ZWRFbnVtXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZvcmVpZ25FbnVtQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GT1JFSUdOX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkRm9yZWlnbkVudW1fLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nUGllY2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR19QSUVDRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZENvcmRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0NPUkRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkQ29yZExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZExhenlNZXNzYWdlQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9MQVpZX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBzd2l0Y2ggKG9uZW9mRmllbGRDYXNlXykgewogICAgICAgIGNhc2UgMTExOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mVWludDMyKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDExMjoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9ORU9GX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mTmVzdGVkTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDExMzoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9ORU9GX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPbmVvZlN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDExNDoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9ORU9GX0JZVEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGlzIHByb3RvIGluY2x1ZGVzIGV2ZXJ5IHR5cGUgb2YgZmllbGQgaW4gYm90aCBzaW5ndWxhciBhbmQgcmVwZWF0ZWQKICAgICAqIGZvcm1zLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzKQogICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLmNsYXNzLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGJpdEZpZWxkMV8gPSAwOwogICAgICAgIG9wdGlvbmFsSW50MzJfID0gMDsKICAgICAgICBvcHRpb25hbEludDY0XyA9IDBMOwogICAgICAgIG9wdGlvbmFsVWludDMyXyA9IDA7CiAgICAgICAgb3B0aW9uYWxVaW50NjRfID0gMEw7CiAgICAgICAgb3B0aW9uYWxTaW50MzJfID0gMDsKICAgICAgICBvcHRpb25hbFNpbnQ2NF8gPSAwTDsKICAgICAgICBvcHRpb25hbEZpeGVkMzJfID0gMDsKICAgICAgICBvcHRpb25hbEZpeGVkNjRfID0gMEw7CiAgICAgICAgb3B0aW9uYWxTZml4ZWQzMl8gPSAwOwogICAgICAgIG9wdGlvbmFsU2ZpeGVkNjRfID0gMEw7CiAgICAgICAgb3B0aW9uYWxGbG9hdF8gPSAwRjsKICAgICAgICBvcHRpb25hbERvdWJsZV8gPSAwRDsKICAgICAgICBvcHRpb25hbEJvb2xfID0gZmFsc2U7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgICAgb3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9wdGlvbmFsTmVzdGVkRW51bV8gPSAwOwogICAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gMDsKICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9ICIiOwogICAgICAgIG9wdGlvbmFsQ29yZF8gPSAiIjsKICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIHJlcGVhdGVkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIHJlcGVhdGVkQnl0ZXNfID0gZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwODApOwogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAyMDApOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA0MDApOwogICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZENvcmRfID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyBidWlsZCgpIHsKICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyByZXN1bHQgPSBuZXcgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQxXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDEocmVzdWx0KTsgfQogICAgICAgIGJ1aWxkUGFydGlhbE9uZW9mcyhyZXN1bHQpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzIHJlc3VsdCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkTmVzdGVkRW51bV8gPSByZXBlYXRlZE5lc3RlZEVudW1fOwogICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEZvcmVpZ25FbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5yZXBlYXRlZEZvcmVpZ25FbnVtXyA9IHJlcGVhdGVkRm9yZWlnbkVudW1fOwogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRMYXp5TWVzc2FnZV8pOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSByZXBlYXRlZExhenlNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyXyA9IG9wdGlvbmFsSW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50NjRfID0gb3B0aW9uYWxJbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxVaW50MzJfID0gb3B0aW9uYWxVaW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVWludDY0XyA9IG9wdGlvbmFsVWludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFNpbnQzMl8gPSBvcHRpb25hbFNpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTaW50NjRfID0gb3B0aW9uYWxTaW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRml4ZWQzMl8gPSBvcHRpb25hbEZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRml4ZWQ2NF8gPSBvcHRpb25hbEZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsU2ZpeGVkMzJfID0gb3B0aW9uYWxTZml4ZWQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTZml4ZWQ2NF8gPSBvcHRpb25hbFNmaXhlZDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEZsb2F0XyA9IG9wdGlvbmFsRmxvYXRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRG91YmxlXyA9IG9wdGlvbmFsRG91YmxlXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEJvb2xfID0gb3B0aW9uYWxCb29sXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFN0cmluZ18gPSBvcHRpb25hbFN0cmluZ187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxCeXRlc18gPSBvcHRpb25hbEJ5dGVzXzsKICAgICAgICB9CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPSBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPSBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbEltcG9ydE1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsTmVzdGVkRW51bV8gPSBvcHRpb25hbE5lc3RlZEVudW1fOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRm9yZWlnbkVudW1fID0gb3B0aW9uYWxGb3JlaWduRW51bV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTdHJpbmdQaWVjZV8gPSBvcHRpb25hbFN0cmluZ1BpZWNlXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbENvcmRfID0gb3B0aW9uYWxDb3JkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID0gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXwogICAgICAgICAgICAgIDogb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbExhenlNZXNzYWdlXyA9IG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbExhenlNZXNzYWdlXwogICAgICAgICAgICAgIDogb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbnQzMl8gPSByZXBlYXRlZEludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEludDY0XyA9IHJlcGVhdGVkSW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFVpbnQzMl8gPSByZXBlYXRlZFVpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkVWludDY0XyA9IHJlcGVhdGVkVWludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTaW50MzJfID0gcmVwZWF0ZWRTaW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNpbnQ2NF8gPSByZXBlYXRlZFNpbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZpeGVkMzJfID0gcmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRml4ZWQ2NF8gPSByZXBlYXRlZEZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMShwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQxXyA9IGJpdEZpZWxkMV87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNmaXhlZDMyXyA9IHJlcGVhdGVkU2ZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2ZpeGVkNjRfID0gcmVwZWF0ZWRTZml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRGbG9hdF8gPSByZXBlYXRlZEZsb2F0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWREb3VibGVfID0gcmVwZWF0ZWREb3VibGVfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRCb29sXyA9IHJlcGVhdGVkQm9vbF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nXyA9IHJlcGVhdGVkU3RyaW5nXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQnl0ZXNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEJ5dGVzXyA9IHJlcGVhdGVkQnl0ZXNfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nUGllY2VfID0gcmVwZWF0ZWRTdHJpbmdQaWVjZV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZENvcmRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZENvcmRfID0gcmVwZWF0ZWRDb3JkXzsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxPbmVvZnMocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzIHJlc3VsdCkgewogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkQ2FzZV8gPSBvbmVvZkZpZWxkQ2FzZV87CiAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRfID0gdGhpcy5vbmVvZkZpZWxkXzsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMiAmJgogICAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbEludDMyKCkgIT0gMCkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQzMihvdGhlci5nZXRPcHRpb25hbEludDMyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxJbnQ2NCgpICE9IDBMKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDY0KG90aGVyLmdldE9wdGlvbmFsSW50NjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbFVpbnQzMigpICE9IDApIHsKICAgICAgICAgIHNldE9wdGlvbmFsVWludDMyKG90aGVyLmdldE9wdGlvbmFsVWludDMyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxVaW50NjQoKSAhPSAwTCkgewogICAgICAgICAgc2V0T3B0aW9uYWxVaW50NjQob3RoZXIuZ2V0T3B0aW9uYWxVaW50NjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbFNpbnQzMigpICE9IDApIHsKICAgICAgICAgIHNldE9wdGlvbmFsU2ludDMyKG90aGVyLmdldE9wdGlvbmFsU2ludDMyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxTaW50NjQoKSAhPSAwTCkgewogICAgICAgICAgc2V0T3B0aW9uYWxTaW50NjQob3RoZXIuZ2V0T3B0aW9uYWxTaW50NjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbEZpeGVkMzIoKSAhPSAwKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEZpeGVkMzIob3RoZXIuZ2V0T3B0aW9uYWxGaXhlZDMyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxGaXhlZDY0KCkgIT0gMEwpIHsKICAgICAgICAgIHNldE9wdGlvbmFsRml4ZWQ2NChvdGhlci5nZXRPcHRpb25hbEZpeGVkNjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbFNmaXhlZDMyKCkgIT0gMCkgewogICAgICAgICAgc2V0T3B0aW9uYWxTZml4ZWQzMihvdGhlci5nZXRPcHRpb25hbFNmaXhlZDMyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpICE9IDBMKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFNmaXhlZDY0KG90aGVyLmdldE9wdGlvbmFsU2ZpeGVkNjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbEZsb2F0KCkgIT0gMEYpIHsKICAgICAgICAgIHNldE9wdGlvbmFsRmxvYXQob3RoZXIuZ2V0T3B0aW9uYWxGbG9hdCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsRG91YmxlKCkgIT0gMEQpIHsKICAgICAgICAgIHNldE9wdGlvbmFsRG91YmxlKG90aGVyLmdldE9wdGlvbmFsRG91YmxlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxCb29sKCkgIT0gZmFsc2UpIHsKICAgICAgICAgIHNldE9wdGlvbmFsQm9vbChvdGhlci5nZXRPcHRpb25hbEJvb2woKSk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZ2V0T3B0aW9uYWxTdHJpbmcoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IG90aGVyLm9wdGlvbmFsU3RyaW5nXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxCeXRlcygpICE9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSkgewogICAgICAgICAgc2V0T3B0aW9uYWxCeXRlcyhvdGhlci5nZXRPcHRpb25hbEJ5dGVzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbEZvcmVpZ25NZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbEltcG9ydE1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIub3B0aW9uYWxOZXN0ZWRFbnVtXyAhPSAwKSB7CiAgICAgICAgICBzZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZShvdGhlci5nZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLm9wdGlvbmFsRm9yZWlnbkVudW1fICE9IDApIHsKICAgICAgICAgIHNldE9wdGlvbmFsRm9yZWlnbkVudW1WYWx1ZShvdGhlci5nZXRPcHRpb25hbEZvcmVpZ25FbnVtVmFsdWUoKSk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZSgpLmlzRW1wdHkoKSkgewogICAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSBvdGhlci5vcHRpb25hbFN0cmluZ1BpZWNlXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmdldE9wdGlvbmFsQ29yZCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgb3B0aW9uYWxDb3JkXyA9IG90aGVyLm9wdGlvbmFsQ29yZF87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZShvdGhlci5nZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbExhenlNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxMYXp5TWVzc2FnZShvdGhlci5nZXRPcHRpb25hbExhenlNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEludDMyXyA9IG90aGVyLnJlcGVhdGVkSW50MzJfOwogICAgICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkSW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEludDY0XyA9IG90aGVyLnJlcGVhdGVkSW50NjRfOwogICAgICAgICAgICByZXBlYXRlZEludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkVWludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFVpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXyA9IG90aGVyLnJlcGVhdGVkVWludDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZFVpbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRVaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkVWludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gb3RoZXIucmVwZWF0ZWRVaW50NjRfOwogICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkVWludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8gPSBvdGhlci5yZXBlYXRlZFNpbnQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTaW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2ludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IG90aGVyLnJlcGVhdGVkU2ludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNpbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gb3RoZXIucmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZEZpeGVkMzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IG90aGVyLnJlcGVhdGVkRml4ZWQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGaXhlZDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNmaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNmaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBvdGhlci5yZXBlYXRlZFNmaXhlZDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNmaXhlZDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNmaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNmaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBvdGhlci5yZXBlYXRlZFNmaXhlZDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNmaXhlZDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZsb2F0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEZsb2F0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBvdGhlci5yZXBlYXRlZEZsb2F0XzsKICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEZsb2F0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZERvdWJsZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWREb3VibGVfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBvdGhlci5yZXBlYXRlZERvdWJsZV87CiAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWREb3VibGVfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQm9vbF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRCb29sXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRCb29sXyA9IG90aGVyLnJlcGVhdGVkQm9vbF87CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRCb29sXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRCb29sXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZ18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmdfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFN0cmluZ18gPSBvdGhlci5yZXBlYXRlZFN0cmluZ187CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmdfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQnl0ZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkQnl0ZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEJ5dGVzXyA9IG90aGVyLnJlcGVhdGVkQnl0ZXNfOwogICAgICAgICAgICByZXBlYXRlZEJ5dGVzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRCeXRlc18uYWRkQWxsKG90aGVyLnJlcGVhdGVkQnl0ZXNfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwODApOwogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRJbXBvcnRNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkSW1wb3J0TWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAyMDApOwogICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZEltcG9ydE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IG90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV87CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZEFsbChvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRm9yZWlnbkVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbkVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXyA9IG90aGVyLnJlcGVhdGVkRm9yZWlnbkVudW1fOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLmFkZEFsbChvdGhlci5yZXBlYXRlZEZvcmVpZ25FbnVtXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZ1BpZWNlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFN0cmluZ1BpZWNlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8gPSBvdGhlci5yZXBlYXRlZFN0cmluZ1BpZWNlXzsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdQaWVjZUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmdQaWVjZV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRDb3JkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZENvcmRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZENvcmRfID0gb3RoZXIucmVwZWF0ZWRDb3JkXzsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRDb3JkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkQ29yZF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkQ29yZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZExhenlNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRMYXp5TWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDQwMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRMYXp5TWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTGF6eU1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkTGF6eU1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIucmVwZWF0ZWRMYXp5TWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHN3aXRjaCAob3RoZXIuZ2V0T25lb2ZGaWVsZENhc2UoKSkgewogICAgICAgICAgY2FzZSBPTkVPRl9VSU5UMzI6IHsKICAgICAgICAgICAgc2V0T25lb2ZVaW50MzIob3RoZXIuZ2V0T25lb2ZVaW50MzIoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBPTkVPRl9ORVNURURfTUVTU0FHRTogewogICAgICAgICAgICBtZXJnZU9uZW9mTmVzdGVkTWVzc2FnZShvdGhlci5nZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBPTkVPRl9TVFJJTkc6IHsKICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTEzOwogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IG90aGVyLm9uZW9mRmllbGRfOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GX0JZVEVTOiB7CiAgICAgICAgICAgIHNldE9uZW9mQnl0ZXMob3RoZXIuZ2V0T25lb2ZCeXRlcygpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GRklFTERfTk9UX1NFVDogewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDY0XyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxVaW50MzJfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgICAgY2FzZSAzMjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxVaW50NjRfID0gaW5wdXQucmVhZFVJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyCiAgICAgICAgICAgICAgY2FzZSA0MDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxTaW50MzJfID0gaW5wdXQucmVhZFNJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQwCiAgICAgICAgICAgICAgY2FzZSA0ODogewogICAgICAgICAgICAgICAgb3B0aW9uYWxTaW50NjRfID0gaW5wdXQucmVhZFNJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ4CiAgICAgICAgICAgICAgY2FzZSA2MTogewogICAgICAgICAgICAgICAgb3B0aW9uYWxGaXhlZDMyXyA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjEKICAgICAgICAgICAgICBjYXNlIDY1OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEZpeGVkNjRfID0gaW5wdXQucmVhZEZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NQogICAgICAgICAgICAgIGNhc2UgNzc6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsU2ZpeGVkMzJfID0gaW5wdXQucmVhZFNGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzcKICAgICAgICAgICAgICBjYXNlIDgxOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFNmaXhlZDY0XyA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxCiAgICAgICAgICAgICAgY2FzZSA5MzogewogICAgICAgICAgICAgICAgb3B0aW9uYWxGbG9hdF8gPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MwogICAgICAgICAgICAgIGNhc2UgOTc6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsRG91YmxlXyA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NwogICAgICAgICAgICAgIGNhc2UgMTA0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEJvb2xfID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDQKICAgICAgICAgICAgICBjYXNlIDExNDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE0CiAgICAgICAgICAgICAgY2FzZSAxMjI6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsQnl0ZXNfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIyCiAgICAgICAgICAgICAgY2FzZSAxNDY6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ2CiAgICAgICAgICAgICAgY2FzZSAxNTQ6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1NAogICAgICAgICAgICAgIGNhc2UgMTYyOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MgogICAgICAgICAgICAgIGNhc2UgMTY4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjgKICAgICAgICAgICAgICBjYXNlIDE3NjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxGb3JlaWduRW51bV8gPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE3NgogICAgICAgICAgICAgIGNhc2UgMTk0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE5NAogICAgICAgICAgICAgIGNhc2UgMjAyOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbENvcmRfID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjAyCiAgICAgICAgICAgICAgY2FzZSAyMTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjEwCiAgICAgICAgICAgICAgY2FzZSAyMTg6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxOAogICAgICAgICAgICAgIGNhc2UgMjQ4OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0OAogICAgICAgICAgICAgIGNhc2UgMjUwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTAKICAgICAgICAgICAgICBjYXNlIDI1NjogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1NgogICAgICAgICAgICAgIGNhc2UgMjU4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjU4CiAgICAgICAgICAgICAgY2FzZSAyNjQ6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjY0CiAgICAgICAgICAgICAgY2FzZSAyNjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEludChpbnB1dC5yZWFkVUludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2NgogICAgICAgICAgICAgIGNhc2UgMjcyOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjcyCiAgICAgICAgICAgICAgY2FzZSAyNzQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNzQKICAgICAgICAgICAgICBjYXNlIDI4MDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODAKICAgICAgICAgICAgICBjYXNlIDI4MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkSW50KGlucHV0LnJlYWRTSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjgyCiAgICAgICAgICAgICAgY2FzZSAyODg6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODgKICAgICAgICAgICAgICBjYXNlIDI5MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5MAogICAgICAgICAgICAgIGNhc2UgMzAxOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMwMQogICAgICAgICAgICAgIGNhc2UgMjk4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KGlucHV0LnJlYWRGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5OAogICAgICAgICAgICAgIGNhc2UgMzA1OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzA1CiAgICAgICAgICAgICAgY2FzZSAzMDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRMb25nKGlucHV0LnJlYWRGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMwNgogICAgICAgICAgICAgIGNhc2UgMzE3OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMxNwogICAgICAgICAgICAgIGNhc2UgMzE0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQoaW5wdXQucmVhZFNGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMxNAogICAgICAgICAgICAgIGNhc2UgMzIxOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIxCiAgICAgICAgICAgICAgY2FzZSAzMjI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcoaW5wdXQucmVhZFNGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyMgogICAgICAgICAgICAgIGNhc2UgMzMzOiB7CiAgICAgICAgICAgICAgICBmbG9hdCB2ID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMzMKICAgICAgICAgICAgICBjYXNlIDMzMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkRmxvYXQoaW5wdXQucmVhZEZsb2F0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzMAogICAgICAgICAgICAgIGNhc2UgMzM3OiB7CiAgICAgICAgICAgICAgICBkb3VibGUgdiA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkRG91YmxlKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzNwogICAgICAgICAgICAgIGNhc2UgMzM4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfLmFkZERvdWJsZShpbnB1dC5yZWFkRG91YmxlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzOAogICAgICAgICAgICAgIGNhc2UgMzQ0OiB7CiAgICAgICAgICAgICAgICBib29sZWFuIHYgPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEJvb2xlYW4odik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQ0CiAgICAgICAgICAgICAgY2FzZSAzNDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoYWxsb2MgLyAxKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRCb29sXy5hZGRCb29sZWFuKGlucHV0LnJlYWRCb29sKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0NgogICAgICAgICAgICAgIGNhc2UgMzU0OiB7CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZ18uYWRkKHMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM1NAogICAgICAgICAgICAgIGNhc2UgMzYyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdiA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRCeXRlc18uYWRkKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM2MgogICAgICAgICAgICAgIGNhc2UgMzg2OiB7CiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UucGFyc2VyKCksCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzg2CiAgICAgICAgICAgICAgY2FzZSAzOTQ6IHsKICAgICAgICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZS5wYXJzZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzk0CiAgICAgICAgICAgICAgY2FzZSA0MDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAyCiAgICAgICAgICAgICAgY2FzZSA0MDg6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQwOAogICAgICAgICAgICAgIGNhc2UgNDEwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDEwCiAgICAgICAgICAgICAgY2FzZSA0MTY6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDE2CiAgICAgICAgICAgICAgY2FzZSA0MTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQxOAogICAgICAgICAgICAgIGNhc2UgNDM0OiB7CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfLmFkZChzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MzQKICAgICAgICAgICAgICBjYXNlIDQ0MjogewogICAgICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZENvcmRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkQ29yZF8uYWRkKHMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ0MgogICAgICAgICAgICAgIGNhc2UgNDU4OiB7CiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UucGFyc2VyKCksCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ1OAogICAgICAgICAgICAgIGNhc2UgODg4OiB7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4ODgKICAgICAgICAgICAgICBjYXNlIDg5ODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4OTgKICAgICAgICAgICAgICBjYXNlIDkwNjogewogICAgICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTM7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTA2CiAgICAgICAgICAgICAgY2FzZSA5MTQ6IHsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTE0CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9uZW9mRmllbGRfOwogICAgICBwdWJsaWMgT25lb2ZGaWVsZENhc2UKICAgICAgICAgIGdldE9uZW9mRmllbGRDYXNlKCkgewogICAgICAgIHJldHVybiBPbmVvZkZpZWxkQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZGaWVsZCgpIHsKICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQxXzsKCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFNpbmd1bGFyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5pbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBTaW5ndWxhcgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+aW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFNpbmd1bGFyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5pbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9wdGlvbmFsSW50MzJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsSW50NjRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQ2NCBvcHRpb25hbF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb3B0aW9uYWxJbnQ2NF8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBvcHRpb25hbF91aW50MzIgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9wdGlvbmFsX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsVWludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsVWludDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9wdGlvbmFsX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsVWludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvcHRpb25hbFVpbnQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxVaW50NjRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50NjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsVWludDY0KCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFVpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVWludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxVaW50NjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9wdGlvbmFsVWludDY0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFNpbnQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFNpbnQzMigpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxTaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFNpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxTaW50MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTaW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9wdGlvbmFsU2ludDMyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFNpbnQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxTaW50NjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsU2ludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU2ludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbFNpbnQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQ2NCBvcHRpb25hbF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFNpbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb3B0aW9uYWxTaW50NjRfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsRml4ZWQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEZpeGVkMzIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsRml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxGaXhlZDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxGaXhlZDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvcHRpb25hbEZpeGVkMzJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsRml4ZWQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQ2NCBvcHRpb25hbF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxGaXhlZDY0KCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEZpeGVkNjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9wdGlvbmFsRml4ZWQ2NF8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZml4ZWQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZml4ZWQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFNmaXhlZDMyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFNmaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFNmaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTZml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxTZml4ZWQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTZml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb3B0aW9uYWxTZml4ZWQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxTZml4ZWQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsU2ZpeGVkNjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsU2ZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFNmaXhlZDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTZml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsU2ZpeGVkNjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFNmaXhlZDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvcHRpb25hbFNmaXhlZDY0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IG9wdGlvbmFsRmxvYXRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZsb2F0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0T3B0aW9uYWxGbG9hdCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxGbG9hdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEZsb2F0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsRmxvYXRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5mbG9hdCBvcHRpb25hbF9mbG9hdCA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEZsb2F0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvcHRpb25hbEZsb2F0XyA9IDBGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGRvdWJsZSBvcHRpb25hbERvdWJsZV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxEb3VibGUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0T3B0aW9uYWxEb3VibGUoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsRG91YmxlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbERvdWJsZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRG91YmxlKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbERvdWJsZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmRvdWJsZSBvcHRpb25hbF9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxEb3VibGUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9wdGlvbmFsRG91YmxlXyA9IDBEOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gb3B0aW9uYWxCb29sXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQm9vbC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0T3B0aW9uYWxCb29sKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEJvb2xfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxCb29sIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxCb29sKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxCb29sXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ym9vbCBvcHRpb25hbF9ib29sID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsQm9vbCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb3B0aW9uYWxCb29sXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gczsKICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9wdGlvbmFsU3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFN0cmluZygpIHsKICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbFN0cmluZygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgb3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvcHRpb25hbF9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlcy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEJ5dGVzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxCeXRlcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQnl0ZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbEJ5dGVzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxCeXRlcygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb3B0aW9uYWxCeXRlc18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbEJ5dGVzKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyAhPSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGb3JlaWduTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGb3JlaWduTWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID09IG51bGwgPyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxGb3JlaWduTWVzc2FnZShwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gIT0gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbXBvcnRNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxJbXBvcnRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsSW1wb3J0TWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxOZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZEVudW1fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbE5lc3RlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5mb3JOdW1iZXIob3B0aW9uYWxOZXN0ZWRFbnVtXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxOZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRFbnVtKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxOZXN0ZWRFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxGb3JlaWduRW51bV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldE9wdGlvbmFsRm9yZWlnbkVudW1WYWx1ZSgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduRW51bV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbEZvcmVpZ25FbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxGb3JlaWduRW51bVZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbkVudW0gZ2V0T3B0aW9uYWxGb3JlaWduRW51bSgpIHsKICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bSByZXN1bHQgPSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bS5mb3JOdW1iZXIob3B0aW9uYWxGb3JlaWduRW51bV8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25FbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEZvcmVpZ25FbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxGb3JlaWduRW51bShwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxGb3JlaWduRW51bSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgb3B0aW9uYWxGb3JlaWduRW51bV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmdQaWVjZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nUGllY2UoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ1BpZWNlXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gczsKICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nUGllY2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRPcHRpb25hbFN0cmluZ1BpZWNlQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ1BpZWNlXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTdHJpbmdQaWVjZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU3RyaW5nUGllY2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU3RyaW5nUGllY2UoKSB7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbFN0cmluZ1BpZWNlKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZ1BpZWNlQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbENvcmRfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxDb3JkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxDb3JkKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxDb3JkXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIG9wdGlvbmFsQ29yZF8gPSBzOwogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbENvcmQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRPcHRpb25hbENvcmRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsQ29yZF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIG9wdGlvbmFsQ29yZF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbENvcmQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbENvcmQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbENvcmRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbENvcmQoKSB7CiAgICAgICAgb3B0aW9uYWxDb3JkXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldE9wdGlvbmFsQ29yZCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsQ29yZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQ29yZEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIG9wdGlvbmFsQ29yZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyPiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbExhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlXyA9PSBudWxsID8gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbExhenlNZXNzYWdlKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbExhenlNZXNzYWdlKAogICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTGF6eU1lc3NhZ2UocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfICE9IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkSW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEludDMyKCkgewogICAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRJbnQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkSW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkSW50NjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkSW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRJbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRJbnQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRJbnQ2NCgpIHsKICAgICAgICByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFVpbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkVWludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFVpbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVWludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRVaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVWludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFVpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkVWludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRVaW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFVpbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFVpbnQzMigpIHsKICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkVWludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkVWludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkVWludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkVWludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFVpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFVpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkVWludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkVWludDY0KCkgewogICAgICAgIHJlcGVhdGVkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNpbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNpbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2ludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTaW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFNpbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNpbnQzMigpIHsKICAgICAgICByZXBlYXRlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2ludDY0KCkgewogICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaXhlZDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGaXhlZDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRml4ZWQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRml4ZWQzMigpIHsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkNjRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRGaXhlZDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpeGVkNjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGaXhlZDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRml4ZWQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRml4ZWQ2NCgpIHsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQzMl8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNmaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTZml4ZWQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNmaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNmaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTZml4ZWQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTZml4ZWQzMigpIHsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDY0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRTZml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ZpeGVkNjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNmaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2ZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNmaXhlZDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFNmaXhlZDY0Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNmaXhlZDY0KCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRmxvYXRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRmxvYXRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRmxvYXRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGZsb2F0IGdldFJlcGVhdGVkRmxvYXQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZsb2F0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGbG9hdCgKICAgICAgICAgIGludCBpbmRleCwgZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfLnNldEZsb2F0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZsb2F0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkRmxvYXQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZsb2F0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRGbG9hdF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRGbG9hdCgpIHsKICAgICAgICByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWREb3VibGVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWREb3VibGVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRG91YmxlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRG91YmxlXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRG91YmxlLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZERvdWJsZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0UmVwZWF0ZWREb3VibGUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXy5nZXREb3VibGUoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWREb3VibGUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZERvdWJsZSgKICAgICAgICAgIGludCBpbmRleCwgZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfLnNldERvdWJsZShpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZERvdWJsZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRG91YmxlKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRG91YmxlXy5hZGREb3VibGUodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWREb3VibGUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZERvdWJsZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWREb3VibGVfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWREb3VibGUoKSB7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgcmVwZWF0ZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQm9vbF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkQm9vbF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRCb29sXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRCb29sXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEJvb2xfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2wuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRSZXBlYXRlZEJvb2xMaXN0KCkgewogICAgICAgIHJlcGVhdGVkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCb29sQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJvb2wgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gZ2V0UmVwZWF0ZWRCb29sKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJvb2wgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEJvb2woCiAgICAgICAgICBpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCb29sXy5zZXRCb29sZWFuKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRCb29sIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRCb29sKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCb29sXy5hZGRCb29sZWFuKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRCb29sIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRCb29sKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkQm9vbF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQm9vbCgpIHsKICAgICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTdHJpbmdfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZ18gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KHJlcGVhdGVkU3RyaW5nXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZ0NvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0J5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTdHJpbmcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFN0cmluZyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU3RyaW5nXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nKCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMjApOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gcmVwZWF0ZWRCeXRlc18gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEJ5dGVzXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRCeXRlc18gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRCeXRlc18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJ5dGVzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldFJlcGVhdGVkQnl0ZXNMaXN0KCkgewogICAgICAgIHJlcGVhdGVkQnl0ZXNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJ5dGVzLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJ5dGVzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJ5dGVzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc18uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJ5dGVzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRCeXRlcygKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEJ5dGVzSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCeXRlc18uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJ5dGVzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRCeXRlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJ5dGVzXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkQnl0ZXMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEJ5dGVzKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRCeXRlc18pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRCeXRlcygpIHsKICAgICAgICByZXBlYXRlZEJ5dGVzXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4ocmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZShwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IHZhbHVlcykgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQxXyAmIDB4MDAwMDAwODApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZT4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMV8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZT4ocmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8pOwogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZT4gZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKAogICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQxXyAmIDB4MDAwMDAxMDApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlPiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMV8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlPihyZXBlYXRlZEltcG9ydE1lc3NhZ2VfKTsKICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlPiBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAyMDApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZEltcG9ydE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEltcG9ydE1lc3NhZ2VfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDFfICYgMHgwMDAwMDIwMCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZE5lc3RlZEVudW1fID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMV8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPihyZXBlYXRlZE5lc3RlZEVudW1fLCByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1Db3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkRW51bSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZEVudW0ocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE5lc3RlZEVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWROZXN0ZWRFbnVtKCkgewogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAoaW50IHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZEZvcmVpZ25FbnVtXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQxXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZEZvcmVpZ25FbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25FbnVtPiBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bT4ocmVwZWF0ZWRGb3JlaWduRW51bV8sIHJlcGVhdGVkRm9yZWlnbkVudW1fY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRm9yZWlnbkVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRm9yZWlnbkVudW1Db3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGb3JlaWduRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbkVudW0gZ2V0UmVwZWF0ZWRGb3JlaWduRW51bShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRGb3JlaWduRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGb3JlaWduRW51bSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbkVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbkVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGb3JlaWduRW51bShwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRm9yZWlnbkVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZvcmVpZ25FbnVtKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbkVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRm9yZWlnbkVudW0oKSB7CiAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWVMaXN0KCkgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEZvcmVpZ25FbnVtXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkRm9yZWlnbkVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbkVudW1fLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkRm9yZWlnbkVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWUoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbkVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkRm9yZWlnbkVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWUoaW50IHZhbHVlKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkRm9yZWlnbkVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbkVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKGludCB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nUGllY2VfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZ1BpZWNlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KHJlcGVhdGVkU3RyaW5nUGllY2VfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nUGllY2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmdQaWVjZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nUGllY2UgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFN0cmluZ1BpZWNlKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nUGllY2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nUGllY2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdQaWVjZUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZ1BpZWNlXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmdQaWVjZSgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDEwMDApOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmdQaWVjZUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRDb3JkXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZENvcmRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZENvcmRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZENvcmRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZENvcmRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRDb3JkLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZENvcmRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkQ29yZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZENvcmRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRDb3JkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZENvcmRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRDb3JkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkQ29yZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRDb3JkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkQ29yZEJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZENvcmRfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQ29yZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQ29yZCgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRDb3JkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRDb3JkXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQ29yZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQ29yZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQ29yZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQ29yZF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZENvcmQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZENvcmQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRDb3JkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkQ29yZF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRDb3JkKCkgewogICAgICAgIHJlcGVhdGVkQ29yZF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAyMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZENvcmQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZENvcmRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBlbnN1cmVSZXBlYXRlZENvcmRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZENvcmRfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiByZXBlYXRlZExhenlNZXNzYWdlXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQxXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPihyZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTGF6eU1lc3NhZ2VfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZExhenlNZXNzYWdlQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZV8uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRMYXp5TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTGF6eU1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRMYXp5TWVzc2FnZShwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTGF6eU1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZExhenlNZXNzYWdlKAogICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRMYXp5TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZExhenlNZXNzYWdlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkTGF6eU1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRMYXp5TWVzc2FnZV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDFfICYgMHgwMDAwNDAwMCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlVpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlVpbnQzMigpIHsKICAgICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDExMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9uZW9mVWludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRPbmVvZlVpbnQzMigpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMSkgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVvZlVpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mVWludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTE7CiAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDExMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZVaW50MzIoKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTEpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExMjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb25lb2ZOZXN0ZWRNZXNzYWdlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICAgICByZXR1cm4gKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICAgICAgcmV0dXJuIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZk5lc3RlZE1lc3NhZ2UocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZk5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9uZW9mTmVzdGVkTWVzc2FnZShwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMiAmJgogICAgICAgICAgICAgIG9uZW9mRmllbGRfICE9IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfKQogICAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTEyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZk5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmICgob25lb2ZGaWVsZENhc2VfID09IDExMikgJiYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgICByZXR1cm4gb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICAgICByZXR1cm4gKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIShvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSkgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgICAgfQogICAgICAgICAgb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICAocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlN0cmluZygpIHsKICAgICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExMzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9uZW9mU3RyaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPbmVvZlN0cmluZygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgICByZWYgPSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9uZW9mU3RyaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRPbmVvZlN0cmluZ0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVvZlN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTEzOwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mU3RyaW5nKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZlN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMzsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZCeXRlcygpIHsKICAgICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExNDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZkJ5dGVzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPbmVvZkJ5dGVzKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0KSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVvZkJ5dGVzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZCeXRlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExNDsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDExNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZCeXRlcygpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNCkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RBbGxUeXBlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0QWxsVHlwZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0QWxsVHlwZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0QWxsVHlwZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEFsbFR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0UGFja2VkVHlwZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkSW50MzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQzMi4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkSW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZEludDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50NjQuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRJbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRQYWNrZWRJbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkVWludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkVWludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRVaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRVaW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRVaW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFVpbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZFVpbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDY0LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkVWludDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRVaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFBhY2tlZFVpbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkU2ludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRTaW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRTaW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNpbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZFNpbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ludDY0LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2ludDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFBhY2tlZFNpbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGaXhlZDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkRml4ZWQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkRml4ZWQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRGaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEZpeGVkMzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRml4ZWQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZEZpeGVkNjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRml4ZWQ2NC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UGFja2VkRml4ZWQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNmaXhlZDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldFBhY2tlZFNmaXhlZDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2ZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2ZpeGVkMzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZml4ZWQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZFNmaXhlZDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ZpeGVkNjQuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRTZml4ZWQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNmaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRQYWNrZWRTZml4ZWQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGbG9hdC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PiBnZXRQYWNrZWRGbG9hdExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGbG9hdC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEZsb2F0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZmxvYXQgZ2V0UGFja2VkRmxvYXQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWREb3VibGUuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+IGdldFBhY2tlZERvdWJsZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZERvdWJsZS4KICAgICAqLwogICAgaW50IGdldFBhY2tlZERvdWJsZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZERvdWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGRvdWJsZSBnZXRQYWNrZWREb3VibGUoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEJvb2wuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPiBnZXRQYWNrZWRCb29sTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRCb29sLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkQm9vbENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0UGFja2VkQm9vbChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bT4gZ2V0UGFja2VkRW51bUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRFbnVtLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbkVudW0gZ2V0UGFja2VkRW51bShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHBhY2tlZEVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UGFja2VkRW51bVZhbHVlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEVudW1WYWx1ZShpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0UGFja2VkVHlwZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0UGFja2VkVHlwZXMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzKQogICAgICBUZXN0UGFja2VkVHlwZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RQYWNrZWRUeXBlcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0UGFja2VkVHlwZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0UGFja2VkVHlwZXMoKSB7CiAgICAgIHBhY2tlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHBhY2tlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcGFja2VkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcGFja2VkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwYWNrZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcGFja2VkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHBhY2tlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcGFja2VkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcGFja2VkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBwYWNrZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcGFja2VkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFBhY2tlZFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0UGFja2VkVHlwZXMuY2xhc3MsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfSU5UMzJfRklFTERfTlVNQkVSID0gOTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZEludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFBhY2tlZEludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9JTlQ2NF9GSUVMRF9OVU1CRVIgPSA5MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZEludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRQYWNrZWRJbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkSW50NjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRJbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9VSU5UMzJfRklFTERfTlVNQkVSID0gOTI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZFVpbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRVaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRQYWNrZWRVaW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkVWludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFVpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkVWludDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRVaW50MzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRVaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1VJTlQ2NF9GSUVMRF9OVU1CRVIgPSA5MzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFVpbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkVWludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UGFja2VkVWludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFVpbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZFVpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRVaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1NJTlQzMl9GSUVMRF9OVU1CRVIgPSA5NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkU2ludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFBhY2tlZFNpbnQzMkxpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTaW50MzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZFNpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfU0lOVDY0X0ZJRUxEX05VTUJFUiA9IDk1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkU2ludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRQYWNrZWRTaW50NjRMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkU2ludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ludDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkU2ludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UGFja2VkU2ludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkU2ludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZFNpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA5NjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkRml4ZWQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEZpeGVkMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRQYWNrZWRGaXhlZDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEZpeGVkMzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkRml4ZWQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRGaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDk3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkRml4ZWQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGaXhlZDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UGFja2VkRml4ZWQ2NExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRGaXhlZDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkNjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRGaXhlZDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkRml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRGaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9TRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA5ODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkU2ZpeGVkMzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNmaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkU2ZpeGVkMzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ZpeGVkMzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkU2ZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1NGSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDk5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkU2ZpeGVkNjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFBhY2tlZFNmaXhlZDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNmaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNmaXhlZDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZFNmaXhlZDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkU2ZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkU2ZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0ZMT0FUX0ZJRUxEX05VTUJFUiA9IDEwMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCBwYWNrZWRGbG9hdF8gPQogICAgICAgIGVtcHR5RmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZ2V0UGFja2VkRmxvYXRMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkRmxvYXRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEZsb2F0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZsb2F0Q291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRGbG9hdF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZmxvYXQgZ2V0UGFja2VkRmxvYXQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRGbG9hdF8uZ2V0RmxvYXQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkRmxvYXRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0RPVUJMRV9GSUVMRF9OVU1CRVIgPSAxMDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHBhY2tlZERvdWJsZV8gPQogICAgICAgIGVtcHR5RG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRG91YmxlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBnZXRQYWNrZWREb3VibGVMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkRG91YmxlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZERvdWJsZS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWREb3VibGVDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZERvdWJsZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZG91YmxlIGdldFBhY2tlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZERvdWJsZV8uZ2V0RG91YmxlKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZERvdWJsZU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfQk9PTF9GSUVMRF9OVU1CRVIgPSAxMDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCBwYWNrZWRCb29sXyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRCb29sLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZ2V0UGFja2VkQm9vbExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRCb29sXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkQm9vbC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRCb29sQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRCb29sXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdldFBhY2tlZEJvb2woaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRCb29sXy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0VOVU1fRklFTERfTlVNQkVSID0gMTAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrZWRFbnVtXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bT4gcGFja2VkRW51bV9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25FbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbkVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bSByZXN1bHQgPSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bT4gZ2V0UGFja2VkRW51bUxpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bT4ocGFja2VkRW51bV8sIHBhY2tlZEVudW1fY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQYWNrZWRFbnVtQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRFbnVtXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25FbnVtIGdldFBhY2tlZEVudW0oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRFbnVtX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciBwYWNrZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRQYWNrZWRFbnVtVmFsdWVMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkRW51bV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHBhY2tlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEVudW1fLmdldChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRFbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZTsKCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIGlmIChnZXRQYWNrZWRJbnQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzIyKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkSW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzJOb1RhZyhwYWNrZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkSW50NjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDczMCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkSW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDY0Tm9UYWcocGFja2VkSW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRVaW50MzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDczOCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkVWludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRVaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkVWludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRVaW50NjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDc0Nik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkVWludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRVaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDY0Tm9UYWcocGFja2VkVWludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2ludDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3NTQpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZFNpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2ludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQzMk5vVGFnKHBhY2tlZFNpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2ludDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3NjIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZFNpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2ludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NE5vVGFnKHBhY2tlZFNpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEZpeGVkMzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDc3MCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkRml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkRml4ZWQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDMyTm9UYWcocGFja2VkRml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkRml4ZWQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzc4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRGaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRGaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjROb1RhZyhwYWNrZWRGaXhlZDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDc4Nik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2ZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNmaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyTm9UYWcocGFja2VkU2ZpeGVkMzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNmaXhlZDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3OTQpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZFNmaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRTZml4ZWQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQ2NE5vVGFnKHBhY2tlZFNmaXhlZDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkRmxvYXRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDgwMik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkRmxvYXRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEZsb2F0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0Tm9UYWcocGFja2VkRmxvYXRfLmdldEZsb2F0KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkRG91YmxlTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MTApOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZERvdWJsZU1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkRG91YmxlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZU5vVGFnKHBhY2tlZERvdWJsZV8uZ2V0RG91YmxlKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkQm9vbExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoODE4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRCb29sTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRCb29sXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJvb2xOb1RhZyhwYWNrZWRCb29sXy5nZXRCb29sZWFuKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkRW51bUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoODI2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRFbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRFbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW1Ob1RhZyhwYWNrZWRFbnVtXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKHBhY2tlZEludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkSW50MzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkSW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRJbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemVOb1RhZyhwYWNrZWRJbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRJbnQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRJbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFVpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcocGFja2VkVWludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkVWludDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZFVpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplTm9UYWcocGFja2VkVWludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZFVpbnQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRVaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZU5vVGFnKHBhY2tlZFNpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZFNpbnQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRTaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRTaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZU5vVGFnKHBhY2tlZFNpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRTaW50NjRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkU2ludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFBhY2tlZEZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRGaXhlZDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UGFja2VkRml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEZpeGVkNjRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkRml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRQYWNrZWRTZml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZFNmaXhlZDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZFNmaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFBhY2tlZFNmaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkU2ZpeGVkNjRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkU2ZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UGFja2VkRmxvYXRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRGbG9hdExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRGbG9hdE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRQYWNrZWREb3VibGVMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWREb3VibGVMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkRG91YmxlTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gMSAqIGdldFBhY2tlZEJvb2xMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRCb29sTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRFbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocGFja2VkRW51bV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEVudW1MaXN0KCkuaXNFbXB0eSgpKSB7ICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH1wYWNrZWRFbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFBhY2tlZFR5cGVzIG90aGVyID0gKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcykgb2JqOwoKICAgICAgaWYgKCFnZXRQYWNrZWRJbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRJbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRJbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRJbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRVaW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkVWludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZFVpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRVaW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkU2ludDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZFNpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRTaW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkU2ludDY0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkRml4ZWQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRGaXhlZDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkU2ZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkU2ZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkRmxvYXRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkRmxvYXRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkRG91YmxlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZERvdWJsZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRCb29sTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEJvb2xMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghcGFja2VkRW51bV8uZXF1YWxzKG90aGVyLnBhY2tlZEVudW1fKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChnZXRQYWNrZWRJbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRJbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRJbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRJbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRVaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9VSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZFVpbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRVaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9VSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZFVpbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9TSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZFNpbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9TSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZFNpbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRGaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfRklYRUQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkRml4ZWQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRGaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkRml4ZWQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTZml4ZWQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1NGSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRTZml4ZWQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTZml4ZWQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1NGSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRGbG9hdENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX0ZMT0FUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRGbG9hdExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWREb3VibGVDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9ET1VCTEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZERvdWJsZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRCb29sQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfQk9PTF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkQm9vbExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRFbnVtQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcGFja2VkRW51bV8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0UGFja2VkVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0UGFja2VkVHlwZXMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzKQogICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFBhY2tlZFR5cGVzLmNsYXNzLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0UGFja2VkVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0UGFja2VkVHlwZXMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHBhY2tlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHBhY2tlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBwYWNrZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcGFja2VkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBwYWNrZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcGFja2VkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBwYWNrZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHBhY2tlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHBhY2tlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHBhY2tlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBwYWNrZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIHBhY2tlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBwYWNrZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBwYWNrZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFBhY2tlZFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFBhY2tlZFR5cGVzIGJ1aWxkKCkgewogICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFBhY2tlZFR5cGVzIHJlc3VsdCA9IG5ldyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0UGFja2VkVHlwZXModGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFBhY2tlZFR5cGVzIHJlc3VsdCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChwYWNrZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5wYWNrZWRFbnVtXyA9IHBhY2tlZEVudW1fOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0UGFja2VkVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkSW50MzJfID0gcGFja2VkSW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRJbnQ2NF8gPSBwYWNrZWRJbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRVaW50MzJfID0gcGFja2VkVWludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZFVpbnQ2NF8gPSBwYWNrZWRVaW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkU2ludDMyXyA9IHBhY2tlZFNpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRTaW50NjRfID0gcGFja2VkU2ludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRGaXhlZDMyXyA9IHBhY2tlZEZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZEZpeGVkNjRfID0gcGFja2VkRml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZFNmaXhlZDMyXyA9IHBhY2tlZFNmaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkU2ZpeGVkNjRfID0gcGFja2VkU2ZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRGbG9hdF8gPSBwYWNrZWRGbG9hdF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWREb3VibGVfID0gcGFja2VkRG91YmxlXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRCb29sXyA9IHBhY2tlZEJvb2xfOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFBhY2tlZFR5cGVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0UGFja2VkVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmICghb3RoZXIucGFja2VkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkSW50MzJfID0gb3RoZXIucGFja2VkSW50MzJfOwogICAgICAgICAgICBwYWNrZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRJbnQzMl8uYWRkQWxsKG90aGVyLnBhY2tlZEludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRJbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkSW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRJbnQ2NF8gPSBvdGhlci5wYWNrZWRJbnQ2NF87CiAgICAgICAgICAgIHBhY2tlZEludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEludDY0Xy5hZGRBbGwob3RoZXIucGFja2VkSW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZFVpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkVWludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkVWludDMyXyA9IG90aGVyLnBhY2tlZFVpbnQzMl87CiAgICAgICAgICAgIHBhY2tlZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkVWludDMyXy5hZGRBbGwob3RoZXIucGFja2VkVWludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRVaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFVpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZFVpbnQ2NF8gPSBvdGhlci5wYWNrZWRVaW50NjRfOwogICAgICAgICAgICBwYWNrZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFVpbnQ2NF8uYWRkQWxsKG90aGVyLnBhY2tlZFVpbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkU2ludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRTaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRTaW50MzJfID0gb3RoZXIucGFja2VkU2ludDMyXzsKICAgICAgICAgICAgcGFja2VkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRTaW50MzJfLmFkZEFsbChvdGhlci5wYWNrZWRTaW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZFNpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkU2ludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkU2ludDY0XyA9IG90aGVyLnBhY2tlZFNpbnQ2NF87CiAgICAgICAgICAgIHBhY2tlZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkU2ludDY0Xy5hZGRBbGwob3RoZXIucGFja2VkU2ludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRGaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRGaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkRml4ZWQzMl8gPSBvdGhlci5wYWNrZWRGaXhlZDMyXzsKICAgICAgICAgICAgcGFja2VkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEZpeGVkMzJfLmFkZEFsbChvdGhlci5wYWNrZWRGaXhlZDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRGaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRGaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkRml4ZWQ2NF8gPSBvdGhlci5wYWNrZWRGaXhlZDY0XzsKICAgICAgICAgICAgcGFja2VkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEZpeGVkNjRfLmFkZEFsbChvdGhlci5wYWNrZWRGaXhlZDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRTZml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkU2ZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8gPSBvdGhlci5wYWNrZWRTZml4ZWQzMl87CiAgICAgICAgICAgIHBhY2tlZFNmaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFNmaXhlZDMyXy5hZGRBbGwob3RoZXIucGFja2VkU2ZpeGVkMzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZFNmaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZFNmaXhlZDY0XyA9IG90aGVyLnBhY2tlZFNmaXhlZDY0XzsKICAgICAgICAgICAgcGFja2VkU2ZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkU2ZpeGVkNjRfLmFkZEFsbChvdGhlci5wYWNrZWRTZml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkRmxvYXRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEZsb2F0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkRmxvYXRfID0gb3RoZXIucGFja2VkRmxvYXRfOwogICAgICAgICAgICBwYWNrZWRGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRGbG9hdF8uYWRkQWxsKG90aGVyLnBhY2tlZEZsb2F0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWREb3VibGVfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZERvdWJsZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZERvdWJsZV8gPSBvdGhlci5wYWNrZWREb3VibGVfOwogICAgICAgICAgICBwYWNrZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZERvdWJsZV8uYWRkQWxsKG90aGVyLnBhY2tlZERvdWJsZV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkQm9vbF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkQm9vbF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEJvb2xfID0gb3RoZXIucGFja2VkQm9vbF87CiAgICAgICAgICAgIHBhY2tlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkQm9vbElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRCb29sXy5hZGRBbGwob3RoZXIucGFja2VkQm9vbF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEVudW1fID0gb3RoZXIucGFja2VkRW51bV87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkRW51bV8uYWRkQWxsKG90aGVyLnBhY2tlZEVudW1fKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDcyMDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRJbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDcyMAogICAgICAgICAgICAgIGNhc2UgNzIyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZEludDMyXy5hZGRJbnQoaW5wdXQucmVhZEludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDcyMgogICAgICAgICAgICAgIGNhc2UgNzI4OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRJbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MjgKICAgICAgICAgICAgICBjYXNlIDczMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRJbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzMwCiAgICAgICAgICAgICAgY2FzZSA3MzY6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRVaW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MzYKICAgICAgICAgICAgICBjYXNlIDczODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkVWludDMyXy5hZGRJbnQoaW5wdXQucmVhZFVJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MzgKICAgICAgICAgICAgICBjYXNlIDc0NDogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFVJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRVaW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQ0CiAgICAgICAgICAgICAgY2FzZSA3NDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZFVpbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkVUludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0NgogICAgICAgICAgICAgIGNhc2UgNzUyOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkU2ludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzUyCiAgICAgICAgICAgICAgY2FzZSA3NTQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZFNpbnQzMl8uYWRkSW50KGlucHV0LnJlYWRTSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzU0CiAgICAgICAgICAgICAgY2FzZSA3NjA6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkU2ludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc2MAogICAgICAgICAgICAgIGNhc2UgNzYyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRTaW50NjRfLmFkZExvbmcoaW5wdXQucmVhZFNJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NjIKICAgICAgICAgICAgICBjYXNlIDc3MzogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkRml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc3MwogICAgICAgICAgICAgIGNhc2UgNzcwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQzMklzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRGaXhlZDMyXy5hZGRJbnQoaW5wdXQucmVhZEZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzcwCiAgICAgICAgICAgICAgY2FzZSA3Nzc6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRGaXhlZDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc3NwogICAgICAgICAgICAgIGNhc2UgNzc4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQ2NElzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRGaXhlZDY0Xy5hZGRMb25nKGlucHV0LnJlYWRGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc3OAogICAgICAgICAgICAgIGNhc2UgNzg5OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZFNmaXhlZDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzg5CiAgICAgICAgICAgICAgY2FzZSA3ODY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQzMklzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8uYWRkSW50KGlucHV0LnJlYWRTRml4ZWQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3ODYKICAgICAgICAgICAgICBjYXNlIDc5MzogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkU2ZpeGVkNjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzkzCiAgICAgICAgICAgICAgY2FzZSA3OTQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRTZml4ZWQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzk0CiAgICAgICAgICAgICAgY2FzZSA4MDU6IHsKICAgICAgICAgICAgICAgIGZsb2F0IHYgPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRGbG9hdF8uYWRkRmxvYXQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODA1CiAgICAgICAgICAgICAgY2FzZSA4MDI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRGbG9hdF8uYWRkRmxvYXQoaW5wdXQucmVhZEZsb2F0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMgogICAgICAgICAgICAgIGNhc2UgODA5OiB7CiAgICAgICAgICAgICAgICBkb3VibGUgdiA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkRG91YmxlXy5hZGREb3VibGUodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODA5CiAgICAgICAgICAgICAgY2FzZSA4MTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWREb3VibGVJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkRG91YmxlXy5hZGREb3VibGUoaW5wdXQucmVhZERvdWJsZSgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MTAKICAgICAgICAgICAgICBjYXNlIDgxNjogewogICAgICAgICAgICAgICAgYm9vbGVhbiB2ID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZEJvb2xfLmFkZEJvb2xlYW4odik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODE2CiAgICAgICAgICAgICAgY2FzZSA4MTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRCb29sSXNNdXRhYmxlKGFsbG9jIC8gMSk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZEJvb2xfLmFkZEJvb2xlYW4oaW5wdXQucmVhZEJvb2woKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODE4CiAgICAgICAgICAgICAgY2FzZSA4MjQ6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODI0CiAgICAgICAgICAgICAgY2FzZSA4MjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHBhY2tlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgyNgogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEludDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkSW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRJbnQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkSW50MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFBhY2tlZEludDMyTGlzdCgpIHsKICAgICAgICBwYWNrZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRJbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRJbnQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkSW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50MzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRJbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkSW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkSW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEludDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkSW50MzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkSW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkSW50MzIoKSB7CiAgICAgICAgcGFja2VkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRJbnQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEludDY0XyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRJbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UGFja2VkSW50NjRMaXN0KCkgewogICAgICAgIHBhY2tlZEludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRJbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkSW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkSW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRJbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkSW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEludDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZEludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkSW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRJbnQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRJbnQ2NCgpIHsKICAgICAgICBwYWNrZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRVaW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRVaW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRVaW50MzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFVpbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkVWludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UGFja2VkVWludDMyTGlzdCgpIHsKICAgICAgICBwYWNrZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkVWludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRVaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFVpbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRVaW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkVWludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRVaW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFVpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZFVpbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFVpbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkVWludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkVWludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRVaW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFVpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZFVpbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRVaW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRVaW50MzIoKSB7CiAgICAgICAgcGFja2VkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRVaW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRVaW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRVaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFVpbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkVWludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UGFja2VkVWludDY0TGlzdCgpIHsKICAgICAgICBwYWNrZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkVWludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRVaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFVpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRVaW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkVWludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZFVpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkVWludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkVWludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkVWludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFVpbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFVpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFVpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFVpbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFVpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZFVpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRVaW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRVaW50NjQoKSB7CiAgICAgICAgcGFja2VkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNpbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZFNpbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZFNpbnQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkU2ludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRQYWNrZWRTaW50MzJMaXN0KCkgewogICAgICAgIHBhY2tlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNpbnQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRTaW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkU2ludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2ludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRTaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRTaW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNpbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkU2ludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkU2ludDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZFNpbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZFNpbnQzMigpIHsKICAgICAgICBwYWNrZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZFNpbnQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZFNpbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkU2ludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRQYWNrZWRTaW50NjRMaXN0KCkgewogICAgICAgIHBhY2tlZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRTaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNpbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UGFja2VkU2ludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRTaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRTaW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRTaW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2ludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkU2ludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2ludDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkU2ludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkU2ludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZFNpbnQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZFNpbnQ2NCgpIHsKICAgICAgICBwYWNrZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEZpeGVkMzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRGaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRml4ZWQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEZpeGVkMzJJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWRGaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRml4ZWQzMl8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFBhY2tlZEZpeGVkMzJMaXN0KCkgewogICAgICAgIHBhY2tlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkRml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRGaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRGaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRGaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkRml4ZWQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRGaXhlZDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRGaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRml4ZWQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRGaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkRml4ZWQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkRml4ZWQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkRml4ZWQzMigpIHsKICAgICAgICBwYWNrZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRml4ZWQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRGaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRGaXhlZDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRml4ZWQ2NElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXBhY2tlZEZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRGaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRGaXhlZDY0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UGFja2VkRml4ZWQ2NExpc3QoKSB7CiAgICAgICAgcGFja2VkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRGaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZpeGVkNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRml4ZWQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UGFja2VkRml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRml4ZWQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEZpeGVkNjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEZpeGVkNjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRGaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEZpeGVkNjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZEZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRGaXhlZDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRGaXhlZDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRGaXhlZDY0KCkgewogICAgICAgIHBhY2tlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRTZml4ZWQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZFNmaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkU2ZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFNmaXhlZDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkU2ZpeGVkMzJJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWRTZml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZFNmaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRTZml4ZWQzMl8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFBhY2tlZFNmaXhlZDMyTGlzdCgpIHsKICAgICAgICBwYWNrZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNmaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRTZml4ZWQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkU2ZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRTZml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZFNmaXhlZDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTZml4ZWQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNmaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkU2ZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2ZpeGVkMzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRTZml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZFNmaXhlZDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkU2ZpeGVkMzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkU2ZpeGVkMzIoKSB7CiAgICAgICAgcGFja2VkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkU2ZpeGVkNjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRTZml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZFNmaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRTZml4ZWQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTZml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkU2ZpeGVkNjRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKSB7CiAgICAgICAgcGFja2VkU2ZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkU2ZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ZpeGVkNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ZpeGVkNjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNmaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZFNmaXhlZDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRTZml4ZWQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZFNmaXhlZDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2ZpeGVkNjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRTZml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2ZpeGVkNjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkU2ZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRTZml4ZWQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZFNmaXhlZDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZFNmaXhlZDY0KCkgewogICAgICAgIHBhY2tlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5GbG9hdExpc3QgcGFja2VkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEZsb2F0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkRmxvYXRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRGbG9hdF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRmxvYXRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXBhY2tlZEZsb2F0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEZsb2F0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGbG9hdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRQYWNrZWRGbG9hdExpc3QoKSB7CiAgICAgICAgcGFja2VkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkRmxvYXRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZsb2F0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZsb2F0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGZsb2F0IGdldFBhY2tlZEZsb2F0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRGbG9hdF8uZ2V0RmxvYXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEZsb2F0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkRmxvYXQoCiAgICAgICAgICBpbnQgaW5kZXgsIGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRmxvYXRfLnNldEZsb2F0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRGbG9hdCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEZsb2F0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRmxvYXRfLmFkZEZsb2F0KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRGbG9hdCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEZsb2F0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEZsb2F0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRGbG9hdCgpIHsKICAgICAgICBwYWNrZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkRvdWJsZUxpc3QgcGFja2VkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkRG91YmxlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRG91YmxlXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWREb3VibGVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWREb3VibGVJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWREb3VibGVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWREb3VibGVfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZERvdWJsZV8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWREb3VibGUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldFBhY2tlZERvdWJsZUxpc3QoKSB7CiAgICAgICAgcGFja2VkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZERvdWJsZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZERvdWJsZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRG91YmxlQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZERvdWJsZV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0UGFja2VkRG91YmxlKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWREb3VibGVfLmdldERvdWJsZShpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWREb3VibGUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWREb3VibGUoCiAgICAgICAgICBpbnQgaW5kZXgsIGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICBwYWNrZWREb3VibGVfLnNldERvdWJsZShpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWREb3VibGUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWREb3VibGUoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZERvdWJsZV8uYWRkRG91YmxlKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZERvdWJsZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZERvdWJsZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZERvdWJsZV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWREb3VibGUoKSB7CiAgICAgICAgcGFja2VkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHBhY2tlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkQm9vbElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEJvb2xfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRCb29sXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRCb29sXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkQm9vbElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXBhY2tlZEJvb2xfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRCb29sXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRCb29sXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkQm9vbC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldFBhY2tlZEJvb2xMaXN0KCkgewogICAgICAgIHBhY2tlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkQm9vbF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkQm9vbC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkQm9vbENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRCb29sXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEJvb2wgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gZ2V0UGFja2VkQm9vbChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkQm9vbF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEJvb2wgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRCb29sKAogICAgICAgICAgaW50IGluZGV4LCBib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRCb29sXy5zZXRCb29sZWFuKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkQm9vbCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEJvb2woYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkQm9vbF8uYWRkQm9vbGVhbih2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZEJvb2wgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRCb29sKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkQm9vbElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRCb29sXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkQm9vbCgpIHsKICAgICAgICBwYWNrZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZEVudW1fID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRFbnVtSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEVudW1fID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHBhY2tlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25FbnVtPiBnZXRQYWNrZWRFbnVtTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bT4ocGFja2VkRW51bV8sIHBhY2tlZEVudW1fY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRFbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bSBnZXRQYWNrZWRFbnVtKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRFbnVtX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkRW51bSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbkVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBwYWNrZWRFbnVtXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEVudW0ocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbkVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBwYWNrZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25FbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduRW51bSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcGFja2VkRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEVudW0oKSB7CiAgICAgICAgcGFja2VkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcGFja2VkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0UGFja2VkRW51bVZhbHVlTGlzdCgpIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocGFja2VkRW51bV8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcGFja2VkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRW51bV8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHBhY2tlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRFbnVtVmFsdWUoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBwYWNrZWRFbnVtXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBwYWNrZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkRW51bVZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBwYWNrZWRFbnVtXy5hZGQodmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcGFja2VkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEVudW1WYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAoaW50IHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICBwYWNrZWRFbnVtXy5hZGQodmFsdWUpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0UGFja2VkVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RQYWNrZWRUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQYWNrZWRUeXBlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0UGFja2VkVHlwZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UGFja2VkVHlwZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UGFja2VkVHlwZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFBhY2tlZFR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0UGFja2VkVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0VW5wYWNrZWRUeXBlc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRSZXBlYXRlZEludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+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+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJvb2wuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEJvb2xDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2woaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRSZXBlYXRlZE5lc3RlZEVudW0oaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIEV4cGxpY2l0bHkgc2V0IHBhY2tlZCB0byBmYWxzZQogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdFVucGFja2VkVHlwZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0VW5wYWNrZWRUeXBlcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgICAgVGVzdFVucGFja2VkVHlwZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RVbnBhY2tlZFR5cGVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RVbnBhY2tlZFR5cGVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFVucGFja2VkVHlwZXMoKSB7CiAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RVbnBhY2tlZFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFVucGFja2VkVHlwZXMuY2xhc3MsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RVbnBhY2tlZFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkSW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkSW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkSW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9VSU5UMzJfRklFTERfTlVNQkVSID0gMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRVaW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkVWludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1VJTlQ2NF9GSUVMRF9OVU1CRVIgPSA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRVaW50NjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkVWludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NJTlQzMl9GSUVMRF9OVU1CRVIgPSA1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFNpbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0lOVDY0X0ZJRUxEX05VTUJFUiA9IDY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNpbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkU2ludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRTaW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEZpeGVkMzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0ZJWEVENjRfRklFTERfTlVNQkVSID0gODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkRml4ZWQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkRml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0ZJWEVEMzJfRklFTERfTlVNQkVSID0gOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTZml4ZWQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0ZJWEVENjRfRklFTERfTlVNQkVSID0gMTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNmaXhlZDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9GTE9BVF9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCByZXBlYXRlZEZsb2F0XyA9CiAgICAgICAgZW1wdHlGbG9hdExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmxvYXQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGZsb2F0IGdldFJlcGVhdGVkRmxvYXQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0Xy5nZXRGbG9hdChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRE9VQkxFX0ZJRUxEX05VTUJFUiA9IDEyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCByZXBlYXRlZERvdWJsZV8gPQogICAgICAgIGVtcHR5RG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZERvdWJsZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZERvdWJsZS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZERvdWJsZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZERvdWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBkb3VibGUgZ2V0UmVwZWF0ZWREb3VibGUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV8uZ2V0RG91YmxlKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9CT09MX0ZJRUxEX05VTUJFUiA9IDEzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgcmVwZWF0ZWRCb29sXyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGdldFJlcGVhdGVkQm9vbExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJvb2xDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZ2V0UmVwZWF0ZWRCb29sKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVIgPSAxNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlc3VsdCA9IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IGdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocmVwZWF0ZWROZXN0ZWRFbnVtXywgcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgcmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMiwgcmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoMywgcmVwZWF0ZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50NjQoNCwgcmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyKDUsIHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0KDYsIHJlcGVhdGVkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRml4ZWQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDMyKDcsIHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRml4ZWQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0KDgsIHJlcGVhdGVkRml4ZWQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNmaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyKDksIHJlcGVhdGVkU2ZpeGVkMzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNmaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0KDEwLCByZXBlYXRlZFNmaXhlZDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRmxvYXRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMTEsIHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRG91YmxlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgxMiwgcmVwZWF0ZWREb3VibGVfLmdldERvdWJsZShpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEJvb2xfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgxMywgcmVwZWF0ZWRCb29sXy5nZXRCb29sZWFuKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDE0LCByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhyZXBlYXRlZEludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkSW50MzJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZEludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZEludDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhyZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplTm9UYWcocmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkVWludDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemVOb1RhZyhyZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50NjRTaXplTm9UYWcocmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU2ludDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSAxICogZ2V0UmVwZWF0ZWRCb29sTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkQm9vbExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFVucGFja2VkVHlwZXMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIG90aGVyID0gKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RVbnBhY2tlZFR5cGVzKSBvYmo7CgogICAgICBpZiAoIWdldFJlcGVhdGVkSW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkSW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEZsb2F0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkRG91YmxlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRG91YmxlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkQm9vbExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEJvb2xMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghcmVwZWF0ZWROZXN0ZWRFbnVtXy5lcXVhbHMob3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRCb29sQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9CT09MX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEJvb2xMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcmVwZWF0ZWROZXN0ZWRFbnVtXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBFeHBsaWNpdGx5IHNldCBwYWNrZWQgdG8gZmFsc2UKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZFR5cGVzfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdFVucGFja2VkVHlwZXMpCiAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFVucGFja2VkVHlwZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcy5jbGFzcywgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFVucGFja2VkVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIHJlcGVhdGVkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFVucGFja2VkVHlwZXMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFVucGFja2VkVHlwZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFVucGFja2VkVHlwZXMgcmVzdWx0ID0gbmV3IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RVbnBhY2tlZFR5cGVzKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIHJlc3VsdCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQucmVwZWF0ZWROZXN0ZWRFbnVtXyA9IHJlcGVhdGVkTmVzdGVkRW51bV87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbnQzMl8gPSByZXBlYXRlZEludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEludDY0XyA9IHJlcGVhdGVkSW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFVpbnQzMl8gPSByZXBlYXRlZFVpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkVWludDY0XyA9IHJlcGVhdGVkVWludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTaW50MzJfID0gcmVwZWF0ZWRTaW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNpbnQ2NF8gPSByZXBlYXRlZFNpbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZpeGVkMzJfID0gcmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRml4ZWQ2NF8gPSByZXBlYXRlZEZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2ZpeGVkMzJfID0gcmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTZml4ZWQ2NF8gPSByZXBlYXRlZFNmaXhlZDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZsb2F0XyA9IHJlcGVhdGVkRmxvYXRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZERvdWJsZV8gPSByZXBlYXRlZERvdWJsZV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEJvb2xfID0gcmVwZWF0ZWRCb29sXzsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFVucGFja2VkVHlwZXMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFVucGFja2VkVHlwZXMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFVucGFja2VkVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRJbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfID0gb3RoZXIucmVwZWF0ZWRJbnQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRJbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRJbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfID0gb3RoZXIucmVwZWF0ZWRJbnQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRJbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRVaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkVWludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gb3RoZXIucmVwZWF0ZWRVaW50MzJfOwogICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkVWludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFVpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRVaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBvdGhlci5yZXBlYXRlZFVpbnQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRVaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2ludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IG90aGVyLnJlcGVhdGVkU2ludDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNpbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gb3RoZXIucmVwZWF0ZWRTaW50NjRfOwogICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBvdGhlci5yZXBlYXRlZEZpeGVkMzJfOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRml4ZWQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gb3RoZXIucmVwZWF0ZWRGaXhlZDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEZpeGVkNjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2ZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IG90aGVyLnJlcGVhdGVkU2ZpeGVkMzJfOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ZpeGVkMzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2ZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IG90aGVyLnJlcGVhdGVkU2ZpeGVkNjRfOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ZpeGVkNjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRmxvYXRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRmxvYXRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEZsb2F0XyA9IG90aGVyLnJlcGVhdGVkRmxvYXRfOwogICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRmxvYXRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRG91YmxlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZERvdWJsZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IG90aGVyLnJlcGVhdGVkRG91YmxlXzsKICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfLmFkZEFsbChvdGhlci5yZXBlYXRlZERvdWJsZV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRCb29sXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEJvb2xfID0gb3RoZXIucmVwZWF0ZWRCb29sXzsKICAgICAgICAgICAgcmVwZWF0ZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEFsbChvdGhlci5yZXBlYXRlZEJvb2xfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IG90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZEFsbChvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQoaW5wdXQucmVhZEludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZExvbmcoaW5wdXQucmVhZEludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEludChpbnB1dC5yZWFkVUludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzMjogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFVJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyCiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkVUludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MAogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEludChpbnB1dC5yZWFkU0ludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA0ODogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ4CiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA2MTogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MQogICAgICAgICAgICAgIGNhc2UgNTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRJbnQoaW5wdXQucmVhZEZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgICBjYXNlIDY1OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjUKICAgICAgICAgICAgICBjYXNlIDY2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NgogICAgICAgICAgICAgIGNhc2UgNzc6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFNGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzcKICAgICAgICAgICAgICBjYXNlIDc0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQoaW5wdXQucmVhZFNGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MTogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxCiAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBjYXNlIDkzOiB7CiAgICAgICAgICAgICAgICBmbG9hdCB2ID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MwogICAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLmFkZEZsb2F0KGlucHV0LnJlYWRGbG9hdCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICAgIGNhc2UgOTc6IHsKICAgICAgICAgICAgICAgIGRvdWJsZSB2ID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5hZGREb3VibGUodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTcKICAgICAgICAgICAgICBjYXNlIDk4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfLmFkZERvdWJsZShpbnB1dC5yZWFkRG91YmxlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk4CiAgICAgICAgICAgICAgY2FzZSAxMDQ6IHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdiA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8uYWRkQm9vbGVhbih2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDQKICAgICAgICAgICAgICBjYXNlIDEwNjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEJvb2xlYW4oaW5wdXQucmVhZEJvb2woKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA2CiAgICAgICAgICAgICAgY2FzZSAxMTI6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExMgogICAgICAgICAgICAgIGNhc2UgMTE0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE0CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRJbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50MzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkSW50MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZEludDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRJbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRJbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkSW50MzIoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRJbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkSW50NjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRJbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkSW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRJbnQ2NCgpIHsKICAgICAgICByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFVpbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkVWludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFVpbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkVWludDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkVWludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkVWludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkVWludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRVaW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFVpbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRVaW50MzIoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFVpbnQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkVWludDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFVpbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkVWludDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFVpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVWludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRVaW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFVpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkVWludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRVaW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFVpbnQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRVaW50NjQoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTaW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNpbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNpbnQzMigpIHsKICAgICAgICByZXBlYXRlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSA2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFNpbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNpbnQ2NCgpIHsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRml4ZWQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDMyXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpeGVkMzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRml4ZWQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEZpeGVkMzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRGaXhlZDMyKCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkNjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRml4ZWQ2NF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpeGVkNjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZpeGVkNjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRGaXhlZDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRml4ZWQ2NCgpIHsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQzMl8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ZpeGVkMzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNmaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTZml4ZWQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2ZpeGVkMzIoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQ2NF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNmaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ZpeGVkNjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNmaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTZml4ZWQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTZml4ZWQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNmaXhlZDY0KCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRmxvYXRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRmxvYXRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGbG9hdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZsb2F0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZsb2F0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGZsb2F0IGdldFJlcGVhdGVkRmxvYXQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZsb2F0KAogICAgICAgICAgaW50IGluZGV4LCBmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8uc2V0RmxvYXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGbG9hdCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmxvYXQoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfLmFkZEZsb2F0KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZsb2F0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRGbG9hdF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZsb2F0KCkgewogICAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZERvdWJsZV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZERvdWJsZV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWREb3VibGVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWREb3VibGVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZERvdWJsZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZERvdWJsZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGRvdWJsZSBnZXRSZXBlYXRlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLmdldERvdWJsZShpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAxMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRG91YmxlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWREb3VibGUoCiAgICAgICAgICBpbnQgaW5kZXgsIGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRG91YmxlXy5zZXREb3VibGUoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAxMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZERvdWJsZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRG91YmxlKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRG91YmxlXy5hZGREb3VibGUodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZERvdWJsZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRG91YmxlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZERvdWJsZV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRG91YmxlKCkgewogICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHJlcGVhdGVkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEJvb2xfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkQm9vbF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQm9vbF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkQm9vbF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRCb29sXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2wuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRSZXBlYXRlZEJvb2xMaXN0KCkgewogICAgICAgIHJlcGVhdGVkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCb29sLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJvb2xDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGdldFJlcGVhdGVkQm9vbChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXy5nZXRCb29sZWFuKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJvb2wgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEJvb2woCiAgICAgICAgICBpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCb29sXy5zZXRCb29sZWFuKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJvb2wgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEJvb2woYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkQm9vbCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkQm9vbCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEJvb2xfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQm9vbCgpIHsKICAgICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWROZXN0ZWRFbnVtXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4ocmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPihyZXBlYXRlZE5lc3RlZEVudW1fLCByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkRW51bSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkTmVzdGVkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkRW51bShwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRFbnVtKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWROZXN0ZWRFbnVtKCkgewogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKGludCB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodmFsdWUpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdFVucGFja2VkVHlwZXMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdFVucGFja2VkVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VW5wYWNrZWRUeXBlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0VW5wYWNrZWRUeXBlcz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFVucGFja2VkVHlwZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFVucGFja2VkVHlwZXM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2hpbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0NoaWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNoaWxkLgogICAgICovCiAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMgZ2V0Q2hpbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0Q2hpbGRPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXlsb2FkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNQYXlsb2FkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcGF5bG9hZC4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzIGdldFBheWxvYWQoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRQYXlsb2FkT3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVGhpcyBwcm90byBpbmNsdWRlcyBhIHJlY3Vyc2l2ZWx5IG5lc3RlZCBtZXNzYWdlLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTmVzdGVkVGVzdEFsbFR5cGVzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcykKICAgICAgTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBOZXN0ZWRUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgTmVzdGVkVGVzdEFsbFR5cGVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgTmVzdGVkVGVzdEFsbFR5cGVzKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE5lc3RlZFRlc3RBbGxUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9OZXN0ZWRUZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLmNsYXNzLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENISUxEX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZF87CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2hpbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBnZXRDaGlsZCgpIHsKICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogY2hpbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0Q2hpbGRPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQVlMT0FEX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyBwYXlsb2FkXzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBheWxvYWQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNQYXlsb2FkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcGF5bG9hZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyBnZXRQYXlsb2FkKCkgewogICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBheWxvYWRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRQYXlsb2FkT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBheWxvYWRfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRDaGlsZCgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIsIGdldFBheWxvYWQoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRDaGlsZCgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgZ2V0UGF5bG9hZCgpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBvdGhlciA9IChwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMpIG9iajsKCiAgICAgIGlmIChoYXNDaGlsZCgpICE9IG90aGVyLmhhc0NoaWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0NoaWxkKCkpIHsKICAgICAgICBpZiAoIWdldENoaWxkKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRDaGlsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNQYXlsb2FkKCkgIT0gb3RoZXIuaGFzUGF5bG9hZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNQYXlsb2FkKCkpIHsKICAgICAgICBpZiAoIWdldFBheWxvYWQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBheWxvYWQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNDaGlsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ0hJTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldENoaWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzUGF5bG9hZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFZTE9BRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGF5bG9hZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGlzIHByb3RvIGluY2x1ZGVzIGEgcmVjdXJzaXZlbHkgbmVzdGVkIG1lc3NhZ2UuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMpCiAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9OZXN0ZWRUZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMuY2xhc3MsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRDaGlsZEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgY2hpbGRfID0gbnVsbDsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBwYXlsb2FkXyA9IG51bGw7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9OZXN0ZWRUZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIGJ1aWxkKCkgewogICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHJlc3VsdCA9IG5ldyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXModGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNoaWxkXyA9IGNoaWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gY2hpbGRfCiAgICAgICAgICAgICAgOiBjaGlsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucGF5bG9hZF8gPSBwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gcGF5bG9hZF8KICAgICAgICAgICAgICA6IHBheWxvYWRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0NoaWxkKCkpIHsKICAgICAgICAgIG1lcmdlQ2hpbGQob3RoZXIuZ2V0Q2hpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNQYXlsb2FkKCkpIHsKICAgICAgICAgIG1lcmdlUGF5bG9hZChvdGhlci5nZXRQYXlsb2FkKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRDaGlsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRQYXlsb2FkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcywgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlcj4gY2hpbGRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY2hpbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIGdldENoaWxkKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGNoaWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Q2hpbGQocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBjaGlsZF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDaGlsZCgKICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGNoaWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlQ2hpbGQocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICAgIGNoaWxkXyAhPSBudWxsICYmCiAgICAgICAgICAgIGNoaWxkXyAhPSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0Q2hpbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNoaWxkXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChjaGlsZF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNoaWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBjaGlsZF8gPSBudWxsOwogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgY2hpbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0Q2hpbGRCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0Q2hpbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0Q2hpbGRPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNoaWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gY2hpbGRfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcywgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRDaGlsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0Q2hpbGQoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGNoaWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyBwYXlsb2FkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBwYXlsb2FkQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXlsb2FkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1BheWxvYWQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcGF5bG9hZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMgZ2V0UGF5bG9hZCgpIHsKICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBwYXlsb2FkXyA9PSBudWxsID8gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcGF5bG9hZF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBwYXlsb2FkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYXlsb2FkKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBwYXlsb2FkXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYXlsb2FkKAogICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBwYXlsb2FkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVBheWxvYWQocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkgJiYKICAgICAgICAgICAgcGF5bG9hZF8gIT0gbnVsbCAmJgogICAgICAgICAgICBwYXlsb2FkXyAhPSBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0UGF5bG9hZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGF5bG9hZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChwYXlsb2FkXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYXlsb2FkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBwYXlsb2FkXyA9IG51bGw7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldFBheWxvYWRCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFBheWxvYWRPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcGF5bG9hZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHBheWxvYWRfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBheWxvYWRfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXMsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHBheWxvYWRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlcywgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldFBheWxvYWQoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHBheWxvYWRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBheWxvYWRCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZFRlc3RBbGxUeXBlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxOZXN0ZWRUZXN0QWxsVHlwZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBOZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRUZXN0QWxsVHlwZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkVGVzdEFsbFR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBGb3JlaWduTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGMuCiAgICAgKi8KICAgIGludCBnZXRDKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogRGVmaW5lIHRoZXNlIGFmdGVyIFRlc3RBbGxUeXBlcyB0byBtYWtlIHN1cmUgdGhlIGNvbXBpbGVyIGNhbiBoYW5kbGUKICAgKiB0aGF0LgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGb3JlaWduTWVzc2FnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSkKICAgICAgRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEZvcmVpZ25NZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIEZvcmVpZ25NZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgRm9yZWlnbk1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZS5jbGFzcywgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ19GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgY18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBjID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEMoKSB7CiAgICAgIHJldHVybiBjXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmIChjXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgY18pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoY18gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgY18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSBvdGhlciA9IChwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKGdldEMoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0QygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ19GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEMoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIERlZmluZSB0aGVzZSBhZnRlciBUZXN0QWxsVHlwZXMgdG8gbWFrZSBzdXJlIHRoZSBjb21waWxlciBjYW4gaGFuZGxlCiAgICAgKiB0aGF0LgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSkKICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlLmNsYXNzLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBjXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY18gPSBjXzsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5nZXRDKCkgIT0gMCkgewogICAgICAgICAgc2V0QyhvdGhlci5nZXRDKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIGNfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBjXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBjID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0QygpIHsKICAgICAgICByZXR1cm4gY187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGMgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBjIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QyhpbnQgdmFsdWUpIHsKCiAgICAgICAgY18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGMgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJDKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBjXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuRm9yZWlnbk1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLkZvcmVpZ25NZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Rm9yZWlnbk1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Rm9yZWlnbk1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBGb3JlaWduTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvcmVpZ25NZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvcmVpZ25NZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5Gb3JlaWduTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RFbXB0eU1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUZXN0RW1wdHlNZXNzYWdlIGlzIHVzZWQgdG8gdGVzdCBiZWhhdmlvciBvZiB1bmtub3duIGZpZWxkcy4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0RW1wdHlNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2UpCiAgICAgIFRlc3RFbXB0eU1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RFbXB0eU1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdEVtcHR5TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RFbXB0eU1lc3NhZ2UoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdEVtcHR5TWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0RW1wdHlNZXNzYWdlLmNsYXNzLCBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0RW1wdHlNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RFbXB0eU1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RFbXB0eU1lc3NhZ2Ugb3RoZXIgPSAocHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEVtcHR5TWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0RW1wdHlNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0RW1wdHlNZXNzYWdlIGlzIHVzZWQgdG8gdGVzdCBiZWhhdmlvciBvZiB1bmtub3duIGZpZWxkcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0RW1wdHlNZXNzYWdlKQogICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RFbXB0eU1lc3NhZ2VPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEVtcHR5TWVzc2FnZS5jbGFzcywgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEVtcHR5TWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RFbXB0eU1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0RW1wdHlNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RFbXB0eU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RFbXB0eU1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEVtcHR5TWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RFbXB0eU1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RFbXB0eU1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RFbXB0eU1lc3NhZ2UodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0RW1wdHlNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5UZXN0RW1wdHlNZXNzYWdlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RFbXB0eU1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEVtcHR5TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RFbXB0eU1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEVtcHR5TWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYUxpdGUuVGVzdEVtcHR5TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFbXB0eU1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEVtcHR5TWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RW1wdHlNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFbXB0eU1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmFMaXRlLlRlc3RFbXB0eU1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9OZXN0ZWRUZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4wZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3Byb3RvM19hcmVuYV8iICsKICAgICAgImxpdGUucHJvdG9cMDIyXDAzMnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0XDAzMiUiICsKICAgICAgImdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnQucHJvdG9cIlwyNTVcMDIxIiArCiAgICAgICJcblwwMTRUZXN0QWxsVHlwZXNcMDIyXDAyNlxuXDAxNm9wdGlvbmFsX2ludDMyXDAzMFwwMDEgXDAwMShcMDA1XDAyMlwwMjYiICsKICAgICAgIlxuXDAxNm9wdGlvbmFsX2ludDY0XDAzMFwwMDIgXDAwMShcMDAzXDAyMlwwMjdcblwwMTdvcHRpb25hbF91aW50MyIgKwogICAgICAiMlwwMzBcMDAzIFwwMDEoXHJcMDIyXDAyN1xuXDAxN29wdGlvbmFsX3VpbnQ2NFwwMzBcMDA0IFwwMDEoXDAwNFwwMjJcMDI3XG5cMDE3b3B0aSIgKwogICAgICAib25hbF9zaW50MzJcMDMwXDAwNSBcMDAxKFwwMjFcMDIyXDAyN1xuXDAxN29wdGlvbmFsX3NpbnQ2NFwwMzBcMDA2IFwwMDEiICsKICAgICAgIihcMDIyXDAyMlwwMzBcblwwMjBvcHRpb25hbF9maXhlZDMyXDAzMFwwMDcgXDAwMShcMDA3XDAyMlwwMzBcblwwMjBvcHRpb25hbCIgKwogICAgICAiX2ZpeGVkNjRcMDMwXDAxMCBcMDAxKFwwMDZcMDIyXDAzMVxuXDAyMW9wdGlvbmFsX3NmaXhlZDMyXDAzMFx0IFwwMDEoIiArCiAgICAgICJcMDE3XDAyMlwwMzFcblwwMjFvcHRpb25hbF9zZml4ZWQ2NFwwMzBcbiBcMDAxKFwwMjBcMDIyXDAyNlxuXDAxNm9wdGlvbmFsIiArCiAgICAgICJfZmxvYXRcMDMwXDAxMyBcMDAxKFwwMDJcMDIyXDAyN1xuXDAxN29wdGlvbmFsX2RvdWJsZVwwMzBcMDE0IFwwMDEoXDAwMVwwMjJcMDI1XG4iICsKICAgICAgIlxyb3B0aW9uYWxfYm9vbFwwMzBcciBcMDAxKFwwMTBcMDIyXDAyN1xuXDAxN29wdGlvbmFsX3N0cmluZ1wwMzAiICsKICAgICAgIlwwMTYgXDAwMShcdFwwMjJcMDI2XG5cMDE2b3B0aW9uYWxfYnl0ZXNcMDMwXDAxNyBcMDAxKFwwMTRcMDIyV1xuXDAyN29wdGlvbmEiICsKICAgICAgImxfbmVzdGVkX21lc3NhZ2VcMDMwXDAyMiBcMDAxKFwwMTMyNi5wcm90bzNfYXJlbmFfbGkiICsKICAgICAgInRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlXDAyMkwiICsKICAgICAgIlxuXDAzMG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZVwwMzBcMDIzIFwwMDEoXDAxMzIqLnByb3RvIiArCiAgICAgICIzX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2VcMDIySFxuXDAyNyIgKwogICAgICAib3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VcMDMwXDAyNCBcMDAxKFwwMTMyXCcucHJvdG9idWYiICsKICAgICAgIl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZVwwMjJRXG5cMDI0b3B0aW9uIiArCiAgICAgICJhbF9uZXN0ZWRfZW51bVwwMzBcMDI1IFwwMDEoXDAxNjIzLnByb3RvM19hcmVuYV9saXRlIiArCiAgICAgICJfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW1cMDIyRlxuXDAyNW9wdCIgKwogICAgICAiaW9uYWxfZm9yZWlnbl9lbnVtXDAzMFwwMjYgXDAwMShcMDE2MlwnLnByb3RvM19hcmVuYV8iICsKICAgICAgImxpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW1cMDIyIVxuXDAyNW9wdGlvbmFsX3N0IiArCiAgICAgICJyaW5nX3BpZWNlXDAzMFwwMzAgXDAwMShcdEJcMDAyXDAxMFwwMDJcMDIyXDAzMVxuXHJvcHRpb25hbF9jb3JkXDAzMFwwMzEgIiArCiAgICAgICJcMDAxKFx0QlwwMDJcMDEwXDAwMVwwMjJVXG5cMDM2b3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWciICsKICAgICAgImVcMDMwXDAzMiBcMDAxKFwwMTMyLS5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGkiICsKICAgICAgImNJbXBvcnRNZXNzYWdlXDAyMllcblwwMjVvcHRpb25hbF9sYXp5X21lc3NhZ2VcMDMwIiArCiAgICAgICJcMDMzIFwwMDEoXDAxMzI2LnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBIiArCiAgICAgICJsbFR5cGVzLk5lc3RlZE1lc3NhZ2VCXDAwMihcMDAxXDAyMlwwMjZcblwwMTZyZXBlYXRlZF9pbiIgKwogICAgICAidDMyXDAzMFwwMzcgXDAwMyhcMDA1XDAyMlwwMjZcblwwMTZyZXBlYXRlZF9pbnQ2NFwwMzAgIFwwMDMoXDAwM1wwMjJcMDI3XG5cMDE3cmVwIiArCiAgICAgICJlYXRlZF91aW50MzJcMDMwISBcMDAzKFxyXDAyMlwwMjdcblwwMTdyZXBlYXRlZF91aW50NjRcMDMwXCIgIiArCiAgICAgICJcMDAzKFwwMDRcMDIyXDAyN1xuXDAxN3JlcGVhdGVkX3NpbnQzMlwwMzAjIFwwMDMoXDAyMVwwMjJcMDI3XG5cMDE3cmVwZWF0ZWQiICsKICAgICAgIl9zaW50NjRcMDMwJCBcMDAzKFwwMjJcMDIyXDAzMFxuXDAyMHJlcGVhdGVkX2ZpeGVkMzJcMDMwJSBcMDAzKFwwMDdcMDIyIiArCiAgICAgICJcMDMwXG5cMDIwcmVwZWF0ZWRfZml4ZWQ2NFwwMzAmIFwwMDMoXDAwNlwwMjJcMDMxXG5cMDIxcmVwZWF0ZWRfc2YiICsKICAgICAgIml4ZWQzMlwwMzBcJyBcMDAzKFwwMTdcMDIyXDAzMVxuXDAyMXJlcGVhdGVkX3NmaXhlZDY0XDAzMCggXDAwMyhcMDIwXDAyMiIgKwogICAgICAiXDAyNlxuXDAxNnJlcGVhdGVkX2Zsb2F0XDAzMCkgXDAwMyhcMDAyXDAyMlwwMjdcblwwMTdyZXBlYXRlZF9kb3ViIiArCiAgICAgICJsZVwwMzAqIFwwMDMoXDAwMVwwMjJcMDI1XG5ccnJlcGVhdGVkX2Jvb2xcMDMwKyBcMDAzKFwwMTBcMDIyXDAyN1xuXDAxN3JlcGVhIiArCiAgICAgICJ0ZWRfc3RyaW5nXDAzMCwgXDAwMyhcdFwwMjJcMDI2XG5cMDE2cmVwZWF0ZWRfYnl0ZXNcMDMwLSBcMDAzKFwwMTQiICsKICAgICAgIlwwMjJXXG5cMDI3cmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VcMDMwMCBcMDAzKFwwMTMyNi5wcm90IiArCiAgICAgICJvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0IiArCiAgICAgICJlZE1lc3NhZ2VcMDIyTFxuXDAzMHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZVwwMzAxICIgKwogICAgICAiXDAwMyhcMDEzMioucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbiIgKwogICAgICAiTWVzc2FnZVwwMjJIXG5cMDI3cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VcMDMwMiBcMDAzKFwwMTMiICsKICAgICAgIjJcJy5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnIiArCiAgICAgICJlXDAyMlFcblwwMjRyZXBlYXRlZF9uZXN0ZWRfZW51bVwwMzAzIFwwMDMoXDAxNjIzLnByb3RvMyIgKwogICAgICAiX2FyZW5hX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZCIgKwogICAgICAiRW51bVwwMjJGXG5cMDI1cmVwZWF0ZWRfZm9yZWlnbl9lbnVtXDAzMDQgXDAwMyhcMDE2MlwnLnByIiArCiAgICAgICJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW1cMDIyIVxuXDAyNSIgKwogICAgICAicmVwZWF0ZWRfc3RyaW5nX3BpZWNlXDAzMDYgXDAwMyhcdEJcMDAyXDAxMFwwMDJcMDIyXDAzMVxuXHJyZXBlYSIgKwogICAgICAidGVkX2NvcmRcMDMwNyBcMDAzKFx0QlwwMDJcMDEwXDAwMVwwMjJZXG5cMDI1cmVwZWF0ZWRfbGF6eV9tZXNzIiArCiAgICAgICJhZ2VcMDMwOSBcMDAzKFwwMTMyNi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UIiArCiAgICAgICJlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlQlwwMDIoXDAwMVwwMjJcMDI2XG5cMDE0b25lb2ZfdSIgKwogICAgICAiaW50MzJcMDMwbyBcMDAxKFxySFwwMDBcMDIyVlxuXDAyNG9uZW9mX25lc3RlZF9tZXNzYWdlXDAzMHAgIiArCiAgICAgICJcMDAxKFwwMTMyNi5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UZXN0QWxsIiArCiAgICAgICJUeXBlcy5OZXN0ZWRNZXNzYWdlSFwwMDBcMDIyXDAyNlxuXDAxNG9uZW9mX3N0cmluZ1wwMzBxICIgKwogICAgICAiXDAwMShcdEhcMDAwXDAyMlwwMjVcblwwMTNvbmVvZl9ieXRlc1wwMzByIFwwMDEoXDAxNEhcMDAwXDAzMlwwMzNcblxyTmVzdGVkTWUiICsKICAgICAgInNzYWdlXDAyMlxuXG5cMDAyYmJcMDMwXDAwMSBcMDAxKFwwMDVcIkNcblxuTmVzdGVkRW51bVwwMjJcMDEwXG5cMDA0WkVST1wwMjAiICsKICAgICAgIlwwMDBcMDIyXDAwN1xuXDAwM0ZPT1wwMjBcMDAxXDAyMlwwMDdcblwwMDNCQVJcMDIwXDAwMlwwMjJcMDA3XG5cMDAzQkFaXDAyMFwwMDNcMDIyXDAyMFxuXDAwM05FR1wwMjBcMzc3XDM3N1wzNzdcMzc3IiArCiAgICAgICJcMzc3XDM3N1wzNzdcMzc3XDM3N1wwMDFCXHJcblwwMTNvbmVvZl9maWVsZFwiXDI2M1wwMDNcblwwMTdUZXN0UGFja2VkVHlwZSIgKwogICAgICAic1wwMjJcMDMwXG5cMDE0cGFja2VkX2ludDMyXDAzMFogXDAwMyhcMDA1QlwwMDJcMDIwXDAwMVwwMjJcMDMwXG5cMDE0cGFja2VkX2luIiArCiAgICAgICJ0NjRcMDMwWyBcMDAzKFwwMDNCXDAwMlwwMjBcMDAxXDAyMlwwMzFcblxycGFja2VkX3VpbnQzMlwwMzBcXCBcMDAzKFxyQlwwMDJcMDIwXDAwMSIgKwogICAgICAiXDAyMlwwMzFcblxycGFja2VkX3VpbnQ2NFwwMzBdIFwwMDMoXDAwNEJcMDAyXDAyMFwwMDFcMDIyXDAzMVxuXHJwYWNrZWRfc2kiICsKICAgICAgIm50MzJcMDMwXiBcMDAzKFwwMjFCXDAwMlwwMjBcMDAxXDAyMlwwMzFcblxycGFja2VkX3NpbnQ2NFwwMzBfIFwwMDMoXDAyMkJcMDAyXDAyMCIgKwogICAgICAiXDAwMVwwMjJcMDMyXG5cMDE2cGFja2VkX2ZpeGVkMzJcMDMwYCBcMDAzKFwwMDdCXDAwMlwwMjBcMDAxXDAyMlwwMzJcblwwMTZwYWNrZWRfIiArCiAgICAgICJmaXhlZDY0XDAzMGEgXDAwMyhcMDA2QlwwMDJcMDIwXDAwMVwwMjJcMDMzXG5cMDE3cGFja2VkX3NmaXhlZDMyXDAzMGIgXDAwMyIgKwogICAgICAiKFwwMTdCXDAwMlwwMjBcMDAxXDAyMlwwMzNcblwwMTdwYWNrZWRfc2ZpeGVkNjRcMDMwYyBcMDAzKFwwMjBCXDAwMlwwMjBcMDAxXDAyMlwwMzBcblwwMTRwIiArCiAgICAgICJhY2tlZF9mbG9hdFwwMzBkIFwwMDMoXDAwMkJcMDAyXDAyMFwwMDFcMDIyXDAzMVxuXHJwYWNrZWRfZG91YmxlXDAzMGUiICsKICAgICAgIiBcMDAzKFwwMDFCXDAwMlwwMjBcMDAxXDAyMlwwMjdcblwwMTNwYWNrZWRfYm9vbFwwMzBmIFwwMDMoXDAxMEJcMDAyXDAyMFwwMDFcMDIyQFxuXDAxM3BhYyIgKwogICAgICAia2VkX2VudW1cMDMwZyBcMDAzKFwwMTYyXCcucHJvdG8zX2FyZW5hX2xpdGVfdW5pdHQiICsKICAgICAgImVzdC5Gb3JlaWduRW51bUJcMDAyXDAyMFwwMDFcIlwzNDRcMDAzXG5cMDIxVGVzdFVucGFja2VkVHlwZSIgKwogICAgICAic1wwMjJcMDMyXG5cMDE2cmVwZWF0ZWRfaW50MzJcMDMwXDAwMSBcMDAzKFwwMDVCXDAwMlwwMjBcMDAwXDAyMlwwMzJcblwwMTZyZXBlYXRlIiArCiAgICAgICJkX2ludDY0XDAzMFwwMDIgXDAwMyhcMDAzQlwwMDJcMDIwXDAwMFwwMjJcMDMzXG5cMDE3cmVwZWF0ZWRfdWludDMyXDAzMFwwMDMgXDAwMyIgKwogICAgICAiKFxyQlwwMDJcMDIwXDAwMFwwMjJcMDMzXG5cMDE3cmVwZWF0ZWRfdWludDY0XDAzMFwwMDQgXDAwMyhcMDA0QlwwMDJcMDIwXDAwMFwwMjJcMDMzXG5cMDE3ciIgKwogICAgICAiZXBlYXRlZF9zaW50MzJcMDMwXDAwNSBcMDAzKFwwMjFCXDAwMlwwMjBcMDAwXDAyMlwwMzNcblwwMTdyZXBlYXRlZF9zaW4iICsKICAgICAgInQ2NFwwMzBcMDA2IFwwMDMoXDAyMkJcMDAyXDAyMFwwMDBcMDIyXDAzNFxuXDAyMHJlcGVhdGVkX2ZpeGVkMzJcMDMwXDAwNyBcMDAzKFwwMDdCIiArCiAgICAgICJcMDAyXDAyMFwwMDBcMDIyXDAzNFxuXDAyMHJlcGVhdGVkX2ZpeGVkNjRcMDMwXDAxMCBcMDAzKFwwMDZCXDAwMlwwMjBcMDAwXDAyMlwwMzVcblwwMjFyZXAiICsKICAgICAgImVhdGVkX3NmaXhlZDMyXDAzMFx0IFwwMDMoXDAxN0JcMDAyXDAyMFwwMDBcMDIyXDAzNVxuXDAyMXJlcGVhdGVkX3NmaSIgKwogICAgICAieGVkNjRcMDMwXG4gXDAwMyhcMDIwQlwwMDJcMDIwXDAwMFwwMjJcMDMyXG5cMDE2cmVwZWF0ZWRfZmxvYXRcMDMwXDAxMyBcMDAzKFwwMDJCIiArCiAgICAgICJcMDAyXDAyMFwwMDBcMDIyXDAzM1xuXDAxN3JlcGVhdGVkX2RvdWJsZVwwMzBcMDE0IFwwMDMoXDAwMUJcMDAyXDAyMFwwMDBcMDIyXDAzMVxuXHJyZXBlIiArCiAgICAgICJhdGVkX2Jvb2xcMDMwXHIgXDAwMyhcMDEwQlwwMDJcMDIwXDAwMFwwMjJVXG5cMDI0cmVwZWF0ZWRfbmVzdGVkX2UiICsKICAgICAgIm51bVwwMzBcMDE2IFwwMDMoXDAxNjIzLnByb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0LlQiICsKICAgICAgImVzdEFsbFR5cGVzLk5lc3RlZEVudW1CXDAwMlwwMjBcMDAwXCJcMjE2XDAwMVxuXDAyMk5lc3RlZFRlcyIgKwogICAgICAidEFsbFR5cGVzXDAyMj1cblwwMDVjaGlsZFwwMzBcMDAxIFwwMDEoXDAxMzIuLnByb3RvM19hcmVuYV8iICsKICAgICAgImxpdGVfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzXDAyMjlcblwwMDdwYXlsIiArCiAgICAgICJvYWRcMDMwXDAwMiBcMDAxKFwwMTMyKC5wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC5UIiArCiAgICAgICJlc3RBbGxUeXBlc1wiXDAzM1xuXDAxNkZvcmVpZ25NZXNzYWdlXDAyMlx0XG5cMDAxY1wwMzBcMDAxIFwwMDEoXDAwNSIgKwogICAgICAiXCJcMDIyXG5cMDIwVGVzdEVtcHR5TWVzc2FnZSpSXG5cMDEzRm9yZWlnbkVudW1cMDIyXDAyMFxuXDAxNEYiICsKICAgICAgIk9SRUlHTl9aRVJPXDAyMFwwMDBcMDIyXDAxN1xuXDAxM0ZPUkVJR05fRk9PXDAyMFwwMDRcMDIyXDAxN1xuXDAxM0ZPUkVJRyIgKwogICAgICAiTl9CQVJcMDIwXDAwNVwwMjJcMDE3XG5cMDEzRk9SRUlHTl9CQVpcMDIwXDAwNkJcMDA1SFwwMDNcMzcwXDAwMVwwMDFiXDAwNnByb3RvMyIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LmdldERlc2NyaXB0b3IoKSwKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiT3B0aW9uYWxJbnQzMiIsICJPcHRpb25hbEludDY0IiwgIk9wdGlvbmFsVWludDMyIiwgIk9wdGlvbmFsVWludDY0IiwgIk9wdGlvbmFsU2ludDMyIiwgIk9wdGlvbmFsU2ludDY0IiwgIk9wdGlvbmFsRml4ZWQzMiIsICJPcHRpb25hbEZpeGVkNjQiLCAiT3B0aW9uYWxTZml4ZWQzMiIsICJPcHRpb25hbFNmaXhlZDY0IiwgIk9wdGlvbmFsRmxvYXQiLCAiT3B0aW9uYWxEb3VibGUiLCAiT3B0aW9uYWxCb29sIiwgIk9wdGlvbmFsU3RyaW5nIiwgIk9wdGlvbmFsQnl0ZXMiLCAiT3B0aW9uYWxOZXN0ZWRNZXNzYWdlIiwgIk9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UiLCAiT3B0aW9uYWxJbXBvcnRNZXNzYWdlIiwgIk9wdGlvbmFsTmVzdGVkRW51bSIsICJPcHRpb25hbEZvcmVpZ25FbnVtIiwgIk9wdGlvbmFsU3RyaW5nUGllY2UiLCAiT3B0aW9uYWxDb3JkIiwgIk9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSIsICJPcHRpb25hbExhenlNZXNzYWdlIiwgIlJlcGVhdGVkSW50MzIiLCAiUmVwZWF0ZWRJbnQ2NCIsICJSZXBlYXRlZFVpbnQzMiIsICJSZXBlYXRlZFVpbnQ2NCIsICJSZXBlYXRlZFNpbnQzMiIsICJSZXBlYXRlZFNpbnQ2NCIsICJSZXBlYXRlZEZpeGVkMzIiLCAiUmVwZWF0ZWRGaXhlZDY0IiwgIlJlcGVhdGVkU2ZpeGVkMzIiLCAiUmVwZWF0ZWRTZml4ZWQ2NCIsICJSZXBlYXRlZEZsb2F0IiwgIlJlcGVhdGVkRG91YmxlIiwgIlJlcGVhdGVkQm9vbCIsICJSZXBlYXRlZFN0cmluZyIsICJSZXBlYXRlZEJ5dGVzIiwgIlJlcGVhdGVkTmVzdGVkTWVzc2FnZSIsICJSZXBlYXRlZEZvcmVpZ25NZXNzYWdlIiwgIlJlcGVhdGVkSW1wb3J0TWVzc2FnZSIsICJSZXBlYXRlZE5lc3RlZEVudW0iLCAiUmVwZWF0ZWRGb3JlaWduRW51bSIsICJSZXBlYXRlZFN0cmluZ1BpZWNlIiwgIlJlcGVhdGVkQ29yZCIsICJSZXBlYXRlZExhenlNZXNzYWdlIiwgIk9uZW9mVWludDMyIiwgIk9uZW9mTmVzdGVkTWVzc2FnZSIsICJPbmVvZlN0cmluZyIsICJPbmVvZkJ5dGVzIiwgIk9uZW9mRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJCYiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJQYWNrZWRJbnQzMiIsICJQYWNrZWRJbnQ2NCIsICJQYWNrZWRVaW50MzIiLCAiUGFja2VkVWludDY0IiwgIlBhY2tlZFNpbnQzMiIsICJQYWNrZWRTaW50NjQiLCAiUGFja2VkRml4ZWQzMiIsICJQYWNrZWRGaXhlZDY0IiwgIlBhY2tlZFNmaXhlZDMyIiwgIlBhY2tlZFNmaXhlZDY0IiwgIlBhY2tlZEZsb2F0IiwgIlBhY2tlZERvdWJsZSIsICJQYWNrZWRCb29sIiwgIlBhY2tlZEVudW0iLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUmVwZWF0ZWRJbnQzMiIsICJSZXBlYXRlZEludDY0IiwgIlJlcGVhdGVkVWludDMyIiwgIlJlcGVhdGVkVWludDY0IiwgIlJlcGVhdGVkU2ludDMyIiwgIlJlcGVhdGVkU2ludDY0IiwgIlJlcGVhdGVkRml4ZWQzMiIsICJSZXBlYXRlZEZpeGVkNjQiLCAiUmVwZWF0ZWRTZml4ZWQzMiIsICJSZXBlYXRlZFNmaXhlZDY0IiwgIlJlcGVhdGVkRmxvYXQiLCAiUmVwZWF0ZWREb3VibGUiLCAiUmVwZWF0ZWRCb29sIiwgIlJlcGVhdGVkTmVzdGVkRW51bSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9OZXN0ZWRUZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJDaGlsZCIsICJQYXlsb2FkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkMiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV9saXRlX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX2xpdGVfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5nZXREZXNjcmlwdG9yKCk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQD114GeVSkNAFUpDQAuAAAAcHJvdG8zX2FyZW5hX3VuaXR0ZXN0L1VuaXR0ZXN0UHJvdG8zQXJlbmEuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3Byb3RvM19hcmVuYS5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIFVuaXR0ZXN0UHJvdG8zQXJlbmEgewogIHByaXZhdGUgVW5pdHRlc3RQcm90bzNBcmVuYSgpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtfQogICAqLwogIHB1YmxpYyBlbnVtIEZvcmVpZ25FbnVtCiAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgIC8qKgogICAgICogPGNvZGU+Rk9SRUlHTl9aRVJPID0gMDs8L2NvZGU+CiAgICAgKi8KICAgIEZPUkVJR05fWkVSTygwKSwKICAgIC8qKgogICAgICogPGNvZGU+Rk9SRUlHTl9GT08gPSA0OzwvY29kZT4KICAgICAqLwogICAgRk9SRUlHTl9GT08oNCksCiAgICAvKioKICAgICAqIDxjb2RlPkZPUkVJR05fQkFSID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEZPUkVJR05fQkFSKDUpLAogICAgLyoqCiAgICAgKiA8Y29kZT5GT1JFSUdOX0JBWiA9IDY7PC9jb2RlPgogICAgICovCiAgICBGT1JFSUdOX0JBWig2KSwKICAgIFVOUkVDT0dOSVpFRCgtMSksCiAgICA7CgogICAgLyoqCiAgICAgKiA8Y29kZT5GT1JFSUdOX1pFUk8gPSAwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9SRUlHTl9aRVJPX1ZBTFVFID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+Rk9SRUlHTl9GT08gPSA0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9SRUlHTl9GT09fVkFMVUUgPSA0OwogICAgLyoqCiAgICAgKiA8Y29kZT5GT1JFSUdOX0JBUiA9IDU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT1JFSUdOX0JBUl9WQUxVRSA9IDU7CiAgICAvKioKICAgICAqIDxjb2RlPkZPUkVJR05fQkFaID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPUkVJR05fQkFaX1ZBTFVFID0gNjsKCgogICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBudW1iZXIgb2YgYW4gdW5rbm93biBlbnVtIHZhbHVlLiIpOwogICAgICB9CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIHN0YXRpYyBGb3JlaWduRW51bSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIEZvcmVpZ25FbnVtIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgIGNhc2UgMDogcmV0dXJuIEZPUkVJR05fWkVSTzsKICAgICAgICBjYXNlIDQ6IHJldHVybiBGT1JFSUdOX0ZPTzsKICAgICAgICBjYXNlIDU6IHJldHVybiBGT1JFSUdOX0JBUjsKICAgICAgICBjYXNlIDY6IHJldHVybiBGT1JFSUdOX0JBWjsKICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxGb3JlaWduRW51bT4KICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgRm9yZWlnbkVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8Rm9yZWlnbkVudW0+KCkgewogICAgICAgICAgICBwdWJsaWMgRm9yZWlnbkVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgIHJldHVybiBGb3JlaWduRW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKCiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgZGVzY3JpcHRvciBvZiBhbiB1bnJlY29nbml6ZWQgZW51bSB2YWx1ZS4iKTsKICAgICAgfQogICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgfQogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZvcmVpZ25FbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgcHVibGljIHN0YXRpYyBGb3JlaWduRW51bSB2YWx1ZU9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICB9CiAgICAgIGlmIChkZXNjLmdldEluZGV4KCkgPT0gLTEpIHsKICAgICAgICByZXR1cm4gVU5SRUNPR05JWkVEOwogICAgICB9CiAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICBwcml2YXRlIEZvcmVpZ25FbnVtKGludCB2YWx1ZSkgewogICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtKQogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBTaW5ndWxhcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+aW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBvcHRpb25hbF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbEludDY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsVWludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT51aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbFVpbnQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbFNpbnQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTaW50NjQuCiAgICAgKi8KICAgIGxvbmcgZ2V0T3B0aW9uYWxTaW50NjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxGaXhlZDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbEZpeGVkNjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxTZml4ZWQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDY0LgogICAgICovCiAgICBsb25nIGdldE9wdGlvbmFsU2ZpeGVkNjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGbG9hdC4KICAgICAqLwogICAgZmxvYXQgZ2V0T3B0aW9uYWxGbG9hdCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+ZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRG91YmxlLgogICAgICovCiAgICBkb3VibGUgZ2V0T3B0aW9uYWxEb3VibGUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQm9vbC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRPcHRpb25hbEJvb2woKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFN0cmluZ0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvcHRpb25hbF9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQnl0ZXMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGb3JlaWduTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEltcG9ydE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbXBvcnRNZXNzYWdlLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgKi8KICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIG9wdGlvbmFsRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEZvcmVpZ25FbnVtVmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICovCiAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bSBnZXRPcHRpb25hbEZvcmVpZ25FbnVtKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZ1BpZWNlLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nUGllY2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsU3RyaW5nUGllY2VCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbENvcmQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxDb3JkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsQ29yZC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxDb3JkQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF91bnZlcmlmaWVkX2xhenlfbWVzc2FnZSA9IDI4IFt1bnZlcmlmaWVkX2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlLgogICAgICovCiAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9sYXp5X2ltcG9ydF9tZXNzYWdlID0gMTE1IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9sYXp5X2ltcG9ydF9tZXNzYWdlID0gMTE1IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9pbXBvcnRfbWVzc2FnZSA9IDExNSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRSZXBlYXRlZEludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUmVwZWF0ZWQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUmVwZWF0ZWQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+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+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZ0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZyhpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJ5dGVzLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldFJlcGVhdGVkQnl0ZXNMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCeXRlcy4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQnl0ZXNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCeXRlcyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXBlYXRlZEJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogT3B0aW9uYWwKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHByb3RvM19vcHRpb25hbF9pbnQzMiA9IDExNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsSW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsSW50MzIoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE9wdGlvbmFsCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBwcm90bzNfb3B0aW9uYWxfaW50MzIgPSAxMTY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxJbnQzMi4KICAgICAqLwogICAgaW50IGdldFByb3RvM09wdGlvbmFsSW50MzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IHByb3RvM19vcHRpb25hbF9pbnQ2NCA9IDExNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsSW50NjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsSW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgcHJvdG8zX29wdGlvbmFsX2ludDY0ID0gMTE3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsSW50NjQuCiAgICAgKi8KICAgIGxvbmcgZ2V0UHJvdG8zT3B0aW9uYWxJbnQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIHByb3RvM19vcHRpb25hbF91aW50MzIgPSAxMTg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbFVpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxVaW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIHByb3RvM19vcHRpb25hbF91aW50MzIgPSAxMTg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxVaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRQcm90bzNPcHRpb25hbFVpbnQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IHByb3RvM19vcHRpb25hbF91aW50NjQgPSAxMTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbFVpbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxVaW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IHByb3RvM19vcHRpb25hbF91aW50NjQgPSAxMTk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxVaW50NjQuCiAgICAgKi8KICAgIGxvbmcgZ2V0UHJvdG8zT3B0aW9uYWxVaW50NjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBwcm90bzNfb3B0aW9uYWxfc2ludDMyID0gMTIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxTaW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsU2ludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBwcm90bzNfb3B0aW9uYWxfc2ludDMyID0gMTIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsU2ludDMyLgogICAgICovCiAgICBpbnQgZ2V0UHJvdG8zT3B0aW9uYWxTaW50MzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBwcm90bzNfb3B0aW9uYWxfc2ludDY0ID0gMTIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxTaW50NjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsU2ludDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBwcm90bzNfb3B0aW9uYWxfc2ludDY0ID0gMTIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsU2ludDY0LgogICAgICovCiAgICBsb25nIGdldFByb3RvM09wdGlvbmFsU2ludDY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIHByb3RvM19vcHRpb25hbF9maXhlZDMyID0gMTIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxGaXhlZDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNQcm90bzNPcHRpb25hbEZpeGVkMzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBwcm90bzNfb3B0aW9uYWxfZml4ZWQzMiA9IDEyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBwcm90bzNPcHRpb25hbEZpeGVkMzIuCiAgICAgKi8KICAgIGludCBnZXRQcm90bzNPcHRpb25hbEZpeGVkMzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgcHJvdG8zX29wdGlvbmFsX2ZpeGVkNjQgPSAxMjM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbEZpeGVkNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsRml4ZWQ2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDY0IHByb3RvM19vcHRpb25hbF9maXhlZDY0ID0gMTIzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsRml4ZWQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRQcm90bzNPcHRpb25hbEZpeGVkNjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDMyIHByb3RvM19vcHRpb25hbF9zZml4ZWQzMiA9IDEyNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsU2ZpeGVkMzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsU2ZpeGVkMzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgcHJvdG8zX29wdGlvbmFsX3NmaXhlZDMyID0gMTI0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsU2ZpeGVkMzIuCiAgICAgKi8KICAgIGludCBnZXRQcm90bzNPcHRpb25hbFNmaXhlZDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBwcm90bzNfb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMjU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbFNmaXhlZDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNQcm90bzNPcHRpb25hbFNmaXhlZDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDY0IHByb3RvM19vcHRpb25hbF9zZml4ZWQ2NCA9IDEyNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBwcm90bzNPcHRpb25hbFNmaXhlZDY0LgogICAgICovCiAgICBsb25nIGdldFByb3RvM09wdGlvbmFsU2ZpeGVkNjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHByb3RvM19vcHRpb25hbF9mbG9hdCA9IDEyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsRmxvYXQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgcHJvdG8zX29wdGlvbmFsX2Zsb2F0ID0gMTI2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsRmxvYXQuCiAgICAgKi8KICAgIGZsb2F0IGdldFByb3RvM09wdGlvbmFsRmxvYXQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBwcm90bzNfb3B0aW9uYWxfZG91YmxlID0gMTI3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxEb3VibGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsRG91YmxlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBwcm90bzNfb3B0aW9uYWxfZG91YmxlID0gMTI3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsRG91YmxlLgogICAgICovCiAgICBkb3VibGUgZ2V0UHJvdG8zT3B0aW9uYWxEb3VibGUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgcHJvdG8zX29wdGlvbmFsX2Jvb2wgPSAxMjg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbEJvb2wgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsQm9vbCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHByb3RvM19vcHRpb25hbF9ib29sID0gMTI4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsQm9vbC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRQcm90bzNPcHRpb25hbEJvb2woKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBwcm90bzNfb3B0aW9uYWxfc3RyaW5nID0gMTI5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBwcm90bzNfb3B0aW9uYWxfc3RyaW5nID0gMTI5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFByb3RvM09wdGlvbmFsU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBwcm90bzNfb3B0aW9uYWxfc3RyaW5nID0gMTI5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBwcm90bzNPcHRpb25hbFN0cmluZy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UHJvdG8zT3B0aW9uYWxTdHJpbmdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgcHJvdG8zX29wdGlvbmFsX2J5dGVzID0gMTMwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxCeXRlcygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBwcm90bzNfb3B0aW9uYWxfYnl0ZXMgPSAxMzA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxCeXRlcy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldFByb3RvM09wdGlvbmFsQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiAKICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlPiAKICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gCiAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IGdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bT4gZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0gZ2V0UmVwZWF0ZWRGb3JlaWduRW51bShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UmVwZWF0ZWRGb3JlaWduRW51bVZhbHVlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZEZvcmVpZ25FbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRm9yZWlnbkVudW1WYWx1ZShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmdQaWVjZS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZ1BpZWNlLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZENvcmQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQ29yZC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQ29yZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZENvcmQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkQ29yZChpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZENvcmQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZENvcmRCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IAogICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2UoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlVpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZVaW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDExMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZlVpbnQzMi4KICAgICAqLwogICAgaW50IGdldE9uZW9mVWludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPbmVvZk5lc3RlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZk5lc3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9uZW9mTmVzdGVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09uZW9mU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZTdHJpbmcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0T25lb2ZTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9uZW9mU3RyaW5nQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZCeXRlcygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDExNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZkJ5dGVzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T25lb2ZCeXRlcygpOwoKICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5PbmVvZkZpZWxkQ2FzZSBnZXRPbmVvZkZpZWxkQ2FzZSgpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRoaXMgcHJvdG8gaW5jbHVkZXMgZXZlcnkgdHlwZSBvZiBmaWVsZCBpbiBib3RoIHNpbmd1bGFyIGFuZCByZXBlYXRlZAogICAqIGZvcm1zLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RBbGxUeXBlcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzKQogICAgICBUZXN0QWxsVHlwZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0QWxsVHlwZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0QWxsVHlwZXMoKSB7CiAgICAgIG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgICBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gMDsKICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSAiIjsKICAgICAgb3B0aW9uYWxDb3JkXyA9ICIiOwogICAgICByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcmVwZWF0ZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRCeXRlc18gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgcHJvdG8zT3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgIHByb3RvM09wdGlvbmFsQnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRDb3JkXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RBbGxUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuY2xhc3MsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bX0KICAgICAqLwogICAgcHVibGljIGVudW0gTmVzdGVkRW51bQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlpFUk8gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIFpFUk8oMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEZPTygxKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQkFSKDIpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QkFaID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVooMyksCiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBJbnRlbnRpb25hbGx5IG5lZ2F0aXZlLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+TkVHID0gLTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgTkVHKC0xKSwKICAgICAgVU5SRUNPR05JWkVEKC0xKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlpFUk8gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFpFUk9fVkFMVUUgPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+Rk9PID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fVkFMVUUgPSAxOwogICAgICAvKioKICAgICAgICogPGNvZGU+QkFSID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVJfVkFMVUUgPSAyOwogICAgICAvKioKICAgICAgICogPGNvZGU+QkFaID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVpfVkFMVUUgPSAzOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogSW50ZW50aW9uYWxseSBuZWdhdGl2ZS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPk5FRyA9IC0xOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5FR19WQUxVRSA9IC0xOwoKCiAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgbnVtYmVyIG9mIGFuIHVua25vd24gZW51bSB2YWx1ZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBaRVJPOwogICAgICAgICAgY2FzZSAxOiByZXR1cm4gRk9POwogICAgICAgICAgY2FzZSAyOiByZXR1cm4gQkFSOwogICAgICAgICAgY2FzZSAzOiByZXR1cm4gQkFaOwogICAgICAgICAgY2FzZSAtMTogcmV0dXJuIE5FRzsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE5lc3RlZEVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBOZXN0ZWRFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIE5lc3RlZEVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIE5lc3RlZEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgZGVzY3JpcHRvciBvZiBhbiB1bnJlY29nbml6ZWQgZW51bSB2YWx1ZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBOZXN0ZWRFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICBpZiAoZGVzYy5nZXRJbmRleCgpID09IC0xKSB7CiAgICAgICAgICByZXR1cm4gVU5SRUNPR05JWkVEOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBOZXN0ZWRFbnVtKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtKQogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAqIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCiAgICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+aW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYmIuCiAgICAgICAqLwogICAgICBpbnQgZ2V0QmIoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZE1lc3NhZ2UgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkKICAgICAgICBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBOZXN0ZWRNZXNzYWdlKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJCX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgaW50IGJiXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPmludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJiLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEJiKCkgewogICAgICAgIHJldHVybiBiYl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGJiXyAhPSAwKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBiYl8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoYmJfICE9IDApIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBiYl8pOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9iajsKCiAgICAgICAgaWYgKGdldEJiKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QmIoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCQl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QmIoKTsKICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2V9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmNsYXNzLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGJiXyA9IDA7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LmJiXyA9IGJiXzsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmdldEJiKCkgIT0gMCkgewogICAgICAgICAgICBzZXRCYihvdGhlci5nZXRCYigpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgICBiYl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCBiYl8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqCiAgICAgICAgICogPGNvZGU+aW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBiYi4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRCYigpIHsKICAgICAgICAgIHJldHVybiBiYl87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqCiAgICAgICAgICogPGNvZGU+aW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJiIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmIoaW50IHZhbHVlKSB7CgogICAgICAgICAgYmJfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIDxjb2RlPmludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQmIoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBiYl8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE5lc3RlZE1lc3NhZ2U+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTmVzdGVkTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHByaXZhdGUgaW50IG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBvbmVvZkZpZWxkXzsKICAgIHB1YmxpYyBlbnVtIE9uZW9mRmllbGRDYXNlCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZS5JbnRlcm5hbE9uZU9mRW51bSB7CiAgICAgIE9ORU9GX1VJTlQzMigxMTEpLAogICAgICBPTkVPRl9ORVNURURfTUVTU0FHRSgxMTIpLAogICAgICBPTkVPRl9TVFJJTkcoMTEzKSwKICAgICAgT05FT0ZfQllURVMoMTE0KSwKICAgICAgT05FT0ZGSUVMRF9OT1RfU0VUKDApOwogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKICAgICAgcHJpdmF0ZSBPbmVvZkZpZWxkQ2FzZShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtYmVyIG9mIHRoZSBlbnVtIHRvIGxvb2sgZm9yLgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtYmVyLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIE9uZW9mRmllbGRDYXNlIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgT25lb2ZGaWVsZENhc2UgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMTExOiByZXR1cm4gT05FT0ZfVUlOVDMyOwogICAgICAgICAgY2FzZSAxMTI6IHJldHVybiBPTkVPRl9ORVNURURfTUVTU0FHRTsKICAgICAgICAgIGNhc2UgMTEzOiByZXR1cm4gT05FT0ZfU1RSSU5HOwogICAgICAgICAgY2FzZSAxMTQ6IHJldHVybiBPTkVPRl9CWVRFUzsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIE9ORU9GRklFTERfTk9UX1NFVDsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgT25lb2ZGaWVsZENhc2UKICAgIGdldE9uZW9mRmllbGRDYXNlKCkgewogICAgICByZXR1cm4gT25lb2ZGaWVsZENhc2UuZm9yTnVtYmVyKAogICAgICAgICAgb25lb2ZGaWVsZENhc2VfKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogU2luZ3VsYXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPmludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQ2NF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsSW50NjRfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPmludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbEludDY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQ2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UNjRfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFVpbnQ2NF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+dWludDY0IG9wdGlvbmFsX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsVWludDY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxVaW50NjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NJTlQzMl9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTaW50MzJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+c2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxTaW50MzIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFNpbnQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0lOVDY0X0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxTaW50NjRfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQ2NCBvcHRpb25hbF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbFNpbnQ2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsU2ludDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9GSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEZpeGVkMzJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZpeGVkMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxGaXhlZDMyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGaXhlZDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9GSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDg7CiAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxGaXhlZDY0XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxGaXhlZDY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGaXhlZDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZml4ZWQzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQzMiBvcHRpb25hbF9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFNmaXhlZDMyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxTZml4ZWQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0ZJWEVENjRfRklFTERfTlVNQkVSID0gMTA7CiAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxTZml4ZWQ2NF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbFNmaXhlZDY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxTZml4ZWQ2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRkxPQVRfRklFTERfTlVNQkVSID0gMTE7CiAgICBwcml2YXRlIGZsb2F0IG9wdGlvbmFsRmxvYXRfID0gMEY7CiAgICAvKioKICAgICAqIDxjb2RlPmZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGbG9hdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldE9wdGlvbmFsRmxvYXQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEZsb2F0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9ET1VCTEVfRklFTERfTlVNQkVSID0gMTI7CiAgICBwcml2YXRlIGRvdWJsZSBvcHRpb25hbERvdWJsZV8gPSAwRDsKICAgIC8qKgogICAgICogPGNvZGU+ZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRG91YmxlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldE9wdGlvbmFsRG91YmxlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxEb3VibGVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0JPT0xfRklFTERfTlVNQkVSID0gMTM7CiAgICBwcml2YXRlIGJvb2xlYW4gb3B0aW9uYWxCb29sXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8Y29kZT5ib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJvb2wuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldE9wdGlvbmFsQm9vbCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsQm9vbF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDE0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gczsKICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0JZVEVTX0ZJRUxEX05VTUJFUiA9IDE1OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgb3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxCeXRlc187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTg7CiAgICBwcml2YXRlIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0ZPUkVJR05fTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAxOTsKICAgIHByaXZhdGUgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxGb3JlaWduTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEZvcmVpZ25NZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxGb3JlaWduTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID09IG51bGwgPyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lNUE9SVF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDIwOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbEltcG9ydE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEltcG9ydE1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsSW1wb3J0TWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxJbXBvcnRNZXNzYWdlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVIgPSAyMTsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsTmVzdGVkRW51bV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGludCBnZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkRW51bV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVzdWx0ID0gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZm9yTnVtYmVyKG9wdGlvbmFsTmVzdGVkRW51bV8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRk9SRUlHTl9FTlVNX0ZJRUxEX05VTUJFUiA9IDIyOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxGb3JlaWduRW51bV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxGb3JlaWduRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldE9wdGlvbmFsRm9yZWlnbkVudW1WYWx1ZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbkVudW1fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25FbnVtIGdldE9wdGlvbmFsRm9yZWlnbkVudW0oKSB7CiAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25FbnVtIHJlc3VsdCA9IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25FbnVtLmZvck51bWJlcihvcHRpb25hbEZvcmVpZ25FbnVtXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25FbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TVFJJTkdfUElFQ0VfRklFTERfTlVNQkVSID0gMjQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFN0cmluZ1BpZWNlXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZ1BpZWNlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZ1BpZWNlKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nUGllY2VfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSBzOwogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZ1BpZWNlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nUGllY2VfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0NPUkRfRklFTERfTlVNQkVSID0gMjU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbENvcmRfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxDb3JkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbENvcmQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxDb3JkXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIG9wdGlvbmFsQ29yZF8gPSBzOwogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsQ29yZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsQ29yZEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsQ29yZF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIG9wdGlvbmFsQ29yZF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9QVUJMSUNfSU1QT1JUX01FU1NBR0VfRklFTERfTlVNQkVSID0gMjY7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV87CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0xBWllfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAyNzsKICAgIHByaXZhdGUgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbExhenlNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbExhenlNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID09IG51bGwgPyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID09IG51bGwgPyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VOVkVSSUZJRURfTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDI4OwogICAgcHJpdmF0ZSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyA9PSBudWxsID8gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0xBWllfSU1QT1JUX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTE1OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2xhenlfaW1wb3J0X21lc3NhZ2UgPSAxMTUgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9sYXp5X2ltcG9ydF9tZXNzYWdlID0gMTE1IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2xhenlfaW1wb3J0X21lc3NhZ2UgPSAxMTUgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSID0gMzE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkSW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZEludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUmVwZWF0ZWQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBSZXBlYXRlZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTlQ2NF9GSUVMRF9OVU1CRVIgPSAzMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkSW50NjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkSW50NjRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRJbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWRJbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9VSU5UMzJfRklFTERfTlVNQkVSID0gMzM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkVWludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkVWludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHJlcGVhdGVkVWludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1VJTlQ2NF9GSUVMRF9OVU1CRVIgPSAzNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkVWludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRVaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFVpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHJlcGVhdGVkVWludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NJTlQzMl9GSUVMRF9OVU1CRVIgPSAzNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTaW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50MzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWRTaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0lOVDY0X0ZJRUxEX05VTUJFUiA9IDM2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRTaW50NjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkU2ludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWRTaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRklYRUQzMl9GSUVMRF9OVU1CRVIgPSAzNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRGaXhlZDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZpeGVkMzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHJlcGVhdGVkRml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDM4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRGaXhlZDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRGaXhlZDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHJlcGVhdGVkRml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TRklYRUQzMl9GSUVMRF9OVU1CRVIgPSAzOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTZml4ZWQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkMzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZFNmaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NGSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDQwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRTZml4ZWQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFNmaXhlZDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZFNmaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0ZMT0FUX0ZJRUxEX05VTUJFUiA9IDQxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IHJlcGVhdGVkRmxvYXRfID0KICAgICAgICBlbXB0eUZsb2F0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZsb2F0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRmxvYXRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZmxvYXQgZ2V0UmVwZWF0ZWRGbG9hdChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHJlcGVhdGVkRmxvYXRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRE9VQkxFX0ZJRUxEX05VTUJFUiA9IDQyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCByZXBlYXRlZERvdWJsZV8gPQogICAgICAgIGVtcHR5RG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWREb3VibGUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRG91YmxlLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRG91YmxlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZERvdWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBkb3VibGUgZ2V0UmVwZWF0ZWREb3VibGUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV8uZ2V0RG91YmxlKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHJlcGVhdGVkRG91YmxlTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0JPT0xfRklFTERfTlVNQkVSID0gNDM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCByZXBlYXRlZEJvb2xfID0KICAgICAgICBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGdldFJlcGVhdGVkQm9vbExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJvb2wuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCb29sQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJvb2wgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2woaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWRCb29sTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR19GSUVMRF9OVU1CRVIgPSA0NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZy4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0J5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0JZVEVTX0ZJRUxEX05VTUJFUiA9IDQ1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gcmVwZWF0ZWRCeXRlc18gPQogICAgICAgIGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQnl0ZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRCeXRlc0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJ5dGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJ5dGVzLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQnl0ZXNDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQnl0ZXMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldFJlcGVhdGVkQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJ5dGVzXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST1RPM19PUFRJT05BTF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAxMTY7CiAgICBwcml2YXRlIGludCBwcm90bzNPcHRpb25hbEludDMyXyA9IDA7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBPcHRpb25hbAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgcHJvdG8zX29wdGlvbmFsX2ludDMyID0gMTE2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsSW50MzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE9wdGlvbmFsCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBwcm90bzNfb3B0aW9uYWxfaW50MzIgPSAxMTY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQcm90bzNPcHRpb25hbEludDMyKCkgewogICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxJbnQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJPVE8zX09QVElPTkFMX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDExNzsKICAgIHByaXZhdGUgbG9uZyBwcm90bzNPcHRpb25hbEludDY0XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBwcm90bzNfb3B0aW9uYWxfaW50NjQgPSAxMTc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbEludDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxJbnQ2NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBwcm90bzNfb3B0aW9uYWxfaW50NjQgPSAxMTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxJbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0UHJvdG8zT3B0aW9uYWxJbnQ2NCgpIHsKICAgICAgcmV0dXJuIHByb3RvM09wdGlvbmFsSW50NjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST1RPM19PUFRJT05BTF9VSU5UMzJfRklFTERfTlVNQkVSID0gMTE4OwogICAgcHJpdmF0ZSBpbnQgcHJvdG8zT3B0aW9uYWxVaW50MzJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIHByb3RvM19vcHRpb25hbF91aW50MzIgPSAxMTg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbFVpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsVWludDMyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBwcm90bzNfb3B0aW9uYWxfdWludDMyID0gMTE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsVWludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFByb3RvM09wdGlvbmFsVWludDMyKCkgewogICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxVaW50MzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST1RPM19PUFRJT05BTF9VSU5UNjRfRklFTERfTlVNQkVSID0gMTE5OwogICAgcHJpdmF0ZSBsb25nIHByb3RvM09wdGlvbmFsVWludDY0XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgcHJvdG8zX29wdGlvbmFsX3VpbnQ2NCA9IDExOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsVWludDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxVaW50NjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IHByb3RvM19vcHRpb25hbF91aW50NjQgPSAxMTk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxVaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldFByb3RvM09wdGlvbmFsVWludDY0KCkgewogICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxVaW50NjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST1RPM19PUFRJT05BTF9TSU5UMzJfRklFTERfTlVNQkVSID0gMTIwOwogICAgcHJpdmF0ZSBpbnQgcHJvdG8zT3B0aW9uYWxTaW50MzJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIHByb3RvM19vcHRpb25hbF9zaW50MzIgPSAxMjA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbFNpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsU2ludDMyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBwcm90bzNfb3B0aW9uYWxfc2ludDMyID0gMTIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsU2ludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFByb3RvM09wdGlvbmFsU2ludDMyKCkgewogICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxTaW50MzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST1RPM19PUFRJT05BTF9TSU5UNjRfRklFTERfTlVNQkVSID0gMTIxOwogICAgcHJpdmF0ZSBsb25nIHByb3RvM09wdGlvbmFsU2ludDY0XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgcHJvdG8zX29wdGlvbmFsX3NpbnQ2NCA9IDEyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsU2ludDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxTaW50NjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IHByb3RvM19vcHRpb25hbF9zaW50NjQgPSAxMjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxTaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldFByb3RvM09wdGlvbmFsU2ludDY0KCkgewogICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxTaW50NjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST1RPM19PUFRJT05BTF9GSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDEyMjsKICAgIHByaXZhdGUgaW50IHByb3RvM09wdGlvbmFsRml4ZWQzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIHByb3RvM19vcHRpb25hbF9maXhlZDMyID0gMTIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxGaXhlZDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxGaXhlZDMyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgcHJvdG8zX29wdGlvbmFsX2ZpeGVkMzIgPSAxMjI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxGaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFByb3RvM09wdGlvbmFsRml4ZWQzMigpIHsKICAgICAgcmV0dXJuIHByb3RvM09wdGlvbmFsRml4ZWQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJPVE8zX09QVElPTkFMX0ZJWEVENjRfRklFTERfTlVNQkVSID0gMTIzOwogICAgcHJpdmF0ZSBsb25nIHByb3RvM09wdGlvbmFsRml4ZWQ2NF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBwcm90bzNfb3B0aW9uYWxfZml4ZWQ2NCA9IDEyMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsRml4ZWQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsRml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDY0IHByb3RvM19vcHRpb25hbF9maXhlZDY0ID0gMTIzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsRml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0UHJvdG8zT3B0aW9uYWxGaXhlZDY0KCkgewogICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxGaXhlZDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUk9UTzNfT1BUSU9OQUxfU0ZJWEVEMzJfRklFTERfTlVNQkVSID0gMTI0OwogICAgcHJpdmF0ZSBpbnQgcHJvdG8zT3B0aW9uYWxTZml4ZWQzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBwcm90bzNfb3B0aW9uYWxfc2ZpeGVkMzIgPSAxMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbFNmaXhlZDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxTZml4ZWQzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBwcm90bzNfb3B0aW9uYWxfc2ZpeGVkMzIgPSAxMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxTZml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQcm90bzNPcHRpb25hbFNmaXhlZDMyKCkgewogICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxTZml4ZWQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJPVE8zX09QVElPTkFMX1NGSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDEyNTsKICAgIHByaXZhdGUgbG9uZyBwcm90bzNPcHRpb25hbFNmaXhlZDY0XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBwcm90bzNfb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMjU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbFNmaXhlZDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxTZml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBwcm90bzNfb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMjU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxTZml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0UHJvdG8zT3B0aW9uYWxTZml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuIHByb3RvM09wdGlvbmFsU2ZpeGVkNjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST1RPM19PUFRJT05BTF9GTE9BVF9GSUVMRF9OVU1CRVIgPSAxMjY7CiAgICBwcml2YXRlIGZsb2F0IHByb3RvM09wdGlvbmFsRmxvYXRfID0gMEY7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHByb3RvM19vcHRpb25hbF9mbG9hdCA9IDEyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcm90bzNPcHRpb25hbEZsb2F0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHByb3RvM19vcHRpb25hbF9mbG9hdCA9IDEyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBwcm90bzNPcHRpb25hbEZsb2F0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0UHJvdG8zT3B0aW9uYWxGbG9hdCgpIHsKICAgICAgcmV0dXJuIHByb3RvM09wdGlvbmFsRmxvYXRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST1RPM19PUFRJT05BTF9ET1VCTEVfRklFTERfTlVNQkVSID0gMTI3OwogICAgcHJpdmF0ZSBkb3VibGUgcHJvdG8zT3B0aW9uYWxEb3VibGVfID0gMEQ7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBwcm90bzNfb3B0aW9uYWxfZG91YmxlID0gMTI3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxEb3VibGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcm90bzNPcHRpb25hbERvdWJsZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgcHJvdG8zX29wdGlvbmFsX2RvdWJsZSA9IDEyNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBwcm90bzNPcHRpb25hbERvdWJsZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRQcm90bzNPcHRpb25hbERvdWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvM09wdGlvbmFsRG91YmxlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUk9UTzNfT1BUSU9OQUxfQk9PTF9GSUVMRF9OVU1CRVIgPSAxMjg7CiAgICBwcml2YXRlIGJvb2xlYW4gcHJvdG8zT3B0aW9uYWxCb29sXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHByb3RvM19vcHRpb25hbF9ib29sID0gMTI4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxCb29sIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxCb29sKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgcHJvdG8zX29wdGlvbmFsX2Jvb2wgPSAxMjg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxCb29sLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRQcm90bzNPcHRpb25hbEJvb2woKSB7CiAgICAgIHJldHVybiBwcm90bzNPcHRpb25hbEJvb2xfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBST1RPM19PUFRJT05BTF9TVFJJTkdfRklFTERfTlVNQkVSID0gMTI5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgcHJvdG8zT3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBwcm90bzNfb3B0aW9uYWxfc3RyaW5nID0gMTI5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcm90bzNPcHRpb25hbFN0cmluZygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcHJvdG8zX29wdGlvbmFsX3N0cmluZyA9IDEyOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBwcm90bzNPcHRpb25hbFN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UHJvdG8zT3B0aW9uYWxTdHJpbmcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gcHJvdG8zT3B0aW9uYWxTdHJpbmdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgcHJvdG8zT3B0aW9uYWxTdHJpbmdfID0gczsKICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcHJvdG8zX29wdGlvbmFsX3N0cmluZyA9IDEyOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgcHJvdG8zT3B0aW9uYWxTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRQcm90bzNPcHRpb25hbFN0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHByb3RvM09wdGlvbmFsU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgcHJvdG8zT3B0aW9uYWxTdHJpbmdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUFJPVE8zX09QVElPTkFMX0JZVEVTX0ZJRUxEX05VTUJFUiA9IDEzMDsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHByb3RvM09wdGlvbmFsQnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBwcm90bzNfb3B0aW9uYWxfYnl0ZXMgPSAxMzA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbEJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxCeXRlcygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBwcm90bzNfb3B0aW9uYWxfYnl0ZXMgPSAxMzA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxCeXRlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRQcm90bzNPcHRpb25hbEJ5dGVzKCkgewogICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxCeXRlc187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gNDg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRk9SRUlHTl9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDQ5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlPiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZT4gZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSA1MDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2U+IGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSID0gNTE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkTmVzdGVkRW51bV87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IGdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocmVwZWF0ZWROZXN0ZWRFbnVtXywgcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRSZXBlYXRlZE5lc3RlZEVudW0oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHJlcGVhdGVkTmVzdGVkRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemU7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRk9SRUlHTl9FTlVNX0ZJRUxEX05VTUJFUiA9IDUyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZEZvcmVpZ25FbnVtXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bT4gcmVwZWF0ZWRGb3JlaWduRW51bV9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25FbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bSByZXN1bHQgPSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bT4gZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUxpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bT4ocmVwZWF0ZWRGb3JlaWduRW51bV8sIHJlcGVhdGVkRm9yZWlnbkVudW1fY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGb3JlaWduRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25FbnVtXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25FbnVtIGdldFJlcGVhdGVkRm9yZWlnbkVudW0oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25FbnVtX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZEZvcmVpZ25FbnVtXy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWVMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkRm9yZWlnbkVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRm9yZWlnbkVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbkVudW1fLmdldChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZEZvcmVpZ25FbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfUElFQ0VfRklFTERfTlVNQkVSID0gNTQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nUGllY2VfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nUGllY2UgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nUGllY2UgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQ09SRF9GSUVMRF9OVU1CRVIgPSA1NTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRDb3JkXyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQ29yZC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRDb3JkLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQ29yZENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZENvcmQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZENvcmQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZENvcmRfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkQ29yZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZENvcmRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDU3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiByZXBlYXRlZExhenlNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiBnZXRSZXBlYXRlZExhenlNZXNzYWdlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZExhenlNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FT0ZfVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDExMTsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDExMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mVWludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZVaW50MzIoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTExOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mVWludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9uZW9mVWludDMyKCkgewogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMSkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDExMjsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTI7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCkgewogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICByZXR1cm4gKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXzsKICAgICAgfQogICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICByZXR1cm4gKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXzsKICAgICAgfQogICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FT0ZfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDExMzsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZTdHJpbmcoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mU3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPbmVvZlN0cmluZygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICByZWYgPSBvbmVvZkZpZWxkXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPbmVvZlN0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9CWVRFU19GSUVMRF9OVU1CRVIgPSAxMTQ7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mQnl0ZXMoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDExNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZkJ5dGVzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9uZW9mQnl0ZXMoKSB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0KSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBpZiAob3B0aW9uYWxJbnQzMl8gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIG9wdGlvbmFsSW50MzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxJbnQ2NF8gIT0gMEwpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgyLCBvcHRpb25hbEludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsVWludDMyXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKDMsIG9wdGlvbmFsVWludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsVWludDY0XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCg0LCBvcHRpb25hbFVpbnQ2NF8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbFNpbnQzMl8gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQzMig1LCBvcHRpb25hbFNpbnQzMl8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbFNpbnQ2NF8gIT0gMEwpIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50NjQoNiwgb3B0aW9uYWxTaW50NjRfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxGaXhlZDMyXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMig3LCBvcHRpb25hbEZpeGVkMzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxGaXhlZDY0XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjQoOCwgb3B0aW9uYWxGaXhlZDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ZpeGVkMzJfICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQzMig5LCBvcHRpb25hbFNmaXhlZDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ZpeGVkNjRfICE9IDBMKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjQoMTAsIG9wdGlvbmFsU2ZpeGVkNjRfKTsKICAgICAgfQogICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKG9wdGlvbmFsRmxvYXRfKSAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMTEsIG9wdGlvbmFsRmxvYXRfKTsKICAgICAgfQogICAgICBpZiAoamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKG9wdGlvbmFsRG91YmxlXykgIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgxMiwgb3B0aW9uYWxEb3VibGVfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxCb29sXyAhPSBmYWxzZSkgewogICAgICAgIG91dHB1dC53cml0ZUJvb2woMTMsIG9wdGlvbmFsQm9vbF8pOwogICAgICB9CiAgICAgIGlmICghY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuaXNTdHJpbmdFbXB0eShvcHRpb25hbFN0cmluZ18pKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxNCwgb3B0aW9uYWxTdHJpbmdfKTsKICAgICAgfQogICAgICBpZiAoIW9wdGlvbmFsQnl0ZXNfLmlzRW1wdHkoKSkgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDE1LCBvcHRpb25hbEJ5dGVzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxOCwgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTksIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyMCwgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbE5lc3RlZEVudW1fICE9IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDIxLCBvcHRpb25hbE5lc3RlZEVudW1fKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxGb3JlaWduRW51bV8gIT0gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0uRk9SRUlHTl9aRVJPLmdldE51bWJlcigpKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgyMiwgb3B0aW9uYWxGb3JlaWduRW51bV8pOwogICAgICB9CiAgICAgIGlmICghY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuaXNTdHJpbmdFbXB0eShvcHRpb25hbFN0cmluZ1BpZWNlXykpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDI0LCBvcHRpb25hbFN0cmluZ1BpZWNlXyk7CiAgICAgIH0KICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KG9wdGlvbmFsQ29yZF8pKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyNSwgb3B0aW9uYWxDb3JkXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyNiwgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMjcsIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyOCwgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkSW50MzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI1MCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMk5vVGFnKHJlcGVhdGVkSW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkSW50NjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI1OCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRJbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NE5vVGFnKHJlcGVhdGVkSW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjY2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZFVpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkVWludDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyNzQpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkVWludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50NjROb1RhZyhyZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2ludDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyODIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkU2ludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzJOb1RhZyhyZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI5MCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRTaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NE5vVGFnKHJlcGVhdGVkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyOTgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkRml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzJOb1RhZyhyZXBlYXRlZEZpeGVkMzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzA2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRml4ZWQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0Tm9UYWcocmVwZWF0ZWRGaXhlZDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzE0KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZFNmaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNmaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyTm9UYWcocmVwZWF0ZWRTZml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzIyKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZFNmaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNmaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0Tm9UYWcocmVwZWF0ZWRTZml4ZWQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRmxvYXRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMzMCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRGbG9hdE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdE5vVGFnKHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMzOCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWREb3VibGVNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRG91YmxlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZU5vVGFnKHJlcGVhdGVkRG91YmxlXy5nZXREb3VibGUoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEJvb2xMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDM0Nik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRCb29sTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEJvb2xfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbE5vVGFnKHJlcGVhdGVkQm9vbF8uZ2V0Qm9vbGVhbihpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZ18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDQ0LCByZXBlYXRlZFN0cmluZ18uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQnl0ZXNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoNDUsIHJlcGVhdGVkQnl0ZXNfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg0OCwgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDQ5LCByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNTAsIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg0MTApOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkTmVzdGVkRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW1Ob1RhZyhyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRm9yZWlnbkVudW1MaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDQxOCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRGb3JlaWduRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGb3JlaWduRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcocmVwZWF0ZWRGb3JlaWduRW51bV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nUGllY2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA1NCwgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQ29yZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDU1LCByZXBlYXRlZENvcmRfLmdldFJhdyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZExhenlNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNTcsIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTEpIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoCiAgICAgICAgICAgIDExMSwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSBvbmVvZkZpZWxkXykpOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxMTIsIChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMTMsIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNCkgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKAogICAgICAgICAgICAxMTQsIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDExNSwgZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxMTYsIHByb3RvM09wdGlvbmFsSW50MzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgxMTcsIHByb3RvM09wdGlvbmFsSW50NjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoMTE4LCBwcm90bzNPcHRpb25hbFVpbnQzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCgxMTksIHByb3RvM09wdGlvbmFsVWludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyKDEyMCwgcHJvdG8zT3B0aW9uYWxTaW50MzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50NjQoMTIxLCBwcm90bzNPcHRpb25hbFNpbnQ2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzIoMTIyLCBwcm90bzNPcHRpb25hbEZpeGVkMzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0KDEyMywgcHJvdG8zT3B0aW9uYWxGaXhlZDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzIoMTI0LCBwcm90bzNPcHRpb25hbFNmaXhlZDMyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjQoMTI1LCBwcm90bzNPcHRpb25hbFNmaXhlZDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMTI2LCBwcm90bzNPcHRpb25hbEZsb2F0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKDEyNywgcHJvdG8zT3B0aW9uYWxEb3VibGVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDEyOCwgcHJvdG8zT3B0aW9uYWxCb29sXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMjksIHByb3RvM09wdGlvbmFsU3RyaW5nXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMTMwLCBwcm90bzNPcHRpb25hbEJ5dGVzXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmIChvcHRpb25hbEludDMyXyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBvcHRpb25hbEludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsSW50NjRfICE9IDBMKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSgyLCBvcHRpb25hbEludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsVWludDMyXyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoMywgb3B0aW9uYWxVaW50MzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxVaW50NjRfICE9IDBMKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemUoNCwgb3B0aW9uYWxVaW50NjRfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxTaW50MzJfICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZSg1LCBvcHRpb25hbFNpbnQzMl8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbFNpbnQ2NF8gIT0gMEwpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZSg2LCBvcHRpb25hbFNpbnQ2NF8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEZpeGVkMzJfICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRml4ZWQzMlNpemUoNywgb3B0aW9uYWxGaXhlZDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsRml4ZWQ2NF8gIT0gMEwpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRml4ZWQ2NFNpemUoOCwgb3B0aW9uYWxGaXhlZDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ZpeGVkMzJfICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ZpeGVkMzJTaXplKDksIG9wdGlvbmFsU2ZpeGVkMzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxTZml4ZWQ2NF8gIT0gMEwpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ZpeGVkNjRTaXplKDEwLCBvcHRpb25hbFNmaXhlZDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKGphdmEubGFuZy5GbG9hdC5mbG9hdFRvUmF3SW50Qml0cyhvcHRpb25hbEZsb2F0XykgIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGbG9hdFNpemUoMTEsIG9wdGlvbmFsRmxvYXRfKTsKICAgICAgfQogICAgICBpZiAoamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKG9wdGlvbmFsRG91YmxlXykgIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVEb3VibGVTaXplKDEyLCBvcHRpb25hbERvdWJsZV8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEJvb2xfICE9IGZhbHNlKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDEzLCBvcHRpb25hbEJvb2xfKTsKICAgICAgfQogICAgICBpZiAoIWNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmlzU3RyaW5nRW1wdHkob3B0aW9uYWxTdHJpbmdfKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMTQsIG9wdGlvbmFsU3RyaW5nXyk7CiAgICAgIH0KICAgICAgaWYgKCFvcHRpb25hbEJ5dGVzXy5pc0VtcHR5KCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplKDE1LCBvcHRpb25hbEJ5dGVzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE4LCBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5LCBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMCwgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbE5lc3RlZEVudW1fICE9IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMjEsIG9wdGlvbmFsTmVzdGVkRW51bV8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25FbnVtXyAhPSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bS5GT1JFSUdOX1pFUk8uZ2V0TnVtYmVyKCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMjIsIG9wdGlvbmFsRm9yZWlnbkVudW1fKTsKICAgICAgfQogICAgICBpZiAoIWNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmlzU3RyaW5nRW1wdHkob3B0aW9uYWxTdHJpbmdQaWVjZV8pKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyNCwgb3B0aW9uYWxTdHJpbmdQaWVjZV8pOwogICAgICB9CiAgICAgIGlmICghY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuaXNTdHJpbmdFbXB0eShvcHRpb25hbENvcmRfKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMjUsIG9wdGlvbmFsQ29yZF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyNiwgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyNywgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjgsIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhyZXBlYXRlZEludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZEludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkSW50NjRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRJbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhyZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkVWludDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkVWludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRVaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDY0U2l6ZU5vVGFnKHJlcGVhdGVkVWludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkVWludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkVWludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZU5vVGFnKHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRTaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50NjRTaXplTm9UYWcocmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRTaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkRml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZEZsb2F0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWREb3VibGVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSAxICogZ2V0UmVwZWF0ZWRCb29sTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRCb29sTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkQm9vbE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZ18uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEJ5dGVzXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZU5vVGFnKHJlcGVhdGVkQnl0ZXNfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRCeXRlc0xpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQ4LCByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0OSwgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNTAsIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfXJlcGVhdGVkTmVzdGVkRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRm9yZWlnbkVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZEZvcmVpZ25FbnVtXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUxpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfXJlcGVhdGVkRm9yZWlnbkVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZ1BpZWNlXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZ1BpZWNlXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkU3RyaW5nUGllY2VMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRDb3JkXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZENvcmRfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTGF6eU1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDU3LCByZXBlYXRlZExhenlNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTExKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoCiAgICAgICAgICAgICAgMTExLCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfKSk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEyLCAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMTEzLCBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTQpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplKAogICAgICAgICAgICAgIDExNCwgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMTUsIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxMTYsIHByb3RvM09wdGlvbmFsSW50MzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplKDExNywgcHJvdG8zT3B0aW9uYWxJbnQ2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKDExOCwgcHJvdG8zT3B0aW9uYWxVaW50MzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDY0U2l6ZSgxMTksIHByb3RvM09wdGlvbmFsVWludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemUoMTIwLCBwcm90bzNPcHRpb25hbFNpbnQzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTSW50NjRTaXplKDEyMSwgcHJvdG8zT3B0aW9uYWxTaW50NjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRml4ZWQzMlNpemUoMTIyLCBwcm90bzNPcHRpb25hbEZpeGVkMzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRml4ZWQ2NFNpemUoMTIzLCBwcm90bzNPcHRpb25hbEZpeGVkNjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ZpeGVkMzJTaXplKDEyNCwgcHJvdG8zT3B0aW9uYWxTZml4ZWQzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTRml4ZWQ2NFNpemUoMTI1LCBwcm90bzNPcHRpb25hbFNmaXhlZDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZsb2F0U2l6ZSgxMjYsIHByb3RvM09wdGlvbmFsRmxvYXRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRG91YmxlU2l6ZSgxMjcsIHByb3RvM09wdGlvbmFsRG91YmxlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDEyOCwgcHJvdG8zT3B0aW9uYWxCb29sXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxMjksIHByb3RvM09wdGlvbmFsU3RyaW5nXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgxMzAsIHByb3RvM09wdGlvbmFsQnl0ZXNfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyBvdGhlciA9IChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMpIG9iajsKCiAgICAgIGlmIChnZXRPcHRpb25hbEludDMyKCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQ2NCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsVWludDMyKCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsVWludDY0KCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsU2ludDMyKCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsU2ludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsU2ludDY0KCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsU2ludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsRml4ZWQzMigpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEZpeGVkMzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0T3B0aW9uYWxGaXhlZDY0KCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsRml4ZWQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbFNmaXhlZDMyKCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsU2ZpeGVkMzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFNmaXhlZDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhnZXRPcHRpb25hbEZsb2F0KCkpCiAgICAgICAgICAhPSBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgb3RoZXIuZ2V0T3B0aW9uYWxGbG9hdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldE9wdGlvbmFsRG91YmxlKCkpCiAgICAgICAgICAhPSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoCiAgICAgICAgICAgICAgb3RoZXIuZ2V0T3B0aW9uYWxEb3VibGUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsQm9vbCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEJvb2woKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldE9wdGlvbmFsU3RyaW5nKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxTdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRPcHRpb25hbEJ5dGVzKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxCeXRlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbE5lc3RlZEVudW1fICE9IG90aGVyLm9wdGlvbmFsTmVzdGVkRW51bV8pIHJldHVybiBmYWxzZTsKICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbkVudW1fICE9IG90aGVyLm9wdGlvbmFsRm9yZWlnbkVudW1fKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZSgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsU3RyaW5nUGllY2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRPcHRpb25hbENvcmQoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbENvcmQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbExhenlNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbExhenlNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoKSAhPSBvdGhlci5oYXNPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkSW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZsb2F0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRmxvYXRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRCb29sTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQm9vbExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZ0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQnl0ZXNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbEludDMyKCkgIT0gb3RoZXIuaGFzUHJvdG8zT3B0aW9uYWxJbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbEludDMyKCkpIHsKICAgICAgICBpZiAoZ2V0UHJvdG8zT3B0aW9uYWxJbnQzMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldFByb3RvM09wdGlvbmFsSW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbEludDY0KCkgIT0gb3RoZXIuaGFzUHJvdG8zT3B0aW9uYWxJbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbEludDY0KCkpIHsKICAgICAgICBpZiAoZ2V0UHJvdG8zT3B0aW9uYWxJbnQ2NCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldFByb3RvM09wdGlvbmFsSW50NjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbFVpbnQzMigpICE9IG90aGVyLmhhc1Byb3RvM09wdGlvbmFsVWludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1Byb3RvM09wdGlvbmFsVWludDMyKCkpIHsKICAgICAgICBpZiAoZ2V0UHJvdG8zT3B0aW9uYWxVaW50MzIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRQcm90bzNPcHRpb25hbFVpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1Byb3RvM09wdGlvbmFsVWludDY0KCkgIT0gb3RoZXIuaGFzUHJvdG8zT3B0aW9uYWxVaW50NjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxVaW50NjQoKSkgewogICAgICAgIGlmIChnZXRQcm90bzNPcHRpb25hbFVpbnQ2NCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldFByb3RvM09wdGlvbmFsVWludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxTaW50MzIoKSAhPSBvdGhlci5oYXNQcm90bzNPcHRpb25hbFNpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbFNpbnQzMigpKSB7CiAgICAgICAgaWYgKGdldFByb3RvM09wdGlvbmFsU2ludDMyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0UHJvdG8zT3B0aW9uYWxTaW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbFNpbnQ2NCgpICE9IG90aGVyLmhhc1Byb3RvM09wdGlvbmFsU2ludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1Byb3RvM09wdGlvbmFsU2ludDY0KCkpIHsKICAgICAgICBpZiAoZ2V0UHJvdG8zT3B0aW9uYWxTaW50NjQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRQcm90bzNPcHRpb25hbFNpbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1Byb3RvM09wdGlvbmFsRml4ZWQzMigpICE9IG90aGVyLmhhc1Byb3RvM09wdGlvbmFsRml4ZWQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbEZpeGVkMzIoKSkgewogICAgICAgIGlmIChnZXRQcm90bzNPcHRpb25hbEZpeGVkMzIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRQcm90bzNPcHRpb25hbEZpeGVkMzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbEZpeGVkNjQoKSAhPSBvdGhlci5oYXNQcm90bzNPcHRpb25hbEZpeGVkNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxGaXhlZDY0KCkpIHsKICAgICAgICBpZiAoZ2V0UHJvdG8zT3B0aW9uYWxGaXhlZDY0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0UHJvdG8zT3B0aW9uYWxGaXhlZDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxTZml4ZWQzMigpICE9IG90aGVyLmhhc1Byb3RvM09wdGlvbmFsU2ZpeGVkMzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxTZml4ZWQzMigpKSB7CiAgICAgICAgaWYgKGdldFByb3RvM09wdGlvbmFsU2ZpeGVkMzIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRQcm90bzNPcHRpb25hbFNmaXhlZDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxTZml4ZWQ2NCgpICE9IG90aGVyLmhhc1Byb3RvM09wdGlvbmFsU2ZpeGVkNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxTZml4ZWQ2NCgpKSB7CiAgICAgICAgaWYgKGdldFByb3RvM09wdGlvbmFsU2ZpeGVkNjQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRQcm90bzNPcHRpb25hbFNmaXhlZDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxGbG9hdCgpICE9IG90aGVyLmhhc1Byb3RvM09wdGlvbmFsRmxvYXQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxGbG9hdCgpKSB7CiAgICAgICAgaWYgKGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhnZXRQcm90bzNPcHRpb25hbEZsb2F0KCkpCiAgICAgICAgICAgICE9IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgICAgIG90aGVyLmdldFByb3RvM09wdGlvbmFsRmxvYXQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxEb3VibGUoKSAhPSBvdGhlci5oYXNQcm90bzNPcHRpb25hbERvdWJsZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbERvdWJsZSgpKSB7CiAgICAgICAgaWYgKGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRQcm90bzNPcHRpb25hbERvdWJsZSgpKQogICAgICAgICAgICAhPSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoCiAgICAgICAgICAgICAgICBvdGhlci5nZXRQcm90bzNPcHRpb25hbERvdWJsZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbEJvb2woKSAhPSBvdGhlci5oYXNQcm90bzNPcHRpb25hbEJvb2woKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxCb29sKCkpIHsKICAgICAgICBpZiAoZ2V0UHJvdG8zT3B0aW9uYWxCb29sKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0UHJvdG8zT3B0aW9uYWxCb29sKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxTdHJpbmcoKSAhPSBvdGhlci5oYXNQcm90bzNPcHRpb25hbFN0cmluZygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbFN0cmluZygpKSB7CiAgICAgICAgaWYgKCFnZXRQcm90bzNPcHRpb25hbFN0cmluZygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UHJvdG8zT3B0aW9uYWxTdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxCeXRlcygpICE9IG90aGVyLmhhc1Byb3RvM09wdGlvbmFsQnl0ZXMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxCeXRlcygpKSB7CiAgICAgICAgaWYgKCFnZXRQcm90bzNPcHRpb25hbEJ5dGVzKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQcm90bzNPcHRpb25hbEJ5dGVzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXJlcGVhdGVkTmVzdGVkRW51bV8uZXF1YWxzKG90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV8pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghcmVwZWF0ZWRGb3JlaWduRW51bV8uZXF1YWxzKG90aGVyLnJlcGVhdGVkRm9yZWlnbkVudW1fKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nUGllY2VMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZENvcmRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkTGF6eU1lc3NhZ2VMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRPbmVvZkZpZWxkQ2FzZSgpLmVxdWFscyhvdGhlci5nZXRPbmVvZkZpZWxkQ2FzZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBzd2l0Y2ggKG9uZW9mRmllbGRDYXNlXykgewogICAgICAgIGNhc2UgMTExOgogICAgICAgICAgaWYgKGdldE9uZW9mVWludDMyKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRPbmVvZlVpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDExMjoKICAgICAgICAgIGlmICghZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9uZW9mTmVzdGVkTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMTM6CiAgICAgICAgICBpZiAoIWdldE9uZW9mU3RyaW5nKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9uZW9mU3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDExNDoKICAgICAgICAgIGlmICghZ2V0T25lb2ZCeXRlcygpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPbmVvZkJ5dGVzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMigpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBnZXRPcHRpb25hbEludDY0KCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9VSU5UMzJfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFVpbnQzMigpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9VSU5UNjRfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0T3B0aW9uYWxVaW50NjQoKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsU2ludDMyKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBnZXRPcHRpb25hbFNpbnQ2NCgpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRklYRUQzMl9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsRml4ZWQzMigpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgIGdldE9wdGlvbmFsRml4ZWQ2NCgpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFNmaXhlZDMyKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1NGSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgIGdldE9wdGlvbmFsU2ZpeGVkNjQoKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0ZMT0FUX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgZ2V0T3B0aW9uYWxGbG9hdCgpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRE9VQkxFX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgIGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRPcHRpb25hbERvdWJsZSgpKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0JPT0xfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKAogICAgICAgICAgZ2V0T3B0aW9uYWxCb29sKCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0JZVEVTX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxCeXRlcygpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9GT1JFSUdOX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lNUE9SVF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgb3B0aW9uYWxOZXN0ZWRFbnVtXzsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRk9SRUlHTl9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgb3B0aW9uYWxGb3JlaWduRW51bV87CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1NUUklOR19QSUVDRV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsU3RyaW5nUGllY2UoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9DT1JEX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxDb3JkKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfUFVCTElDX0lNUE9SVF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbExhenlNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9MQVpZX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVU5WRVJJRklFRF9MQVpZX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfTEFaWV9JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkSW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkSW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkVWludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9VSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkVWludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkVWludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9VSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkVWludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2ludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2ludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRml4ZWQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRklYRUQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NGSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NGSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRmxvYXRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZMT0FUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRG91YmxlQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ET1VCTEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQm9vbENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQk9PTF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRCb29sTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQnl0ZXNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0JZVEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1Byb3RvM09wdGlvbmFsSW50MzIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBST1RPM19PUFRJT05BTF9JTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UHJvdG8zT3B0aW9uYWxJbnQzMigpOwogICAgICB9CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbEludDY0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQUk9UTzNfT1BUSU9OQUxfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldFByb3RvM09wdGlvbmFsSW50NjQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc1Byb3RvM09wdGlvbmFsVWludDMyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQUk9UTzNfT1BUSU9OQUxfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQcm90bzNPcHRpb25hbFVpbnQzMigpOwogICAgICB9CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbFVpbnQ2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUFJPVE8zX09QVElPTkFMX1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0UHJvdG8zT3B0aW9uYWxVaW50NjQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc1Byb3RvM09wdGlvbmFsU2ludDMyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQUk9UTzNfT1BUSU9OQUxfU0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQcm90bzNPcHRpb25hbFNpbnQzMigpOwogICAgICB9CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbFNpbnQ2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUFJPVE8zX09QVElPTkFMX1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0UHJvdG8zT3B0aW9uYWxTaW50NjQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc1Byb3RvM09wdGlvbmFsRml4ZWQzMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUFJPVE8zX09QVElPTkFMX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFByb3RvM09wdGlvbmFsRml4ZWQzMigpOwogICAgICB9CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbEZpeGVkNjQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBST1RPM19PUFRJT05BTF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXRQcm90bzNPcHRpb25hbEZpeGVkNjQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc1Byb3RvM09wdGlvbmFsU2ZpeGVkMzIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBST1RPM19PUFRJT05BTF9TRklYRUQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UHJvdG8zT3B0aW9uYWxTZml4ZWQzMigpOwogICAgICB9CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbFNmaXhlZDY0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQUk9UTzNfT1BUSU9OQUxfU0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldFByb3RvM09wdGlvbmFsU2ZpeGVkNjQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc1Byb3RvM09wdGlvbmFsRmxvYXQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBST1RPM19PUFRJT05BTF9GTE9BVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICBnZXRQcm90bzNPcHRpb25hbEZsb2F0KCkpOwogICAgICB9CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbERvdWJsZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUFJPVE8zX09QVElPTkFMX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldFByb3RvM09wdGlvbmFsRG91YmxlKCkpKTsKICAgICAgfQogICAgICBpZiAoaGFzUHJvdG8zT3B0aW9uYWxCb29sKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQUk9UTzNfT1BUSU9OQUxfQk9PTF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgICAgZ2V0UHJvdG8zT3B0aW9uYWxCb29sKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbFN0cmluZygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUFJPVE8zX09QVElPTkFMX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UHJvdG8zT3B0aW9uYWxTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNQcm90bzNPcHRpb25hbEJ5dGVzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQUk9UTzNfT1BUSU9OQUxfQllURVNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFByb3RvM09wdGlvbmFsQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRk9SRUlHTl9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU1QT1JUX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZE5lc3RlZEVudW1Db3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXBlYXRlZE5lc3RlZEVudW1fLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRm9yZWlnbkVudW1Db3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZPUkVJR05fRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcmVwZWF0ZWRGb3JlaWduRW51bV8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HX1BJRUNFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQ29yZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQ09SRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0xBWllfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIHN3aXRjaCAob25lb2ZGaWVsZENhc2VfKSB7CiAgICAgICAgY2FzZSAxMTE6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPTkVPRl9VSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZVaW50MzIoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTEyOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTEzOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mU3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTE0OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfQllURVNfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZCeXRlcygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoaXMgcHJvdG8gaW5jbHVkZXMgZXZlcnkgdHlwZSBvZiBmaWVsZCBpbiBib3RoIHNpbmd1bGFyIGFuZCByZXBlYXRlZAogICAgICogZm9ybXMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcykKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLmNsYXNzLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBiaXRGaWVsZDFfID0gMDsKICAgICAgICBiaXRGaWVsZDJfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyXyA9IDA7CiAgICAgICAgb3B0aW9uYWxJbnQ2NF8gPSAwTDsKICAgICAgICBvcHRpb25hbFVpbnQzMl8gPSAwOwogICAgICAgIG9wdGlvbmFsVWludDY0XyA9IDBMOwogICAgICAgIG9wdGlvbmFsU2ludDMyXyA9IDA7CiAgICAgICAgb3B0aW9uYWxTaW50NjRfID0gMEw7CiAgICAgICAgb3B0aW9uYWxGaXhlZDMyXyA9IDA7CiAgICAgICAgb3B0aW9uYWxGaXhlZDY0XyA9IDBMOwogICAgICAgIG9wdGlvbmFsU2ZpeGVkMzJfID0gMDsKICAgICAgICBvcHRpb25hbFNmaXhlZDY0XyA9IDBMOwogICAgICAgIG9wdGlvbmFsRmxvYXRfID0gMEY7CiAgICAgICAgb3B0aW9uYWxEb3VibGVfID0gMEQ7CiAgICAgICAgb3B0aW9uYWxCb29sXyA9IGZhbHNlOwogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgICAgIG9wdGlvbmFsQnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgICAgICBvcHRpb25hbEZvcmVpZ25FbnVtXyA9IDA7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSAiIjsKICAgICAgICBvcHRpb25hbENvcmRfID0gIiI7CiAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZEJ5dGVzXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIHByb3RvM09wdGlvbmFsSW50MzJfID0gMDsKICAgICAgICBwcm90bzNPcHRpb25hbEludDY0XyA9IDBMOwogICAgICAgIHByb3RvM09wdGlvbmFsVWludDMyXyA9IDA7CiAgICAgICAgcHJvdG8zT3B0aW9uYWxVaW50NjRfID0gMEw7CiAgICAgICAgcHJvdG8zT3B0aW9uYWxTaW50MzJfID0gMDsKICAgICAgICBwcm90bzNPcHRpb25hbFNpbnQ2NF8gPSAwTDsKICAgICAgICBwcm90bzNPcHRpb25hbEZpeGVkMzJfID0gMDsKICAgICAgICBwcm90bzNPcHRpb25hbEZpeGVkNjRfID0gMEw7CiAgICAgICAgcHJvdG8zT3B0aW9uYWxTZml4ZWQzMl8gPSAwOwogICAgICAgIHByb3RvM09wdGlvbmFsU2ZpeGVkNjRfID0gMEw7CiAgICAgICAgcHJvdG8zT3B0aW9uYWxGbG9hdF8gPSAwRjsKICAgICAgICBwcm90bzNPcHRpb25hbERvdWJsZV8gPSAwRDsKICAgICAgICBwcm90bzNPcHRpb25hbEJvb2xfID0gZmFsc2U7CiAgICAgICAgcHJvdG8zT3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgICAgcHJvdG8zT3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDEwMDAwMDApOwogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDQwMDAwMDApOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDgwMDAwMDApOwogICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDEwMDAwMDAwKTsKICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZENvcmRfID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMgcmVzdWx0ID0gbmV3IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyh0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMV8gIT0gMCkgeyBidWlsZFBhcnRpYWwxKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQyXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDIocmVzdWx0KTsgfQogICAgICAgIGJ1aWxkUGFydGlhbE9uZW9mcyhyZXN1bHQpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIHJlc3VsdCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAyMDAwMDAwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkTmVzdGVkRW51bV8gPSByZXBlYXRlZE5lc3RlZEVudW1fOwogICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEZvcmVpZ25FbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5yZXBlYXRlZEZvcmVpZ25FbnVtXyA9IHJlcGVhdGVkRm9yZWlnbkVudW1fOwogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRMYXp5TWVzc2FnZV8pOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSByZXBlYXRlZExhenlNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyXyA9IG9wdGlvbmFsSW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50NjRfID0gb3B0aW9uYWxJbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxVaW50MzJfID0gb3B0aW9uYWxVaW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVWludDY0XyA9IG9wdGlvbmFsVWludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFNpbnQzMl8gPSBvcHRpb25hbFNpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTaW50NjRfID0gb3B0aW9uYWxTaW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRml4ZWQzMl8gPSBvcHRpb25hbEZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRml4ZWQ2NF8gPSBvcHRpb25hbEZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsU2ZpeGVkMzJfID0gb3B0aW9uYWxTZml4ZWQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTZml4ZWQ2NF8gPSBvcHRpb25hbFNmaXhlZDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEZsb2F0XyA9IG9wdGlvbmFsRmxvYXRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRG91YmxlXyA9IG9wdGlvbmFsRG91YmxlXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEJvb2xfID0gb3B0aW9uYWxCb29sXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFN0cmluZ18gPSBvcHRpb25hbFN0cmluZ187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxCeXRlc18gPSBvcHRpb25hbEJ5dGVzXzsKICAgICAgICB9CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPSBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPSBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbEltcG9ydE1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsTmVzdGVkRW51bV8gPSBvcHRpb25hbE5lc3RlZEVudW1fOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRm9yZWlnbkVudW1fID0gb3B0aW9uYWxGb3JlaWduRW51bV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTdHJpbmdQaWVjZV8gPSBvcHRpb25hbFN0cmluZ1BpZWNlXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbENvcmRfID0gb3B0aW9uYWxDb3JkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID0gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXwogICAgICAgICAgICAgIDogb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbExhenlNZXNzYWdlXyA9IG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbExhenlNZXNzYWdlXwogICAgICAgICAgICAgIDogb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfID0gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXyA9IG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXwogICAgICAgICAgICAgIDogb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbnQzMl8gPSByZXBlYXRlZEludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEludDY0XyA9IHJlcGVhdGVkSW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFVpbnQzMl8gPSByZXBlYXRlZFVpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkVWludDY0XyA9IHJlcGVhdGVkVWludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTaW50MzJfID0gcmVwZWF0ZWRTaW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNpbnQ2NF8gPSByZXBlYXRlZFNpbnQ2NF87CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwxKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDFfID0gYml0RmllbGQxXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRGaXhlZDMyXyA9IHJlcGVhdGVkRml4ZWQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZpeGVkNjRfID0gcmVwZWF0ZWRGaXhlZDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNmaXhlZDMyXyA9IHJlcGVhdGVkU2ZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2ZpeGVkNjRfID0gcmVwZWF0ZWRTZml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRGbG9hdF8gPSByZXBlYXRlZEZsb2F0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWREb3VibGVfID0gcmVwZWF0ZWREb3VibGVfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRCb29sXyA9IHJlcGVhdGVkQm9vbF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nXyA9IHJlcGVhdGVkU3RyaW5nXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQnl0ZXNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEJ5dGVzXyA9IHJlcGVhdGVkQnl0ZXNfOwogICAgICAgIH0KICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5wcm90bzNPcHRpb25hbEludDMyXyA9IHByb3RvM09wdGlvbmFsSW50MzJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnByb3RvM09wdGlvbmFsSW50NjRfID0gcHJvdG8zT3B0aW9uYWxJbnQ2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucHJvdG8zT3B0aW9uYWxVaW50MzJfID0gcHJvdG8zT3B0aW9uYWxVaW50MzJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnByb3RvM09wdGlvbmFsVWludDY0XyA9IHByb3RvM09wdGlvbmFsVWludDY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5wcm90bzNPcHRpb25hbFNpbnQzMl8gPSBwcm90bzNPcHRpb25hbFNpbnQzMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucHJvdG8zT3B0aW9uYWxTaW50NjRfID0gcHJvdG8zT3B0aW9uYWxTaW50NjRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnByb3RvM09wdGlvbmFsRml4ZWQzMl8gPSBwcm90bzNPcHRpb25hbEZpeGVkMzJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnByb3RvM09wdGlvbmFsRml4ZWQ2NF8gPSBwcm90bzNPcHRpb25hbEZpeGVkNjRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnByb3RvM09wdGlvbmFsU2ZpeGVkMzJfID0gcHJvdG8zT3B0aW9uYWxTZml4ZWQzMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucHJvdG8zT3B0aW9uYWxTZml4ZWQ2NF8gPSBwcm90bzNPcHRpb25hbFNmaXhlZDY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5wcm90bzNPcHRpb25hbEZsb2F0XyA9IHByb3RvM09wdGlvbmFsRmxvYXRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnByb3RvM09wdGlvbmFsRG91YmxlXyA9IHByb3RvM09wdGlvbmFsRG91YmxlXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5wcm90bzNPcHRpb25hbEJvb2xfID0gcHJvdG8zT3B0aW9uYWxCb29sXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5wcm90bzNPcHRpb25hbFN0cmluZ18gPSBwcm90bzNPcHRpb25hbFN0cmluZ187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucHJvdG8zT3B0aW9uYWxCeXRlc18gPSBwcm90bzNPcHRpb25hbEJ5dGVzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZ1BpZWNlXyA9IHJlcGVhdGVkU3RyaW5nUGllY2VfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRDb3JkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRDb3JkXyA9IHJlcGVhdGVkQ29yZF87CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwyKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDJfID0gYml0RmllbGQyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbE9uZW9mcyhwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRDYXNlXyA9IG9uZW9mRmllbGRDYXNlXzsKICAgICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSB0aGlzLm9uZW9mRmllbGRfOwogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyICYmCiAgICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsSW50MzIoKSAhPSAwKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyKG90aGVyLmdldE9wdGlvbmFsSW50MzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbEludDY0KCkgIT0gMEwpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50NjQob3RoZXIuZ2V0T3B0aW9uYWxJbnQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsVWludDMyKCkgIT0gMCkgewogICAgICAgICAgc2V0T3B0aW9uYWxVaW50MzIob3RoZXIuZ2V0T3B0aW9uYWxVaW50MzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbFVpbnQ2NCgpICE9IDBMKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFVpbnQ2NChvdGhlci5nZXRPcHRpb25hbFVpbnQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsU2ludDMyKCkgIT0gMCkgewogICAgICAgICAgc2V0T3B0aW9uYWxTaW50MzIob3RoZXIuZ2V0T3B0aW9uYWxTaW50MzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbFNpbnQ2NCgpICE9IDBMKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFNpbnQ2NChvdGhlci5nZXRPcHRpb25hbFNpbnQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsRml4ZWQzMigpICE9IDApIHsKICAgICAgICAgIHNldE9wdGlvbmFsRml4ZWQzMihvdGhlci5nZXRPcHRpb25hbEZpeGVkMzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbEZpeGVkNjQoKSAhPSAwTCkgewogICAgICAgICAgc2V0T3B0aW9uYWxGaXhlZDY0KG90aGVyLmdldE9wdGlvbmFsRml4ZWQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsU2ZpeGVkMzIoKSAhPSAwKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFNmaXhlZDMyKG90aGVyLmdldE9wdGlvbmFsU2ZpeGVkMzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbFNmaXhlZDY0KCkgIT0gMEwpIHsKICAgICAgICAgIHNldE9wdGlvbmFsU2ZpeGVkNjQob3RoZXIuZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsRmxvYXQoKSAhPSAwRikgewogICAgICAgICAgc2V0T3B0aW9uYWxGbG9hdChvdGhlci5nZXRPcHRpb25hbEZsb2F0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxEb3VibGUoKSAhPSAwRCkgewogICAgICAgICAgc2V0T3B0aW9uYWxEb3VibGUob3RoZXIuZ2V0T3B0aW9uYWxEb3VibGUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbEJvb2woKSAhPSBmYWxzZSkgewogICAgICAgICAgc2V0T3B0aW9uYWxCb29sKG90aGVyLmdldE9wdGlvbmFsQm9vbCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5nZXRPcHRpb25hbFN0cmluZygpLmlzRW1wdHkoKSkgewogICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gb3RoZXIub3B0aW9uYWxTdHJpbmdfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbEJ5dGVzKCkgIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEJ5dGVzKG90aGVyLmdldE9wdGlvbmFsQnl0ZXMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbE5lc3RlZE1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsRm9yZWlnbk1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsSW1wb3J0TWVzc2FnZShvdGhlci5nZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5vcHRpb25hbE5lc3RlZEVudW1fICE9IDApIHsKICAgICAgICAgIHNldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIub3B0aW9uYWxGb3JlaWduRW51bV8gIT0gMCkgewogICAgICAgICAgc2V0T3B0aW9uYWxGb3JlaWduRW51bVZhbHVlKG90aGVyLmdldE9wdGlvbmFsRm9yZWlnbkVudW1WYWx1ZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5nZXRPcHRpb25hbFN0cmluZ1BpZWNlKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IG90aGVyLm9wdGlvbmFsU3RyaW5nUGllY2VfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZ2V0T3B0aW9uYWxDb3JkKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBvcHRpb25hbENvcmRfID0gb3RoZXIub3B0aW9uYWxDb3JkXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbExhenlNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBvdGhlci5yZXBlYXRlZEludDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZEludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBvdGhlci5yZXBlYXRlZEludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFVpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRVaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBvdGhlci5yZXBlYXRlZFVpbnQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRVaW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkVWludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFVpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDY0XyA9IG90aGVyLnJlcGVhdGVkVWludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFVpbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gb3RoZXIucmVwZWF0ZWRTaW50MzJfOwogICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8gPSBvdGhlci5yZXBlYXRlZFNpbnQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IG90aGVyLnJlcGVhdGVkRml4ZWQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGaXhlZDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBvdGhlci5yZXBlYXRlZEZpeGVkNjRfOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTZml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTZml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gb3RoZXIucmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gb3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gb3RoZXIucmVwZWF0ZWRGbG9hdF87CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGbG9hdF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWREb3VibGVfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRG91YmxlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gb3RoZXIucmVwZWF0ZWREb3VibGVfOwogICAgICAgICAgICByZXBlYXRlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRG91YmxlXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkQm9vbF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8gPSBvdGhlci5yZXBlYXRlZEJvb2xfOwogICAgICAgICAgICByZXBlYXRlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkQm9vbF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTdHJpbmdfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU3RyaW5nXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmdfID0gb3RoZXIucmVwZWF0ZWRTdHJpbmdfOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZ18uYWRkQWxsKG90aGVyLnJlcGVhdGVkU3RyaW5nXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEJ5dGVzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEJ5dGVzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRCeXRlc18gPSBvdGhlci5yZXBlYXRlZEJ5dGVzXzsKICAgICAgICAgICAgcmVwZWF0ZWRCeXRlc18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJ5dGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkQnl0ZXNfLmFkZEFsbChvdGhlci5yZXBlYXRlZEJ5dGVzXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1Byb3RvM09wdGlvbmFsSW50MzIoKSkgewogICAgICAgICAgc2V0UHJvdG8zT3B0aW9uYWxJbnQzMihvdGhlci5nZXRQcm90bzNPcHRpb25hbEludDMyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUHJvdG8zT3B0aW9uYWxJbnQ2NCgpKSB7CiAgICAgICAgICBzZXRQcm90bzNPcHRpb25hbEludDY0KG90aGVyLmdldFByb3RvM09wdGlvbmFsSW50NjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNQcm90bzNPcHRpb25hbFVpbnQzMigpKSB7CiAgICAgICAgICBzZXRQcm90bzNPcHRpb25hbFVpbnQzMihvdGhlci5nZXRQcm90bzNPcHRpb25hbFVpbnQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1Byb3RvM09wdGlvbmFsVWludDY0KCkpIHsKICAgICAgICAgIHNldFByb3RvM09wdGlvbmFsVWludDY0KG90aGVyLmdldFByb3RvM09wdGlvbmFsVWludDY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUHJvdG8zT3B0aW9uYWxTaW50MzIoKSkgewogICAgICAgICAgc2V0UHJvdG8zT3B0aW9uYWxTaW50MzIob3RoZXIuZ2V0UHJvdG8zT3B0aW9uYWxTaW50MzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNQcm90bzNPcHRpb25hbFNpbnQ2NCgpKSB7CiAgICAgICAgICBzZXRQcm90bzNPcHRpb25hbFNpbnQ2NChvdGhlci5nZXRQcm90bzNPcHRpb25hbFNpbnQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1Byb3RvM09wdGlvbmFsRml4ZWQzMigpKSB7CiAgICAgICAgICBzZXRQcm90bzNPcHRpb25hbEZpeGVkMzIob3RoZXIuZ2V0UHJvdG8zT3B0aW9uYWxGaXhlZDMyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUHJvdG8zT3B0aW9uYWxGaXhlZDY0KCkpIHsKICAgICAgICAgIHNldFByb3RvM09wdGlvbmFsRml4ZWQ2NChvdGhlci5nZXRQcm90bzNPcHRpb25hbEZpeGVkNjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNQcm90bzNPcHRpb25hbFNmaXhlZDMyKCkpIHsKICAgICAgICAgIHNldFByb3RvM09wdGlvbmFsU2ZpeGVkMzIob3RoZXIuZ2V0UHJvdG8zT3B0aW9uYWxTZml4ZWQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1Byb3RvM09wdGlvbmFsU2ZpeGVkNjQoKSkgewogICAgICAgICAgc2V0UHJvdG8zT3B0aW9uYWxTZml4ZWQ2NChvdGhlci5nZXRQcm90bzNPcHRpb25hbFNmaXhlZDY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUHJvdG8zT3B0aW9uYWxGbG9hdCgpKSB7CiAgICAgICAgICBzZXRQcm90bzNPcHRpb25hbEZsb2F0KG90aGVyLmdldFByb3RvM09wdGlvbmFsRmxvYXQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNQcm90bzNPcHRpb25hbERvdWJsZSgpKSB7CiAgICAgICAgICBzZXRQcm90bzNPcHRpb25hbERvdWJsZShvdGhlci5nZXRQcm90bzNPcHRpb25hbERvdWJsZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1Byb3RvM09wdGlvbmFsQm9vbCgpKSB7CiAgICAgICAgICBzZXRQcm90bzNPcHRpb25hbEJvb2wob3RoZXIuZ2V0UHJvdG8zT3B0aW9uYWxCb29sKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUHJvdG8zT3B0aW9uYWxTdHJpbmcoKSkgewogICAgICAgICAgcHJvdG8zT3B0aW9uYWxTdHJpbmdfID0gb3RoZXIucHJvdG8zT3B0aW9uYWxTdHJpbmdfOwogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwNDAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNQcm90bzNPcHRpb25hbEJ5dGVzKCkpIHsKICAgICAgICAgIHNldFByb3RvM09wdGlvbmFsQnl0ZXMob3RoZXIuZ2V0UHJvdG8zT3B0aW9uYWxCeXRlcygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDEwMDAwMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmFkZEFsbChvdGhlci5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRGb3JlaWduTWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDIwMDAwMDApOwogICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkSW1wb3J0TWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDQwMDAwMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW1wb3J0TWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZEltcG9ydE1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDA0MDAwMDAwKTsKICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIucmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGRBbGwob3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZvcmVpZ25FbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25FbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8gPSBvdGhlci5yZXBlYXRlZEZvcmVpZ25FbnVtXzsKICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MTAwMDAwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGb3JlaWduRW51bV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTdHJpbmdQaWVjZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmdQaWVjZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfID0gb3RoZXIucmVwZWF0ZWRTdHJpbmdQaWVjZV87CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU3RyaW5nUGllY2VfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQ29yZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRDb3JkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRDb3JkXyA9IG90aGVyLnJlcGVhdGVkQ29yZF87CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQ29yZElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZENvcmRfLmFkZEFsbChvdGhlci5yZXBlYXRlZENvcmRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRMYXp5TWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkTGF6eU1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkTGF6eU1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZExhenlNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZExhenlNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkTGF6eU1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzd2l0Y2ggKG90aGVyLmdldE9uZW9mRmllbGRDYXNlKCkpIHsKICAgICAgICAgIGNhc2UgT05FT0ZfVUlOVDMyOiB7CiAgICAgICAgICAgIHNldE9uZW9mVWludDMyKG90aGVyLmdldE9uZW9mVWludDMyKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgT05FT0ZfTkVTVEVEX01FU1NBR0U6IHsKICAgICAgICAgICAgbWVyZ2VPbmVvZk5lc3RlZE1lc3NhZ2Uob3RoZXIuZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgT05FT0ZfU1RSSU5HOiB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMzsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBvdGhlci5vbmVvZkZpZWxkXzsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBPTkVPRl9CWVRFUzogewogICAgICAgICAgICBzZXRPbmVvZkJ5dGVzKG90aGVyLmdldE9uZW9mQnl0ZXMoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBPTkVPRkZJRUxEX05PVF9TRVQ6IHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQzMl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQ2NF8gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMjQ6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsVWludDMyXyA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgMzI6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsVWludDY0XyA9IGlucHV0LnJlYWRVSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMgogICAgICAgICAgICAgIGNhc2UgNDA6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsU2ludDMyXyA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MAogICAgICAgICAgICAgIGNhc2UgNDg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsU2ludDY0XyA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OAogICAgICAgICAgICAgIGNhc2UgNjE6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsRml4ZWQzMl8gPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYxCiAgICAgICAgICAgICAgY2FzZSA2NTogewogICAgICAgICAgICAgICAgb3B0aW9uYWxGaXhlZDY0XyA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjUKICAgICAgICAgICAgICBjYXNlIDc3OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFNmaXhlZDMyXyA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc3CiAgICAgICAgICAgICAgY2FzZSA4MTogewogICAgICAgICAgICAgICAgb3B0aW9uYWxTZml4ZWQ2NF8gPSBpbnB1dC5yZWFkU0ZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MQogICAgICAgICAgICAgIGNhc2UgOTM6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsRmxvYXRfID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTMKICAgICAgICAgICAgICBjYXNlIDk3OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbERvdWJsZV8gPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTcKICAgICAgICAgICAgICBjYXNlIDEwNDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxCb29sXyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA0CiAgICAgICAgICAgICAgY2FzZSAxMTQ6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExNAogICAgICAgICAgICAgIGNhc2UgMTIyOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEJ5dGVzXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMgogICAgICAgICAgICAgIGNhc2UgMTQ2OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0NgogICAgICAgICAgICAgIGNhc2UgMTU0OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTQKICAgICAgICAgICAgICBjYXNlIDE2MjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjIKICAgICAgICAgICAgICBjYXNlIDE2ODogewogICAgICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTY4CiAgICAgICAgICAgICAgY2FzZSAxNzY6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzYKICAgICAgICAgICAgICBjYXNlIDE5NDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOTQKICAgICAgICAgICAgICBjYXNlIDIwMjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxDb3JkXyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIwMgogICAgICAgICAgICAgIGNhc2UgMjEwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxMAogICAgICAgICAgICAgIGNhc2UgMjE4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMTgKICAgICAgICAgICAgICBjYXNlIDIyNjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIyNgogICAgICAgICAgICAgIGNhc2UgMjQ4OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0OAogICAgICAgICAgICAgIGNhc2UgMjUwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTAKICAgICAgICAgICAgICBjYXNlIDI1NjogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1NgogICAgICAgICAgICAgIGNhc2UgMjU4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjU4CiAgICAgICAgICAgICAgY2FzZSAyNjQ6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjY0CiAgICAgICAgICAgICAgY2FzZSAyNjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEludChpbnB1dC5yZWFkVUludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2NgogICAgICAgICAgICAgIGNhc2UgMjcyOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjcyCiAgICAgICAgICAgICAgY2FzZSAyNzQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNzQKICAgICAgICAgICAgICBjYXNlIDI4MDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODAKICAgICAgICAgICAgICBjYXNlIDI4MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkSW50KGlucHV0LnJlYWRTSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjgyCiAgICAgICAgICAgICAgY2FzZSAyODg6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODgKICAgICAgICAgICAgICBjYXNlIDI5MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5MAogICAgICAgICAgICAgIGNhc2UgMzAxOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMwMQogICAgICAgICAgICAgIGNhc2UgMjk4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KGlucHV0LnJlYWRGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5OAogICAgICAgICAgICAgIGNhc2UgMzA1OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzA1CiAgICAgICAgICAgICAgY2FzZSAzMDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRMb25nKGlucHV0LnJlYWRGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMwNgogICAgICAgICAgICAgIGNhc2UgMzE3OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMxNwogICAgICAgICAgICAgIGNhc2UgMzE0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQoaW5wdXQucmVhZFNGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMxNAogICAgICAgICAgICAgIGNhc2UgMzIxOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIxCiAgICAgICAgICAgICAgY2FzZSAzMjI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcoaW5wdXQucmVhZFNGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyMgogICAgICAgICAgICAgIGNhc2UgMzMzOiB7CiAgICAgICAgICAgICAgICBmbG9hdCB2ID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMzMKICAgICAgICAgICAgICBjYXNlIDMzMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkRmxvYXQoaW5wdXQucmVhZEZsb2F0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzMAogICAgICAgICAgICAgIGNhc2UgMzM3OiB7CiAgICAgICAgICAgICAgICBkb3VibGUgdiA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkRG91YmxlKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzNwogICAgICAgICAgICAgIGNhc2UgMzM4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfLmFkZERvdWJsZShpbnB1dC5yZWFkRG91YmxlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzOAogICAgICAgICAgICAgIGNhc2UgMzQ0OiB7CiAgICAgICAgICAgICAgICBib29sZWFuIHYgPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEJvb2xlYW4odik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQ0CiAgICAgICAgICAgICAgY2FzZSAzNDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoYWxsb2MgLyAxKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRCb29sXy5hZGRCb29sZWFuKGlucHV0LnJlYWRCb29sKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0NgogICAgICAgICAgICAgIGNhc2UgMzU0OiB7CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZ18uYWRkKHMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM1NAogICAgICAgICAgICAgIGNhc2UgMzYyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdiA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRCeXRlc18uYWRkKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM2MgogICAgICAgICAgICAgIGNhc2UgMzg2OiB7CiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UucGFyc2VyKCksCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzg2CiAgICAgICAgICAgICAgY2FzZSAzOTQ6IHsKICAgICAgICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZS5wYXJzZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzk0CiAgICAgICAgICAgICAgY2FzZSA0MDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAyCiAgICAgICAgICAgICAgY2FzZSA0MDg6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQwOAogICAgICAgICAgICAgIGNhc2UgNDEwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDEwCiAgICAgICAgICAgICAgY2FzZSA0MTY6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDE2CiAgICAgICAgICAgICAgY2FzZSA0MTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQxOAogICAgICAgICAgICAgIGNhc2UgNDM0OiB7CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfLmFkZChzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MzQKICAgICAgICAgICAgICBjYXNlIDQ0MjogewogICAgICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZENvcmRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkQ29yZF8uYWRkKHMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ0MgogICAgICAgICAgICAgIGNhc2UgNDU4OiB7CiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UucGFyc2VyKCksCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ1OAogICAgICAgICAgICAgIGNhc2UgODg4OiB7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4ODgKICAgICAgICAgICAgICBjYXNlIDg5ODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4OTgKICAgICAgICAgICAgICBjYXNlIDkwNjogewogICAgICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTM7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTA2CiAgICAgICAgICAgICAgY2FzZSA5MTQ6IHsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTE0CiAgICAgICAgICAgICAgY2FzZSA5MjI6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkyMgogICAgICAgICAgICAgIGNhc2UgOTI4OiB7CiAgICAgICAgICAgICAgICBwcm90bzNPcHRpb25hbEludDMyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkyOAogICAgICAgICAgICAgIGNhc2UgOTM2OiB7CiAgICAgICAgICAgICAgICBwcm90bzNPcHRpb25hbEludDY0XyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkzNgogICAgICAgICAgICAgIGNhc2UgOTQ0OiB7CiAgICAgICAgICAgICAgICBwcm90bzNPcHRpb25hbFVpbnQzMl8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTQ0CiAgICAgICAgICAgICAgY2FzZSA5NTI6IHsKICAgICAgICAgICAgICAgIHByb3RvM09wdGlvbmFsVWludDY0XyA9IGlucHV0LnJlYWRVSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NTIKICAgICAgICAgICAgICBjYXNlIDk2MDogewogICAgICAgICAgICAgICAgcHJvdG8zT3B0aW9uYWxTaW50MzJfID0gaW5wdXQucmVhZFNJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk2MAogICAgICAgICAgICAgIGNhc2UgOTY4OiB7CiAgICAgICAgICAgICAgICBwcm90bzNPcHRpb25hbFNpbnQ2NF8gPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTY4CiAgICAgICAgICAgICAgY2FzZSA5ODE6IHsKICAgICAgICAgICAgICAgIHByb3RvM09wdGlvbmFsRml4ZWQzMl8gPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk4MQogICAgICAgICAgICAgIGNhc2UgOTg1OiB7CiAgICAgICAgICAgICAgICBwcm90bzNPcHRpb25hbEZpeGVkNjRfID0gaW5wdXQucmVhZEZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5ODUKICAgICAgICAgICAgICBjYXNlIDk5NzogewogICAgICAgICAgICAgICAgcHJvdG8zT3B0aW9uYWxTZml4ZWQzMl8gPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5OTcKICAgICAgICAgICAgICBjYXNlIDEwMDE6IHsKICAgICAgICAgICAgICAgIHByb3RvM09wdGlvbmFsU2ZpeGVkNjRfID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAwMQogICAgICAgICAgICAgIGNhc2UgMTAxMzogewogICAgICAgICAgICAgICAgcHJvdG8zT3B0aW9uYWxGbG9hdF8gPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA4MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDEzCiAgICAgICAgICAgICAgY2FzZSAxMDE3OiB7CiAgICAgICAgICAgICAgICBwcm90bzNPcHRpb25hbERvdWJsZV8gPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAxNwogICAgICAgICAgICAgIGNhc2UgMTAyNDogewogICAgICAgICAgICAgICAgcHJvdG8zT3B0aW9uYWxCb29sXyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAyNAogICAgICAgICAgICAgIGNhc2UgMTAzNDogewogICAgICAgICAgICAgICAgcHJvdG8zT3B0aW9uYWxTdHJpbmdfID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAzNAogICAgICAgICAgICAgIGNhc2UgMTA0MjogewogICAgICAgICAgICAgICAgcHJvdG8zT3B0aW9uYWxCeXRlc18gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDQyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9uZW9mRmllbGRfOwogICAgICBwdWJsaWMgT25lb2ZGaWVsZENhc2UKICAgICAgICAgIGdldE9uZW9mRmllbGRDYXNlKCkgewogICAgICAgIHJldHVybiBPbmVvZkZpZWxkQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZGaWVsZCgpIHsKICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQxXzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQyXzsKCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFNpbmd1bGFyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5pbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBTaW5ndWxhcgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+aW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFNpbmd1bGFyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5pbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9wdGlvbmFsSW50MzJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsSW50NjRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQ2NCBvcHRpb25hbF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb3B0aW9uYWxJbnQ2NF8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBvcHRpb25hbF91aW50MzIgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9wdGlvbmFsX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsVWludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsVWludDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9wdGlvbmFsX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsVWludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvcHRpb25hbFVpbnQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxVaW50NjRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50NjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsVWludDY0KCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFVpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVWludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxVaW50NjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9wdGlvbmFsVWludDY0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFNpbnQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFNpbnQzMigpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxTaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFNpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxTaW50MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTaW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9wdGlvbmFsU2ludDMyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFNpbnQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxTaW50NjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsU2ludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU2ludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbFNpbnQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQ2NCBvcHRpb25hbF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFNpbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb3B0aW9uYWxTaW50NjRfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsRml4ZWQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEZpeGVkMzIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsRml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxGaXhlZDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxGaXhlZDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvcHRpb25hbEZpeGVkMzJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsRml4ZWQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQ2NCBvcHRpb25hbF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxGaXhlZDY0KCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEZpeGVkNjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9wdGlvbmFsRml4ZWQ2NF8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZml4ZWQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZml4ZWQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFNmaXhlZDMyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFNmaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFNmaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTZml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxTZml4ZWQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTZml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb3B0aW9uYWxTZml4ZWQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxTZml4ZWQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsU2ZpeGVkNjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsU2ZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFNmaXhlZDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTZml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsU2ZpeGVkNjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFNmaXhlZDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvcHRpb25hbFNmaXhlZDY0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IG9wdGlvbmFsRmxvYXRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZsb2F0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0T3B0aW9uYWxGbG9hdCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxGbG9hdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEZsb2F0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsRmxvYXRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5mbG9hdCBvcHRpb25hbF9mbG9hdCA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEZsb2F0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvcHRpb25hbEZsb2F0XyA9IDBGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGRvdWJsZSBvcHRpb25hbERvdWJsZV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxEb3VibGUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0T3B0aW9uYWxEb3VibGUoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsRG91YmxlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbERvdWJsZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRG91YmxlKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbERvdWJsZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmRvdWJsZSBvcHRpb25hbF9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxEb3VibGUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9wdGlvbmFsRG91YmxlXyA9IDBEOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gb3B0aW9uYWxCb29sXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQm9vbC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0T3B0aW9uYWxCb29sKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEJvb2xfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxCb29sIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxCb29sKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxCb29sXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ym9vbCBvcHRpb25hbF9ib29sID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsQm9vbCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb3B0aW9uYWxCb29sXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gczsKICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9wdGlvbmFsU3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFN0cmluZygpIHsKICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbFN0cmluZygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgb3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvcHRpb25hbF9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlcy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEJ5dGVzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxCeXRlcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQnl0ZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbEJ5dGVzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxCeXRlcygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb3B0aW9uYWxCeXRlc18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbEJ5dGVzKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKAogICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbE5lc3RlZE1lc3NhZ2UocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfICE9IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25NZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxGb3JlaWduTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbEZvcmVpZ25NZXNzYWdlKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyAhPSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxGb3JlaWduTWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbXBvcnRNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxJbXBvcnRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsSW1wb3J0TWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGludCBnZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRFbnVtXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIG9wdGlvbmFsTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIG9wdGlvbmFsTmVzdGVkRW51bV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5mb3JOdW1iZXIob3B0aW9uYWxOZXN0ZWRFbnVtXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkRW51bShwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9wdGlvbmFsTmVzdGVkRW51bV8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbE5lc3RlZEVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9wdGlvbmFsTmVzdGVkRW51bV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEZvcmVpZ25FbnVtXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldE9wdGlvbmFsRm9yZWlnbkVudW1WYWx1ZSgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduRW51bV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxGb3JlaWduRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRm9yZWlnbkVudW1WYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICBvcHRpb25hbEZvcmVpZ25FbnVtXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRm9yZWlnbkVudW0uCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bSBnZXRPcHRpb25hbEZvcmVpZ25FbnVtKCkgewogICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25FbnVtIHJlc3VsdCA9IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25FbnVtLmZvck51bWJlcihvcHRpb25hbEZvcmVpZ25FbnVtXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEZvcmVpZ25FbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxGb3JlaWduRW51bShwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRm9yZWlnbkVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsU3RyaW5nUGllY2VfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nUGllY2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZ1BpZWNlKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdQaWVjZV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IHM7CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZ1BpZWNlLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdQaWVjZV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZ1BpZWNlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFN0cmluZ1BpZWNlKCkgewogICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZSgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZ1BpZWNlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTdHJpbmdQaWVjZUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxDb3JkXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQ29yZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsQ29yZCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsQ29yZF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBvcHRpb25hbENvcmRfID0gczsKICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxDb3JkLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0T3B0aW9uYWxDb3JkQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbENvcmRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBvcHRpb25hbENvcmRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxDb3JkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxDb3JkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxDb3JkXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxDb3JkKCkgewogICAgICAgIG9wdGlvbmFsQ29yZF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbENvcmQoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvcHRpb25hbENvcmQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbENvcmRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBvcHRpb25hbENvcmRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlXyA9PSBudWxsID8gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxMYXp5TWVzc2FnZShwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTGF6eU1lc3NhZ2UoCiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTGF6eU1lc3NhZ2UocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfICE9IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbExhenlNZXNzYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF91bnZlcmlmaWVkX2xhenlfbWVzc2FnZSA9IDI4IFt1bnZlcmlmaWVkX2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKAogICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfICE9IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF91bnZlcmlmaWVkX2xhenlfbWVzc2FnZSA9IDI4IFt1bnZlcmlmaWVkX2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9sYXp5X2ltcG9ydF9tZXNzYWdlID0gMTE1IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9sYXp5X2ltcG9ydF9tZXNzYWdlID0gMTE1IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2xhenlfaW1wb3J0X21lc3NhZ2UgPSAxMTUgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9pbXBvcnRfbWVzc2FnZSA9IDExNSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9sYXp5X2ltcG9ydF9tZXNzYWdlID0gMTE1IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2xhenlfaW1wb3J0X21lc3NhZ2UgPSAxMTUgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2xhenlfaW1wb3J0X21lc3NhZ2UgPSAxMTUgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9sYXp5X2ltcG9ydF9tZXNzYWdlID0gMTE1IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9pbXBvcnRfbWVzc2FnZSA9IDExNSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkSW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEludDMyKCkgewogICAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRJbnQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkSW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkSW50NjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkSW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRJbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRJbnQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRJbnQ2NCgpIHsKICAgICAgICByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFVpbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkVWludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFVpbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVWludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRVaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVWludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFVpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkVWludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRVaW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFVpbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFVpbnQzMigpIHsKICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkVWludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkVWludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkVWludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkVWludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFVpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFVpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkVWludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkVWludDY0KCkgewogICAgICAgIHJlcGVhdGVkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNpbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNpbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2ludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTaW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFNpbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNpbnQzMigpIHsKICAgICAgICByZXBlYXRlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHg0MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2ludDY0KCkgewogICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaXhlZDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGaXhlZDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRml4ZWQzMl8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRml4ZWQzMigpIHsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkNjRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRGaXhlZDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpeGVkNjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGaXhlZDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRml4ZWQ2NF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRml4ZWQ2NCgpIHsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQzMl8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNmaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTZml4ZWQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNmaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNmaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTZml4ZWQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTZml4ZWQzMigpIHsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDY0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRTZml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ZpeGVkNjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNmaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2ZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNmaXhlZDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFNmaXhlZDY0Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNmaXhlZDY0KCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRmxvYXRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRmxvYXRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRmxvYXRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGZsb2F0IGdldFJlcGVhdGVkRmxvYXQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZsb2F0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGbG9hdCgKICAgICAgICAgIGludCBpbmRleCwgZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfLnNldEZsb2F0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZsb2F0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkRmxvYXQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZsb2F0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRGbG9hdF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRGbG9hdCgpIHsKICAgICAgICByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWREb3VibGVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWREb3VibGVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRG91YmxlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRG91YmxlXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRG91YmxlLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZERvdWJsZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0UmVwZWF0ZWREb3VibGUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXy5nZXREb3VibGUoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWREb3VibGUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZERvdWJsZSgKICAgICAgICAgIGludCBpbmRleCwgZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfLnNldERvdWJsZShpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZERvdWJsZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRG91YmxlKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRG91YmxlXy5hZGREb3VibGUodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWREb3VibGUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZERvdWJsZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWREb3VibGVfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWREb3VibGUoKSB7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgcmVwZWF0ZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQm9vbF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkQm9vbF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRCb29sXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRCb29sXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEJvb2xfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2wuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRSZXBlYXRlZEJvb2xMaXN0KCkgewogICAgICAgIHJlcGVhdGVkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCb29sQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJvb2wgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gZ2V0UmVwZWF0ZWRCb29sKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJvb2wgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEJvb2woCiAgICAgICAgICBpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCb29sXy5zZXRCb29sZWFuKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRCb29sIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRCb29sKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCb29sXy5hZGRCb29sZWFuKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRCb29sIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRCb29sKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkQm9vbF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQm9vbCgpIHsKICAgICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTdHJpbmdfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZ18gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KHJlcGVhdGVkU3RyaW5nXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZ0NvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0J5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTdHJpbmcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFN0cmluZyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU3RyaW5nXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nKCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwODApOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gcmVwZWF0ZWRCeXRlc18gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEJ5dGVzXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRCeXRlc18gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRCeXRlc18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAxMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJ5dGVzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldFJlcGVhdGVkQnl0ZXNMaXN0KCkgewogICAgICAgIHJlcGVhdGVkQnl0ZXNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJ5dGVzLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJ5dGVzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJ5dGVzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc18uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJ5dGVzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRCeXRlcygKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEJ5dGVzSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCeXRlc18uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJ5dGVzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRCeXRlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJ5dGVzXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkQnl0ZXMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEJ5dGVzKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRCeXRlc18pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRCeXRlcygpIHsKICAgICAgICByZXBlYXRlZEJ5dGVzXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgcHJvdG8zT3B0aW9uYWxJbnQzMl8gOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogT3B0aW9uYWwKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHByb3RvM19vcHRpb25hbF9pbnQzMiA9IDExNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsSW50MzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBPcHRpb25hbAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgcHJvdG8zX29wdGlvbmFsX2ludDMyID0gMTE2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxJbnQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQcm90bzNPcHRpb25hbEludDMyKCkgewogICAgICAgIHJldHVybiBwcm90bzNPcHRpb25hbEludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogT3B0aW9uYWwKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHByb3RvM19vcHRpb25hbF9pbnQzMiA9IDExNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcHJvdG8zT3B0aW9uYWxJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFByb3RvM09wdGlvbmFsSW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIHByb3RvM09wdGlvbmFsSW50MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBPcHRpb25hbAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgcHJvdG8zX29wdGlvbmFsX2ludDMyID0gMTE2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQcm90bzNPcHRpb25hbEludDMyKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBwcm90bzNPcHRpb25hbEludDMyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBwcm90bzNPcHRpb25hbEludDY0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBwcm90bzNfb3B0aW9uYWxfaW50NjQgPSAxMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsSW50NjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcm90bzNPcHRpb25hbEludDY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgcHJvdG8zX29wdGlvbmFsX2ludDY0ID0gMTE3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxJbnQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0UHJvdG8zT3B0aW9uYWxJbnQ2NCgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IHByb3RvM19vcHRpb25hbF9pbnQ2NCA9IDExNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcHJvdG8zT3B0aW9uYWxJbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFByb3RvM09wdGlvbmFsSW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBwcm90bzNPcHRpb25hbEludDY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgcHJvdG8zX29wdGlvbmFsX2ludDY0ID0gMTE3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQcm90bzNPcHRpb25hbEludDY0KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBwcm90bzNPcHRpb25hbEludDY0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBwcm90bzNPcHRpb25hbFVpbnQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIHByb3RvM19vcHRpb25hbF91aW50MzIgPSAxMTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsVWludDMyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxVaW50MzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgcHJvdG8zX29wdGlvbmFsX3VpbnQzMiA9IDExODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsVWludDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFByb3RvM09wdGlvbmFsVWludDMyKCkgewogICAgICAgIHJldHVybiBwcm90bzNPcHRpb25hbFVpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBwcm90bzNfb3B0aW9uYWxfdWludDMyID0gMTE4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwcm90bzNPcHRpb25hbFVpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFByb3RvM09wdGlvbmFsVWludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBwcm90bzNPcHRpb25hbFVpbnQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBwcm90bzNfb3B0aW9uYWxfdWludDMyID0gMTE4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQcm90bzNPcHRpb25hbFVpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgcHJvdG8zT3B0aW9uYWxVaW50MzJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIHByb3RvM09wdGlvbmFsVWludDY0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgcHJvdG8zX29wdGlvbmFsX3VpbnQ2NCA9IDExOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxVaW50NjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcm90bzNPcHRpb25hbFVpbnQ2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBwcm90bzNfb3B0aW9uYWxfdWludDY0ID0gMTE5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxVaW50NjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldFByb3RvM09wdGlvbmFsVWludDY0KCkgewogICAgICAgIHJldHVybiBwcm90bzNPcHRpb25hbFVpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBwcm90bzNfb3B0aW9uYWxfdWludDY0ID0gMTE5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwcm90bzNPcHRpb25hbFVpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFByb3RvM09wdGlvbmFsVWludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgcHJvdG8zT3B0aW9uYWxVaW50NjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgcHJvdG8zX29wdGlvbmFsX3VpbnQ2NCA9IDExOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUHJvdG8zT3B0aW9uYWxVaW50NjQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDEwMDApOwogICAgICAgIHByb3RvM09wdGlvbmFsVWludDY0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBwcm90bzNPcHRpb25hbFNpbnQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIHByb3RvM19vcHRpb25hbF9zaW50MzIgPSAxMjA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsU2ludDMyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxTaW50MzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgcHJvdG8zX29wdGlvbmFsX3NpbnQzMiA9IDEyMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsU2ludDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFByb3RvM09wdGlvbmFsU2ludDMyKCkgewogICAgICAgIHJldHVybiBwcm90bzNPcHRpb25hbFNpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBwcm90bzNfb3B0aW9uYWxfc2ludDMyID0gMTIwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwcm90bzNPcHRpb25hbFNpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFByb3RvM09wdGlvbmFsU2ludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBwcm90bzNPcHRpb25hbFNpbnQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBwcm90bzNfb3B0aW9uYWxfc2ludDMyID0gMTIwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQcm90bzNPcHRpb25hbFNpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgcHJvdG8zT3B0aW9uYWxTaW50MzJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIHByb3RvM09wdGlvbmFsU2ludDY0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgcHJvdG8zX29wdGlvbmFsX3NpbnQ2NCA9IDEyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxTaW50NjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcm90bzNPcHRpb25hbFNpbnQ2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBwcm90bzNfb3B0aW9uYWxfc2ludDY0ID0gMTIxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxTaW50NjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldFByb3RvM09wdGlvbmFsU2ludDY0KCkgewogICAgICAgIHJldHVybiBwcm90bzNPcHRpb25hbFNpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBwcm90bzNfb3B0aW9uYWxfc2ludDY0ID0gMTIxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwcm90bzNPcHRpb25hbFNpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFByb3RvM09wdGlvbmFsU2ludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgcHJvdG8zT3B0aW9uYWxTaW50NjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgcHJvdG8zX29wdGlvbmFsX3NpbnQ2NCA9IDEyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUHJvdG8zT3B0aW9uYWxTaW50NjQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDQwMDApOwogICAgICAgIHByb3RvM09wdGlvbmFsU2ludDY0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBwcm90bzNPcHRpb25hbEZpeGVkMzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgcHJvdG8zX29wdGlvbmFsX2ZpeGVkMzIgPSAxMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsRml4ZWQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsRml4ZWQzMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgcHJvdG8zX29wdGlvbmFsX2ZpeGVkMzIgPSAxMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBwcm90bzNPcHRpb25hbEZpeGVkMzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0UHJvdG8zT3B0aW9uYWxGaXhlZDMyKCkgewogICAgICAgIHJldHVybiBwcm90bzNPcHRpb25hbEZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIHByb3RvM19vcHRpb25hbF9maXhlZDMyID0gMTIyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwcm90bzNPcHRpb25hbEZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQcm90bzNPcHRpb25hbEZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIHByb3RvM09wdGlvbmFsRml4ZWQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgcHJvdG8zX29wdGlvbmFsX2ZpeGVkMzIgPSAxMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclByb3RvM09wdGlvbmFsRml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgcHJvdG8zT3B0aW9uYWxGaXhlZDMyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBwcm90bzNPcHRpb25hbEZpeGVkNjRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgcHJvdG8zX29wdGlvbmFsX2ZpeGVkNjQgPSAxMjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsRml4ZWQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsRml4ZWQ2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgcHJvdG8zX29wdGlvbmFsX2ZpeGVkNjQgPSAxMjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBwcm90bzNPcHRpb25hbEZpeGVkNjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldFByb3RvM09wdGlvbmFsRml4ZWQ2NCgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxGaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBwcm90bzNfb3B0aW9uYWxfZml4ZWQ2NCA9IDEyMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcHJvdG8zT3B0aW9uYWxGaXhlZDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UHJvdG8zT3B0aW9uYWxGaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgcHJvdG8zT3B0aW9uYWxGaXhlZDY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBwcm90bzNfb3B0aW9uYWxfZml4ZWQ2NCA9IDEyMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUHJvdG8zT3B0aW9uYWxGaXhlZDY0KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBwcm90bzNPcHRpb25hbEZpeGVkNjRfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IHByb3RvM09wdGlvbmFsU2ZpeGVkMzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDMyIHByb3RvM19vcHRpb25hbF9zZml4ZWQzMiA9IDEyNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxTZml4ZWQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsU2ZpeGVkMzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBwcm90bzNfb3B0aW9uYWxfc2ZpeGVkMzIgPSAxMjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBwcm90bzNPcHRpb25hbFNmaXhlZDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFByb3RvM09wdGlvbmFsU2ZpeGVkMzIoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM09wdGlvbmFsU2ZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBwcm90bzNfb3B0aW9uYWxfc2ZpeGVkMzIgPSAxMjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHByb3RvM09wdGlvbmFsU2ZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQcm90bzNPcHRpb25hbFNmaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBwcm90bzNPcHRpb25hbFNmaXhlZDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgcHJvdG8zX29wdGlvbmFsX3NmaXhlZDMyID0gMTI0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQcm90bzNPcHRpb25hbFNmaXhlZDMyKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBwcm90bzNPcHRpb25hbFNmaXhlZDMyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBwcm90bzNPcHRpb25hbFNmaXhlZDY0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBwcm90bzNfb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHByb3RvM09wdGlvbmFsU2ZpeGVkNjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcm90bzNPcHRpb25hbFNmaXhlZDY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDQwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgcHJvdG8zX29wdGlvbmFsX3NmaXhlZDY0ID0gMTI1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxTZml4ZWQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0UHJvdG8zT3B0aW9uYWxTZml4ZWQ2NCgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxTZml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDY0IHByb3RvM19vcHRpb25hbF9zZml4ZWQ2NCA9IDEyNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcHJvdG8zT3B0aW9uYWxTZml4ZWQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFByb3RvM09wdGlvbmFsU2ZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBwcm90bzNPcHRpb25hbFNmaXhlZDY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgcHJvdG8zX29wdGlvbmFsX3NmaXhlZDY0ID0gMTI1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQcm90bzNPcHRpb25hbFNmaXhlZDY0KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBwcm90bzNPcHRpb25hbFNmaXhlZDY0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IHByb3RvM09wdGlvbmFsRmxvYXRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHByb3RvM19vcHRpb25hbF9mbG9hdCA9IDEyNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBwcm90bzNfb3B0aW9uYWxfZmxvYXQgPSAxMjY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBwcm90bzNPcHRpb25hbEZsb2F0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0UHJvdG8zT3B0aW9uYWxGbG9hdCgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxGbG9hdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHByb3RvM19vcHRpb25hbF9mbG9hdCA9IDEyNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcHJvdG8zT3B0aW9uYWxGbG9hdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFByb3RvM09wdGlvbmFsRmxvYXQoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgcHJvdG8zT3B0aW9uYWxGbG9hdF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHByb3RvM19vcHRpb25hbF9mbG9hdCA9IDEyNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUHJvdG8zT3B0aW9uYWxGbG9hdCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgcHJvdG8zT3B0aW9uYWxGbG9hdF8gPSAwRjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBkb3VibGUgcHJvdG8zT3B0aW9uYWxEb3VibGVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBwcm90bzNfb3B0aW9uYWxfZG91YmxlID0gMTI3OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbERvdWJsZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1Byb3RvM09wdGlvbmFsRG91YmxlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIHByb3RvM19vcHRpb25hbF9kb3VibGUgPSAxMjc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBwcm90bzNPcHRpb25hbERvdWJsZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRQcm90bzNPcHRpb25hbERvdWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxEb3VibGVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgcHJvdG8zX29wdGlvbmFsX2RvdWJsZSA9IDEyNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcHJvdG8zT3B0aW9uYWxEb3VibGUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQcm90bzNPcHRpb25hbERvdWJsZShkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgcHJvdG8zT3B0aW9uYWxEb3VibGVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgcHJvdG8zX29wdGlvbmFsX2RvdWJsZSA9IDEyNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUHJvdG8zT3B0aW9uYWxEb3VibGUoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAxMDAwMDApOwogICAgICAgIHByb3RvM09wdGlvbmFsRG91YmxlXyA9IDBEOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gcHJvdG8zT3B0aW9uYWxCb29sXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHByb3RvM19vcHRpb25hbF9ib29sID0gMTI4OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbEJvb2wgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcm90bzNPcHRpb25hbEJvb2woKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIHByb3RvM19vcHRpb25hbF9ib29sID0gMTI4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcHJvdG8zT3B0aW9uYWxCb29sLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRQcm90bzNPcHRpb25hbEJvb2woKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM09wdGlvbmFsQm9vbF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgcHJvdG8zX29wdGlvbmFsX2Jvb2wgPSAxMjg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHByb3RvM09wdGlvbmFsQm9vbCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFByb3RvM09wdGlvbmFsQm9vbChib29sZWFuIHZhbHVlKSB7CgogICAgICAgIHByb3RvM09wdGlvbmFsQm9vbF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgcHJvdG8zX29wdGlvbmFsX2Jvb2wgPSAxMjg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclByb3RvM09wdGlvbmFsQm9vbCgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgcHJvdG8zT3B0aW9uYWxCb29sXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgcHJvdG8zT3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcHJvdG8zX29wdGlvbmFsX3N0cmluZyA9IDEyOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJvdG8zT3B0aW9uYWxTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcHJvdG8zX29wdGlvbmFsX3N0cmluZyA9IDEyOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UHJvdG8zT3B0aW9uYWxTdHJpbmcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBwcm90bzNPcHRpb25hbFN0cmluZ187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBwcm90bzNPcHRpb25hbFN0cmluZ18gPSBzOwogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHByb3RvM19vcHRpb25hbF9zdHJpbmcgPSAxMjk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgcHJvdG8zT3B0aW9uYWxTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRQcm90bzNPcHRpb25hbFN0cmluZ0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gcHJvdG8zT3B0aW9uYWxTdHJpbmdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBwcm90bzNPcHRpb25hbFN0cmluZ18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcHJvdG8zX29wdGlvbmFsX3N0cmluZyA9IDEyOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcHJvdG8zT3B0aW9uYWxTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQcm90bzNPcHRpb25hbFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHByb3RvM09wdGlvbmFsU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHByb3RvM19vcHRpb25hbF9zdHJpbmcgPSAxMjk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclByb3RvM09wdGlvbmFsU3RyaW5nKCkgewogICAgICAgIHByb3RvM09wdGlvbmFsU3RyaW5nXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFByb3RvM09wdGlvbmFsU3RyaW5nKCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcHJvdG8zX29wdGlvbmFsX3N0cmluZyA9IDEyOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHByb3RvM09wdGlvbmFsU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UHJvdG8zT3B0aW9uYWxTdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBwcm90bzNPcHRpb25hbFN0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHByb3RvM09wdGlvbmFsQnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgcHJvdG8zX29wdGlvbmFsX2J5dGVzID0gMTMwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcm90bzNPcHRpb25hbEJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUHJvdG8zT3B0aW9uYWxCeXRlcygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIHByb3RvM19vcHRpb25hbF9ieXRlcyA9IDEzMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHByb3RvM09wdGlvbmFsQnl0ZXMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UHJvdG8zT3B0aW9uYWxCeXRlcygpIHsKICAgICAgICByZXR1cm4gcHJvdG8zT3B0aW9uYWxCeXRlc187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIHByb3RvM19vcHRpb25hbF9ieXRlcyA9IDEzMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcHJvdG8zT3B0aW9uYWxCeXRlcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFByb3RvM09wdGlvbmFsQnl0ZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBwcm90bzNPcHRpb25hbEJ5dGVzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgcHJvdG8zX29wdGlvbmFsX2J5dGVzID0gMTMwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQcm90bzNPcHRpb25hbEJ5dGVzKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBwcm90bzNPcHRpb25hbEJ5dGVzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFByb3RvM09wdGlvbmFsQnl0ZXMoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4ocmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZShwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDEwMDAwMDApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQxXyAmIDB4MDEwMDAwMDApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZT4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMV8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZT4ocmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8pOwogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAyMDAwMDAwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2U+IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDIwMDAwMDApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQxXyAmIDB4MDIwMDAwMDApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlPiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMV8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlPihyZXBlYXRlZEltcG9ydE1lc3NhZ2VfKTsKICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlPiBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDQwMDAwMDApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZEltcG9ydE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEltcG9ydE1lc3NhZ2VfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDFfICYgMHgwNDAwMDAwMCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZE5lc3RlZEVudW1fID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMV8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocmVwZWF0ZWROZXN0ZWRFbnVtXywgcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZE5lc3RlZEVudW0oCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkTmVzdGVkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkRW51bShwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE5lc3RlZEVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkTmVzdGVkRW51bSgpIHsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZSgKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAoaW50IHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZEZvcmVpZ25FbnVtXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQxXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZEZvcmVpZ25FbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGb3JlaWduRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bT4gZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0+KHJlcGVhdGVkRm9yZWlnbkVudW1fLCByZXBlYXRlZEZvcmVpZ25FbnVtX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGb3JlaWduRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25FbnVtXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGb3JlaWduRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0gZ2V0UmVwZWF0ZWRGb3JlaWduRW51bShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRGb3JlaWduRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGb3JlaWduRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRm9yZWlnbkVudW0oCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25FbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRm9yZWlnbkVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZvcmVpZ25FbnVtKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25FbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRm9yZWlnbkVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZvcmVpZ25FbnVtKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZvcmVpZ25FbnVtKCkgewogICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkRm9yZWlnbkVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFJlcGVhdGVkRm9yZWlnbkVudW1WYWx1ZUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkRm9yZWlnbkVudW1fKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkRm9yZWlnbkVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbkVudW1fLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZEZvcmVpZ25FbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGb3JlaWduRW51bVZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWRGb3JlaWduRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbkVudW1WYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkRm9yZWlnbkVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbkVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKGludCB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nUGllY2VfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZ1BpZWNlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KHJlcGVhdGVkU3RyaW5nUGllY2VfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDIwMDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nUGllY2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmdQaWVjZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nUGllY2UgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFN0cmluZ1BpZWNlKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nUGllY2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nUGllY2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdQaWVjZUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZ1BpZWNlXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmdQaWVjZSgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MjAwMDAwMDApOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmdQaWVjZUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRDb3JkXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZENvcmRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZENvcmRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZENvcmRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZENvcmRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDQwMDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRDb3JkLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZENvcmRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkQ29yZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZENvcmRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRDb3JkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZENvcmRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRDb3JkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkQ29yZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRDb3JkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkQ29yZEJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZENvcmRfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQ29yZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQ29yZCgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRDb3JkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRDb3JkXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQ29yZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQ29yZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQ29yZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQ29yZF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZENvcmQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZENvcmQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRDb3JkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkQ29yZF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRDb3JkKCkgewogICAgICAgIHJlcGVhdGVkQ29yZF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDQwMDAwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZENvcmQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZENvcmRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBlbnN1cmVSZXBlYXRlZENvcmRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZENvcmRfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiByZXBlYXRlZExhenlNZXNzYWdlXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQxXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPihyZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiBnZXRSZXBlYXRlZExhenlNZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTGF6eU1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRMYXp5TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRMYXp5TWVzc2FnZShwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZExhenlNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTGF6eU1lc3NhZ2UoCiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRMYXp5TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRMYXp5TWVzc2FnZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IHZhbHVlcykgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRMYXp5TWVzc2FnZV8pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRMYXp5TWVzc2FnZSgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4ODAwMDAwMDApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkTGF6eU1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZExhenlNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZV8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRMYXp5TWVzc2FnZV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDFfICYgMHg4MDAwMDAwMCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlVpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlVpbnQzMigpIHsKICAgICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDExMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9uZW9mVWludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRPbmVvZlVpbnQzMigpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMSkgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVvZlVpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mVWludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTE7CiAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDExMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZVaW50MzIoKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTEpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZk5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZk5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZk5lc3RlZE1lc3NhZ2UuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgICAgIHJldHVybiAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICAgICByZXR1cm4gb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZk5lc3RlZE1lc3NhZ2UocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZOZXN0ZWRNZXNzYWdlKAogICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTEyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT25lb2ZOZXN0ZWRNZXNzYWdlKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyICYmCiAgICAgICAgICAgICAgb25lb2ZGaWVsZF8gIT0gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF8pCiAgICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICAgICAgb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZk5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldE9uZW9mTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPbmVvZk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSAmJiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICAgIHJldHVybiBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgICAgIHJldHVybiAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIShvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSkgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgICAgfQogICAgICAgICAgb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlN0cmluZygpIHsKICAgICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExMzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9uZW9mU3RyaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPbmVvZlN0cmluZygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgICByZWYgPSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9uZW9mU3RyaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRPbmVvZlN0cmluZ0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVvZlN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTEzOwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mU3RyaW5nKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZlN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMzsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZCeXRlcygpIHsKICAgICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExNDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZkJ5dGVzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPbmVvZkJ5dGVzKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0KSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVvZkJ5dGVzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZCeXRlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExNDsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDExNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZCeXRlcygpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNCkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEFsbFR5cGVzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RBbGxUeXBlcz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RBbGxUeXBlcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RBbGxUeXBlcz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0QWxsVHlwZXM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RQYWNrZWRUeXBlc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkSW50MzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQzMi4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkSW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZEludDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50NjQuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRJbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRQYWNrZWRJbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkVWludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkVWludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRVaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRVaW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRVaW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFVpbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZFVpbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDY0LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkVWludDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRVaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFBhY2tlZFVpbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkU2ludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRTaW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRTaW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNpbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZFNpbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ludDY0LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2ludDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFBhY2tlZFNpbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGaXhlZDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkRml4ZWQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkRml4ZWQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRGaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEZpeGVkMzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRml4ZWQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZEZpeGVkNjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRml4ZWQ2NC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UGFja2VkRml4ZWQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNmaXhlZDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldFBhY2tlZFNmaXhlZDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2ZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2ZpeGVkMzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZml4ZWQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZFNmaXhlZDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ZpeGVkNjQuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRTZml4ZWQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNmaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRQYWNrZWRTZml4ZWQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGbG9hdC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PiBnZXRQYWNrZWRGbG9hdExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGbG9hdC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEZsb2F0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZmxvYXQgZ2V0UGFja2VkRmxvYXQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWREb3VibGUuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+IGdldFBhY2tlZERvdWJsZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZERvdWJsZS4KICAgICAqLwogICAgaW50IGdldFBhY2tlZERvdWJsZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZERvdWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGRvdWJsZSBnZXRQYWNrZWREb3VibGUoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEJvb2wuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPiBnZXRQYWNrZWRCb29sTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRCb29sLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkQm9vbENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0UGFja2VkQm9vbChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0+IGdldFBhY2tlZEVudW1MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEVudW0uCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRFbnVtQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0gZ2V0UGFja2VkRW51bShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciBwYWNrZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFBhY2tlZEVudW1WYWx1ZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHBhY2tlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkRW51bVZhbHVlKGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0UGFja2VkVHlwZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0UGFja2VkVHlwZXMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcykKICAgICAgVGVzdFBhY2tlZFR5cGVzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0UGFja2VkVHlwZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFBhY2tlZFR5cGVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFBhY2tlZFR5cGVzKCkgewogICAgICBwYWNrZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcGFja2VkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwYWNrZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHBhY2tlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHBhY2tlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcGFja2VkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcGFja2VkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcGFja2VkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHBhY2tlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHBhY2tlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHBhY2tlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcGFja2VkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgIHBhY2tlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RQYWNrZWRUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMuY2xhc3MsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQYWNrZWRUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfSU5UMzJfRklFTERfTlVNQkVSID0gOTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZEludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFBhY2tlZEludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9JTlQ2NF9GSUVMRF9OVU1CRVIgPSA5MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZEludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRQYWNrZWRJbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkSW50NjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRJbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9VSU5UMzJfRklFTERfTlVNQkVSID0gOTI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZFVpbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRVaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRQYWNrZWRVaW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkVWludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFVpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkVWludDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRVaW50MzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRVaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1VJTlQ2NF9GSUVMRF9OVU1CRVIgPSA5MzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFVpbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkVWludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UGFja2VkVWludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFVpbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZFVpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRVaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1NJTlQzMl9GSUVMRF9OVU1CRVIgPSA5NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkU2ludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFBhY2tlZFNpbnQzMkxpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTaW50MzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZFNpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfU0lOVDY0X0ZJRUxEX05VTUJFUiA9IDk1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkU2ludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRQYWNrZWRTaW50NjRMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkU2ludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ludDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkU2ludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UGFja2VkU2ludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkU2ludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZFNpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA5NjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkRml4ZWQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEZpeGVkMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRQYWNrZWRGaXhlZDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEZpeGVkMzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkRml4ZWQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRGaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDk3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkRml4ZWQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGaXhlZDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UGFja2VkRml4ZWQ2NExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRGaXhlZDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkNjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRGaXhlZDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkRml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRGaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9TRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA5ODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkU2ZpeGVkMzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNmaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkU2ZpeGVkMzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ZpeGVkMzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkU2ZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1NGSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDk5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkU2ZpeGVkNjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFBhY2tlZFNmaXhlZDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNmaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNmaXhlZDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZFNmaXhlZDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkU2ZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkU2ZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0ZMT0FUX0ZJRUxEX05VTUJFUiA9IDEwMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCBwYWNrZWRGbG9hdF8gPQogICAgICAgIGVtcHR5RmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZ2V0UGFja2VkRmxvYXRMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkRmxvYXRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEZsb2F0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZsb2F0Q291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRGbG9hdF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZmxvYXQgZ2V0UGFja2VkRmxvYXQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRGbG9hdF8uZ2V0RmxvYXQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkRmxvYXRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0RPVUJMRV9GSUVMRF9OVU1CRVIgPSAxMDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHBhY2tlZERvdWJsZV8gPQogICAgICAgIGVtcHR5RG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRG91YmxlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBnZXRQYWNrZWREb3VibGVMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkRG91YmxlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZERvdWJsZS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWREb3VibGVDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZERvdWJsZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZG91YmxlIGdldFBhY2tlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZERvdWJsZV8uZ2V0RG91YmxlKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZERvdWJsZU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfQk9PTF9GSUVMRF9OVU1CRVIgPSAxMDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCBwYWNrZWRCb29sXyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRCb29sLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZ2V0UGFja2VkQm9vbExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRCb29sXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkQm9vbC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRCb29sQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRCb29sXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdldFBhY2tlZEJvb2woaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRCb29sXy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0VOVU1fRklFTERfTlVNQkVSID0gMTAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrZWRFbnVtXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bT4gcGFja2VkRW51bV9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25FbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bSByZXN1bHQgPSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0+IGdldFBhY2tlZEVudW1MaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0+KHBhY2tlZEVudW1fLCBwYWNrZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEVudW1fLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25FbnVtIGdldFBhY2tlZEVudW0oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRFbnVtX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcGFja2VkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UGFja2VkRW51bVZhbHVlTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEVudW1fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcGFja2VkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRW51bVZhbHVlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkRW51bV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgaWYgKGdldFBhY2tlZEludDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3MjIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMk5vVGFnKHBhY2tlZEludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRJbnQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzMwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRJbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkSW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjROb1RhZyhwYWNrZWRJbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFVpbnQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzM4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRVaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFVpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFVpbnQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzQ2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRVaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50NjROb1RhZyhwYWNrZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTaW50MzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDc1NCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2ludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyTm9UYWcocGFja2VkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTaW50NjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDc2Mik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2ludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRTaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0Tm9UYWcocGFja2VkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkRml4ZWQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzcwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRGaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRGaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzJOb1RhZyhwYWNrZWRGaXhlZDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRGaXhlZDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3NzgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEZpeGVkNjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NE5vVGFnKHBhY2tlZEZpeGVkNjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTZml4ZWQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzg2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRTZml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2ZpeGVkMzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzJOb1RhZyhwYWNrZWRTZml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2ZpeGVkNjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDc5NCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2ZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNmaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0Tm9UYWcocGFja2VkU2ZpeGVkNjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRGbG9hdExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoODAyKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRGbG9hdE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkRmxvYXRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXROb1RhZyhwYWNrZWRGbG9hdF8uZ2V0RmxvYXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWREb3VibGVMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDgxMCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkRG91YmxlTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWREb3VibGVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlTm9UYWcocGFja2VkRG91YmxlXy5nZXREb3VibGUoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRCb29sTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MTgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEJvb2xfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbE5vVGFnKHBhY2tlZEJvb2xfLmdldEJvb2xlYW4oaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRFbnVtTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MjYpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bU5vVGFnKHBhY2tlZEVudW1fLmdldChpKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkSW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcocGFja2VkSW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRJbnQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZU5vVGFnKHBhY2tlZEludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkVWludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhwYWNrZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRVaW50MzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkVWludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhwYWNrZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkVWludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZFVpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50MzJTaXplTm9UYWcocGFja2VkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkU2ludDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZFNpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50NjRTaXplTm9UYWcocGFja2VkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZFNpbnQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRTaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UGFja2VkRml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEZpeGVkMzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkRml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRQYWNrZWRGaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkRml4ZWQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRGaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFBhY2tlZFNmaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkU2ZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UGFja2VkU2ZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRTZml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRQYWNrZWRGbG9hdExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEZsb2F0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEZsb2F0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFBhY2tlZERvdWJsZUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZERvdWJsZUxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWREb3VibGVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSAxICogZ2V0UGFja2VkQm9vbExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEJvb2xMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkQm9vbE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhwYWNrZWRFbnVtXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkRW51bUxpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfXBhY2tlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBhY2tlZFR5cGVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMgb3RoZXIgPSAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBhY2tlZFR5cGVzKSBvYmo7CgogICAgICBpZiAoIWdldFBhY2tlZEludDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEludDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEludDY0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZFVpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRVaW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkVWludDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZFVpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRTaW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkU2ludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZFNpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRTaW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkRml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRGaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkRml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRTZml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRTZml4ZWQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRTZml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRGbG9hdExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRGbG9hdExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWREb3VibGVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkRG91YmxlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEJvb2xMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkQm9vbExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFwYWNrZWRFbnVtXy5lcXVhbHMob3RoZXIucGFja2VkRW51bV8pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGdldFBhY2tlZEludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFVpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkVWludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFVpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkVWludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkU2ludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkU2ludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEZpeGVkMzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9GSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRGaXhlZDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEZpeGVkNjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRGaXhlZDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNmaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfU0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZFNmaXhlZDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNmaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfU0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZFNmaXhlZDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEZsb2F0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEZsb2F0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZERvdWJsZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkRG91YmxlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEJvb2xDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9CT09MX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRCb29sTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEVudW1Db3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBwYWNrZWRFbnVtXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQYWNrZWRUeXBlcyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQYWNrZWRUeXBlcyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcykKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBhY2tlZFR5cGVzLmNsYXNzLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHBhY2tlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHBhY2tlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBwYWNrZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcGFja2VkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBwYWNrZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcGFja2VkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBwYWNrZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHBhY2tlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHBhY2tlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHBhY2tlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBwYWNrZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIHBhY2tlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBwYWNrZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBwYWNrZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQYWNrZWRUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQYWNrZWRUeXBlcyBidWlsZCgpIHsKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQYWNrZWRUeXBlcyByZXN1bHQgPSBuZXcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBhY2tlZFR5cGVzKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQYWNrZWRUeXBlcyByZXN1bHQpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocGFja2VkRW51bV8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQucGFja2VkRW51bV8gPSBwYWNrZWRFbnVtXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBhY2tlZFR5cGVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZEludDMyXyA9IHBhY2tlZEludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkSW50NjRfID0gcGFja2VkSW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcGFja2VkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkVWludDMyXyA9IHBhY2tlZFVpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRVaW50NjRfID0gcGFja2VkVWludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZFNpbnQzMl8gPSBwYWNrZWRTaW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkU2ludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkU2ludDY0XyA9IHBhY2tlZFNpbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkRml4ZWQzMl8gPSBwYWNrZWRGaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRGaXhlZDY0XyA9IHBhY2tlZEZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRTZml4ZWQzMl8gPSBwYWNrZWRTZml4ZWQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZFNmaXhlZDY0XyA9IHBhY2tlZFNmaXhlZDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkRmxvYXRfID0gcGFja2VkRmxvYXRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkRG91YmxlXyA9IHBhY2tlZERvdWJsZV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkQm9vbF8gPSBwYWNrZWRCb29sXzsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQYWNrZWRUeXBlcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRJbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEludDMyXyA9IG90aGVyLnBhY2tlZEludDMyXzsKICAgICAgICAgICAgcGFja2VkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkSW50MzJfLmFkZEFsbChvdGhlci5wYWNrZWRJbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkSW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkSW50NjRfID0gb3RoZXIucGFja2VkSW50NjRfOwogICAgICAgICAgICBwYWNrZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRJbnQ2NF8uYWRkQWxsKG90aGVyLnBhY2tlZEludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRVaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFVpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZFVpbnQzMl8gPSBvdGhlci5wYWNrZWRVaW50MzJfOwogICAgICAgICAgICBwYWNrZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFVpbnQzMl8uYWRkQWxsKG90aGVyLnBhY2tlZFVpbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkVWludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRVaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRVaW50NjRfID0gb3RoZXIucGFja2VkVWludDY0XzsKICAgICAgICAgICAgcGFja2VkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRVaW50NjRfLmFkZEFsbChvdGhlci5wYWNrZWRVaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZFNpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkU2ludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkU2ludDMyXyA9IG90aGVyLnBhY2tlZFNpbnQzMl87CiAgICAgICAgICAgIHBhY2tlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkU2ludDMyXy5hZGRBbGwob3RoZXIucGFja2VkU2ludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRTaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFNpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZFNpbnQ2NF8gPSBvdGhlci5wYWNrZWRTaW50NjRfOwogICAgICAgICAgICBwYWNrZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFNpbnQ2NF8uYWRkQWxsKG90aGVyLnBhY2tlZFNpbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEZpeGVkMzJfID0gb3RoZXIucGFja2VkRml4ZWQzMl87CiAgICAgICAgICAgIHBhY2tlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRGaXhlZDMyXy5hZGRBbGwob3RoZXIucGFja2VkRml4ZWQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEZpeGVkNjRfID0gb3RoZXIucGFja2VkRml4ZWQ2NF87CiAgICAgICAgICAgIHBhY2tlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRGaXhlZDY0Xy5hZGRBbGwob3RoZXIucGFja2VkRml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkU2ZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFNmaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkU2ZpeGVkMzJfID0gb3RoZXIucGFja2VkU2ZpeGVkMzJfOwogICAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8uYWRkQWxsKG90aGVyLnBhY2tlZFNmaXhlZDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkU2ZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRTZml4ZWQ2NF8gPSBvdGhlci5wYWNrZWRTZml4ZWQ2NF87CiAgICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5hZGRBbGwob3RoZXIucGFja2VkU2ZpeGVkNjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEZsb2F0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEZsb2F0XyA9IG90aGVyLnBhY2tlZEZsb2F0XzsKICAgICAgICAgICAgcGFja2VkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkRmxvYXRfLmFkZEFsbChvdGhlci5wYWNrZWRGbG9hdF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkRG91YmxlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWREb3VibGVfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWREb3VibGVfID0gb3RoZXIucGFja2VkRG91YmxlXzsKICAgICAgICAgICAgcGFja2VkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWREb3VibGVfLmFkZEFsbChvdGhlci5wYWNrZWREb3VibGVfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRCb29sXyA9IG90aGVyLnBhY2tlZEJvb2xfOwogICAgICAgICAgICBwYWNrZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkQm9vbF8uYWRkQWxsKG90aGVyLnBhY2tlZEJvb2xfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRFbnVtXyA9IG90aGVyLnBhY2tlZEVudW1fOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEVudW1fLmFkZEFsbChvdGhlci5wYWNrZWRFbnVtXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA3MjA6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkSW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MjAKICAgICAgICAgICAgICBjYXNlIDcyMjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRJbnQzMl8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MjIKICAgICAgICAgICAgICBjYXNlIDcyODogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkSW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzI4CiAgICAgICAgICAgICAgY2FzZSA3MzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkSW50NjRfLmFkZExvbmcoaW5wdXQucmVhZEludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDczMAogICAgICAgICAgICAgIGNhc2UgNzM2OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkVWludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzM2CiAgICAgICAgICAgICAgY2FzZSA3Mzg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZFVpbnQzMl8uYWRkSW50KGlucHV0LnJlYWRVSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzM4CiAgICAgICAgICAgICAgY2FzZSA3NDQ6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRVSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkVWludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0NAogICAgICAgICAgICAgIGNhc2UgNzQ2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRVaW50NjRfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NDYKICAgICAgICAgICAgICBjYXNlIDc1MjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZFNpbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc1MgogICAgICAgICAgICAgIGNhc2UgNzU0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRTaW50MzJfLmFkZEludChpbnB1dC5yZWFkU0ludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc1NAogICAgICAgICAgICAgIGNhc2UgNzYwOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZFNpbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NjAKICAgICAgICAgICAgICBjYXNlIDc2MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkU2ludDY0Xy5hZGRMb25nKGlucHV0LnJlYWRTSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzYyCiAgICAgICAgICAgICAgY2FzZSA3NzM6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZEZpeGVkMzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzMKICAgICAgICAgICAgICBjYXNlIDc3MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkMzJJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkRml4ZWQzMl8uYWRkSW50KGlucHV0LnJlYWRGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc3MAogICAgICAgICAgICAgIGNhc2UgNzc3OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkRml4ZWQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzcKICAgICAgICAgICAgICBjYXNlIDc3ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkRml4ZWQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzgKICAgICAgICAgICAgICBjYXNlIDc4OTogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc4OQogICAgICAgICAgICAgIGNhc2UgNzg2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkMzJJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkU2ZpeGVkMzJfLmFkZEludChpbnB1dC5yZWFkU0ZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzg2CiAgICAgICAgICAgICAgY2FzZSA3OTM6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc5MwogICAgICAgICAgICAgIGNhc2UgNzk0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkU2ZpeGVkNjRfLmFkZExvbmcoaW5wdXQucmVhZFNGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc5NAogICAgICAgICAgICAgIGNhc2UgODA1OiB7CiAgICAgICAgICAgICAgICBmbG9hdCB2ID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkRmxvYXRfLmFkZEZsb2F0KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwNQogICAgICAgICAgICAgIGNhc2UgODAyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkRmxvYXRfLmFkZEZsb2F0KGlucHV0LnJlYWRGbG9hdCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDIKICAgICAgICAgICAgICBjYXNlIDgwOTogewogICAgICAgICAgICAgICAgZG91YmxlIHYgPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZERvdWJsZV8uYWRkRG91YmxlKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwOQogICAgICAgICAgICAgIGNhc2UgODEwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZERvdWJsZV8uYWRkRG91YmxlKGlucHV0LnJlYWREb3VibGUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODEwCiAgICAgICAgICAgICAgY2FzZSA4MTY6IHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdiA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRCb29sXy5hZGRCb29sZWFuKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxNgogICAgICAgICAgICAgIGNhc2UgODE4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkQm9vbElzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRCb29sXy5hZGRCb29sZWFuKGlucHV0LnJlYWRCb29sKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxOAogICAgICAgICAgICAgIGNhc2UgODI0OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgyNAogICAgICAgICAgICAgIGNhc2UgODI2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBwYWNrZWRFbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MjYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkSW50MzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRQYWNrZWRJbnQzMkxpc3QoKSB7CiAgICAgICAgcGFja2VkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkSW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkSW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRJbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkSW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRJbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEludDMyKCkgewogICAgICAgIHBhY2tlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkSW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRJbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkSW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFBhY2tlZEludDY0TGlzdCgpIHsKICAgICAgICBwYWNrZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRJbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UGFja2VkSW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkSW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRJbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRJbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRJbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRJbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkSW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkSW50NjQoKSB7CiAgICAgICAgcGFja2VkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkVWludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkVWludDMyXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRVaW50MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFBhY2tlZFVpbnQzMkxpc3QoKSB7CiAgICAgICAgcGFja2VkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZFVpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkVWludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFVpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkVWludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRVaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRVaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRVaW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFVpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFVpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkVWludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRVaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRVaW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkVWludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkVWludDMyKCkgewogICAgICAgIHBhY2tlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBwYWNrZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkVWludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkVWludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkVWludDY0XyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRVaW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFBhY2tlZFVpbnQ2NExpc3QoKSB7CiAgICAgICAgcGFja2VkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkVWludDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRVaW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFVpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZFVpbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRVaW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRVaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRVaW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRVaW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkVWludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkVWludDY0KCkgewogICAgICAgIHBhY2tlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRTaW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTaW50MzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFNpbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UGFja2VkU2ludDMyTGlzdCgpIHsKICAgICAgICBwYWNrZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkU2ludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZFNpbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNpbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkU2ludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTaW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZFNpbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRTaW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRTaW50MzIoKSB7CiAgICAgICAgcGFja2VkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRTaW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRTaW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFNpbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UGFja2VkU2ludDY0TGlzdCgpIHsKICAgICAgICBwYWNrZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkU2ludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRTaW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZFNpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkU2ludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNpbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNpbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZFNpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRTaW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRTaW50NjQoKSB7CiAgICAgICAgcGFja2VkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEZpeGVkMzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRQYWNrZWRGaXhlZDMyTGlzdCgpIHsKICAgICAgICBwYWNrZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRml4ZWQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRGaXhlZDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEZpeGVkMzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRml4ZWQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRGaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkRml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEZpeGVkMzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkRml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEZpeGVkMzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEZpeGVkMzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEZpeGVkMzIoKSB7CiAgICAgICAgcGFja2VkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBwYWNrZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRml4ZWQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRml4ZWQ2NF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFBhY2tlZEZpeGVkNjRMaXN0KCkgewogICAgICAgIHBhY2tlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkRml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRGaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkNjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZEZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRGaXhlZDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRGaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkRml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRGaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkRml4ZWQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkRml4ZWQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkRml4ZWQ2NCgpIHsKICAgICAgICBwYWNrZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkU2ZpeGVkMzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRTZml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZFNmaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRTZml4ZWQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkU2ZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkU2ZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRQYWNrZWRTZml4ZWQzMkxpc3QoKSB7CiAgICAgICAgcGFja2VkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkU2ZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ZpeGVkMzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRTZml4ZWQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2ZpeGVkMzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRTZml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNmaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNmaXhlZDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkU2ZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRTZml4ZWQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZFNmaXhlZDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZFNmaXhlZDMyKCkgewogICAgICAgIHBhY2tlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTZml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkU2ZpeGVkNjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXBhY2tlZFNmaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkU2ZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFNmaXhlZDY0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNmaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UGFja2VkU2ZpeGVkNjRMaXN0KCkgewogICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNmaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRTZml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRTZml4ZWQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNmaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkU2ZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNmaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkU2ZpeGVkNjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRTZml4ZWQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRTZml4ZWQ2NCgpIHsKICAgICAgICBwYWNrZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IHBhY2tlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEZsb2F0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEZsb2F0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEZsb2F0XyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRGbG9hdF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0UGFja2VkRmxvYXRMaXN0KCkgewogICAgICAgIHBhY2tlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZsb2F0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEZsb2F0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRGbG9hdENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRGbG9hdF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRQYWNrZWRGbG9hdChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRmxvYXRfLmdldEZsb2F0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRGbG9hdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEZsb2F0KAogICAgICAgICAgaW50IGluZGV4LCBmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEZsb2F0Xy5zZXRGbG9hdChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEZsb2F0Xy5hZGRGbG9hdCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRGbG9hdCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRGbG9hdF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkRmxvYXQoKSB7CiAgICAgICAgcGFja2VkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHBhY2tlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZERvdWJsZV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZERvdWJsZV8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRG91YmxlXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkRG91YmxlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRG91YmxlXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWREb3VibGVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRG91YmxlLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRQYWNrZWREb3VibGVMaXN0KCkgewogICAgICAgIHBhY2tlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWREb3VibGVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWREb3VibGUuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZERvdWJsZUNvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWREb3VibGVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZERvdWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZG91YmxlIGdldFBhY2tlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRG91YmxlXy5nZXREb3VibGUoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRG91YmxlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkRG91YmxlKAogICAgICAgICAgaW50IGluZGV4LCBkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRG91YmxlXy5zZXREb3VibGUoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRG91YmxlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkRG91YmxlKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICBwYWNrZWREb3VibGVfLmFkZERvdWJsZSh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWREb3VibGUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWREb3VibGUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWREb3VibGVfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkRG91YmxlKCkgewogICAgICAgIHBhY2tlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCBwYWNrZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkQm9vbF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkQm9vbF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkQm9vbF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkQm9vbF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEJvb2wuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRQYWNrZWRCb29sTGlzdCgpIHsKICAgICAgICBwYWNrZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEJvb2xfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEJvb2wuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEJvb2xDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkQm9vbF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGdldFBhY2tlZEJvb2woaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEJvb2xfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRCb29sIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkQm9vbCgKICAgICAgICAgIGludCBpbmRleCwgYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkQm9vbF8uc2V0Qm9vbGVhbihpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEJvb2wgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRCb29sKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkQm9vbElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEJvb2xfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRCb29sIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkQm9vbCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkQm9vbF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEJvb2woKSB7CiAgICAgICAgcGFja2VkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrZWRFbnVtXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRFbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihwYWNrZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0+IGdldFBhY2tlZEVudW1MaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25FbnVtPihwYWNrZWRFbnVtXywgcGFja2VkRW51bV9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRFbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0gZ2V0UGFja2VkRW51bShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocGFja2VkRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRFbnVtKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEVudW1fLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEVudW0ocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBwYWNrZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRFbnVtKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduRW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbkVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHBhY2tlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkRW51bSgpIHsKICAgICAgICBwYWNrZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcGFja2VkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0UGFja2VkRW51bVZhbHVlTGlzdCgpIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocGFja2VkRW51bV8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHBhY2tlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRFbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEVudW1fLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgcGFja2VkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEVudW1WYWx1ZSgKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CiAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEVudW1fLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBwYWNrZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkRW51bVZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBwYWNrZWRFbnVtXy5hZGQodmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHBhY2tlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRFbnVtVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKGludCB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcGFja2VkRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQYWNrZWRUeXBlcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQYWNrZWRUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQYWNrZWRUeXBlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0UGFja2VkVHlwZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UGFja2VkVHlwZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UGFja2VkVHlwZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFBhY2tlZFR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGFja2VkVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0VW5wYWNrZWRUeXBlc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdFVucGFja2VkVHlwZXMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRJbnQzMihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFJlcGVhdGVkSW50NjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50NjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRSZXBlYXRlZEludDY0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFVpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFVpbnQzMihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFJlcGVhdGVkVWludDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDY0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRVaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkVWludDY0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNpbnQzMihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFJlcGVhdGVkU2ludDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDY0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkU2ludDY0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGaXhlZDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRml4ZWQzMihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UmVwZWF0ZWRGaXhlZDY0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNmaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRSZXBlYXRlZFNmaXhlZDY0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGbG9hdC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PiBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGbG9hdC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRmxvYXRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZmxvYXQgZ2V0UmVwZWF0ZWRGbG9hdChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWREb3VibGUuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+IGdldFJlcGVhdGVkRG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZERvdWJsZS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRG91YmxlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZERvdWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGRvdWJsZSBnZXRSZXBlYXRlZERvdWJsZShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2wuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPiBnZXRSZXBlYXRlZEJvb2xMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCb29sLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRCb29sQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0UmVwZWF0ZWRCb29sKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIEV4cGxpY2l0bHkgc2V0IHBhY2tlZCB0byBmYWxzZQogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZFR5cGVzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFVucGFja2VkVHlwZXMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZFR5cGVzKQogICAgICBUZXN0VW5wYWNrZWRUeXBlc09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFVucGFja2VkVHlwZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFVucGFja2VkVHlwZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0VW5wYWNrZWRUeXBlcygpIHsKICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcmVwZWF0ZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgIHJlcGVhdGVkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFVucGFja2VkVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzLmNsYXNzLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZEludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTlQ2NF9GSUVMRF9OVU1CRVIgPSAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRJbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkSW50NjRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkVWludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50MzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9VSU5UNjRfRklFTERfTlVNQkVSID0gNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkVWludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRVaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFVpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TSU5UMzJfRklFTERfTlVNQkVSID0gNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTaW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkU2ludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NJTlQ2NF9GSUVMRF9OVU1CRVIgPSA2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRTaW50NjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSA2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSA2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSA2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0ZJWEVEMzJfRklFTERfTlVNQkVSID0gNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRGaXhlZDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEZpeGVkNjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NGSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkU2ZpeGVkMzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkMzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NGSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRTZml4ZWQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDY0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFNmaXhlZDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRkxPQVRfRklFTERfTlVNQkVSID0gMTE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5GbG9hdExpc3QgcmVwZWF0ZWRGbG9hdF8gPQogICAgICAgIGVtcHR5RmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZsb2F0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZsb2F0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRmxvYXRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGbG9hdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBmbG9hdCBnZXRSZXBlYXRlZEZsb2F0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uZ2V0RmxvYXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0RPVUJMRV9GSUVMRF9OVU1CRVIgPSAxMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkRvdWJsZUxpc3QgcmVwZWF0ZWREb3VibGVfID0KICAgICAgICBlbXB0eURvdWJsZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWREb3VibGUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPgogICAgICAgIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWREb3VibGUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAxMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZG91YmxlIGdldFJlcGVhdGVkRG91YmxlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLmdldERvdWJsZShpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQk9PTF9GSUVMRF9OVU1CRVIgPSAxMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHJlcGVhdGVkQm9vbF8gPQogICAgICAgIGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2wuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBnZXRSZXBlYXRlZEJvb2xMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJvb2wuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCb29sQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdldFJlcGVhdGVkQm9vbChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSID0gMTQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkTmVzdGVkRW51bV87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPihyZXBlYXRlZE5lc3RlZEVudW1fLCByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRSZXBlYXRlZE5lc3RlZEVudW0oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgcmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMiwgcmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoMywgcmVwZWF0ZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50NjQoNCwgcmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyKDUsIHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0KDYsIHJlcGVhdGVkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRml4ZWQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDMyKDcsIHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRml4ZWQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0KDgsIHJlcGVhdGVkRml4ZWQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNmaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyKDksIHJlcGVhdGVkU2ZpeGVkMzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNmaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0KDEwLCByZXBlYXRlZFNmaXhlZDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRmxvYXRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMTEsIHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRG91YmxlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgxMiwgcmVwZWF0ZWREb3VibGVfLmdldERvdWJsZShpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEJvb2xfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgxMywgcmVwZWF0ZWRCb29sXy5nZXRCb29sZWFuKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDE0LCByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhyZXBlYXRlZEludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkSW50MzJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZEludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZEludDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhyZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplTm9UYWcocmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkVWludDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemVOb1RhZyhyZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50NjRTaXplTm9UYWcocmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU2ludDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSAxICogZ2V0UmVwZWF0ZWRCb29sTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkQm9vbExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFVucGFja2VkVHlwZXMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzIG90aGVyID0gKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzKSBvYmo7CgogICAgICBpZiAoIWdldFJlcGVhdGVkSW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkSW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEZsb2F0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkRG91YmxlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRG91YmxlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkQm9vbExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEJvb2xMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghcmVwZWF0ZWROZXN0ZWRFbnVtXy5lcXVhbHMob3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRCb29sQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9CT09MX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEJvb2xMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcmVwZWF0ZWROZXN0ZWRFbnVtXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBFeHBsaWNpdGx5IHNldCBwYWNrZWQgdG8gZmFsc2UKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdFVucGFja2VkVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFVucGFja2VkVHlwZXMuY2xhc3MsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFVucGFja2VkVHlwZXMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlcyBidWlsZCgpIHsKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlcyByZXN1bHQgPSBuZXcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFVucGFja2VkVHlwZXModGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFVucGFja2VkVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5yZXBlYXRlZE5lc3RlZEVudW1fID0gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFVucGFja2VkVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEludDMyXyA9IHJlcGVhdGVkSW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW50NjRfID0gcmVwZWF0ZWRJbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkVWludDMyXyA9IHJlcGVhdGVkVWludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRVaW50NjRfID0gcmVwZWF0ZWRVaW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNpbnQzMl8gPSByZXBlYXRlZFNpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2ludDY0XyA9IHJlcGVhdGVkU2ludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRml4ZWQzMl8gPSByZXBlYXRlZEZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRGaXhlZDY0XyA9IHJlcGVhdGVkRml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTZml4ZWQzMl8gPSByZXBlYXRlZFNmaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNmaXhlZDY0XyA9IHJlcGVhdGVkU2ZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRmxvYXRfID0gcmVwZWF0ZWRGbG9hdF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRG91YmxlXyA9IHJlcGVhdGVkRG91YmxlXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQm9vbF8gPSByZXBlYXRlZEJvb2xfOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBvdGhlci5yZXBlYXRlZEludDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZEludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBvdGhlci5yZXBlYXRlZEludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFVpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRVaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBvdGhlci5yZXBlYXRlZFVpbnQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRVaW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkVWludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFVpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDY0XyA9IG90aGVyLnJlcGVhdGVkVWludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFVpbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gb3RoZXIucmVwZWF0ZWRTaW50MzJfOwogICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8gPSBvdGhlci5yZXBlYXRlZFNpbnQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IG90aGVyLnJlcGVhdGVkRml4ZWQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGaXhlZDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBvdGhlci5yZXBlYXRlZEZpeGVkNjRfOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTZml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTZml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gb3RoZXIucmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gb3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gb3RoZXIucmVwZWF0ZWRGbG9hdF87CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGbG9hdF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWREb3VibGVfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRG91YmxlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gb3RoZXIucmVwZWF0ZWREb3VibGVfOwogICAgICAgICAgICByZXBlYXRlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRG91YmxlXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkQm9vbF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8gPSBvdGhlci5yZXBlYXRlZEJvb2xfOwogICAgICAgICAgICByZXBlYXRlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkQm9vbF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gb3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+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+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRCb29sKCkgewogICAgICAgIHJlcGVhdGVkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZE5lc3RlZEVudW1fID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPihyZXBlYXRlZE5lc3RlZEVudW1fLCByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1Db3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkRW51bSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZEVudW0ocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE5lc3RlZEVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWROZXN0ZWRFbnVtKCkgewogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAoaW50IHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZFR5cGVzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFVucGFja2VkVHlwZXMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFVucGFja2VkVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RVbnBhY2tlZFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFVucGFja2VkVHlwZXM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFVucGFja2VkVHlwZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0VW5wYWNrZWRUeXBlcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbnBhY2tlZFR5cGVzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbnBhY2tlZFR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0VW5wYWNrZWRUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIE5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2hpbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0NoaWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZC4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIGdldENoaWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRDaGlsZE9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXlsb2FkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNQYXlsb2FkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHBheWxvYWQuCiAgICAgKi8KICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyBnZXRQYXlsb2FkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFBheWxvYWRPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcz4gCiAgICAgICAgZ2V0UmVwZWF0ZWRDaGlsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQ2hpbGQoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQ2hpbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZENoaWxkT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRDaGlsZE9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMgbGF6eV9wYXlsb2FkID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbGF6eVBheWxvYWQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xhenlQYXlsb2FkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGxhenlfcGF5bG9hZCA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsYXp5UGF5bG9hZC4KICAgICAqLwogICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIGdldExhenlQYXlsb2FkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGxhenlfcGF5bG9hZCA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRMYXp5UGF5bG9hZE9yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRoaXMgcHJvdG8gaW5jbHVkZXMgYSByZWN1cnNpdmVseSBuZXN0ZWQgbWVzc2FnZS4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBOZXN0ZWRUZXN0QWxsVHlwZXMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcykKICAgICAgTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBOZXN0ZWRUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgTmVzdGVkVGVzdEFsbFR5cGVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgTmVzdGVkVGVzdEFsbFR5cGVzKCkgewogICAgICByZXBlYXRlZENoaWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBOZXN0ZWRUZXN0QWxsVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzLmNsYXNzLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENISUxEX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZF87CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNoaWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQ2hpbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNoaWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIGdldENoaWxkKCkgewogICAgICByZXR1cm4gY2hpbGRfID09IG51bGwgPyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0Q2hpbGRPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQVlMT0FEX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyBwYXlsb2FkXzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXlsb2FkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUGF5bG9hZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBwYXlsb2FkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIGdldFBheWxvYWQoKSB7CiAgICAgIHJldHVybiBwYXlsb2FkXyA9PSBudWxsID8gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcGF5bG9hZF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRQYXlsb2FkT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBheWxvYWRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0NISUxEX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzPiByZXBlYXRlZENoaWxkXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcz4gZ2V0UmVwZWF0ZWRDaGlsZExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZENoaWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkQ2hpbGRPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRDaGlsZF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRDaGlsZENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRDaGlsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQ2hpbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZENoaWxkXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcGVhdGVkQ2hpbGRPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZENoaWxkXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExBWllfUEFZTE9BRF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMgbGF6eVBheWxvYWRfOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBsYXp5X3BheWxvYWQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsYXp5UGF5bG9hZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xhenlQYXlsb2FkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGxhenlfcGF5bG9hZCA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsYXp5UGF5bG9hZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyBnZXRMYXp5UGF5bG9hZCgpIHsKICAgICAgcmV0dXJuIGxhenlQYXlsb2FkXyA9PSBudWxsID8gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbGF6eVBheWxvYWRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBsYXp5X3BheWxvYWQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldExhenlQYXlsb2FkT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gbGF6eVBheWxvYWRfID09IG51bGwgPyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBsYXp5UGF5bG9hZF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEsIGdldENoaWxkKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMiwgZ2V0UGF5bG9hZCgpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQ2hpbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgzLCByZXBlYXRlZENoaWxkXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNCwgZ2V0TGF6eVBheWxvYWQoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRDaGlsZCgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgZ2V0UGF5bG9hZCgpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQ2hpbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIHJlcGVhdGVkQ2hpbGRfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQsIGdldExhenlQYXlsb2FkKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIG90aGVyID0gKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcykgb2JqOwoKICAgICAgaWYgKGhhc0NoaWxkKCkgIT0gb3RoZXIuaGFzQ2hpbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQ2hpbGQoKSkgewogICAgICAgIGlmICghZ2V0Q2hpbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldENoaWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1BheWxvYWQoKSAhPSBvdGhlci5oYXNQYXlsb2FkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1BheWxvYWQoKSkgewogICAgICAgIGlmICghZ2V0UGF5bG9hZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGF5bG9hZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRDaGlsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZENoaWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTGF6eVBheWxvYWQoKSAhPSBvdGhlci5oYXNMYXp5UGF5bG9hZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNMYXp5UGF5bG9hZCgpKSB7CiAgICAgICAgaWYgKCFnZXRMYXp5UGF5bG9hZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TGF6eVBheWxvYWQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNDaGlsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ0hJTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldENoaWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzUGF5bG9hZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFZTE9BRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGF5bG9hZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQ2hpbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0NISUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZENoaWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0xhenlQYXlsb2FkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBMQVpZX1BBWUxPQURfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldExhenlQYXlsb2FkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoaXMgcHJvdG8gaW5jbHVkZXMgYSByZWN1cnNpdmVseSBuZXN0ZWQgbWVzc2FnZS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzKQogICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMuY2xhc3MsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRDaGlsZEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRDaGlsZEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0TGF6eVBheWxvYWRGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGNoaWxkXyA9IG51bGw7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcGF5bG9hZF8gPSBudWxsOwogICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHBheWxvYWRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZENoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRDaGlsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgbGF6eVBheWxvYWRfID0gbnVsbDsKICAgICAgICBpZiAobGF6eVBheWxvYWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBsYXp5UGF5bG9hZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGxhenlQYXlsb2FkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9OZXN0ZWRUZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIGJ1aWxkKCkgewogICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIHJlc3VsdCA9IG5ldyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXModGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIHJlc3VsdCkgewogICAgICAgIGlmIChyZXBlYXRlZENoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQ2hpbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRDaGlsZF8pOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRDaGlsZF8gPSByZXBlYXRlZENoaWxkXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQ2hpbGRfID0gcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY2hpbGRfID0gY2hpbGRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBjaGlsZF8KICAgICAgICAgICAgICA6IGNoaWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5wYXlsb2FkXyA9IHBheWxvYWRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBwYXlsb2FkXwogICAgICAgICAgICAgIDogcGF5bG9hZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubGF6eVBheWxvYWRfID0gbGF6eVBheWxvYWRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBsYXp5UGF5bG9hZF8KICAgICAgICAgICAgICA6IGxhenlQYXlsb2FkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNDaGlsZCgpKSB7CiAgICAgICAgICBtZXJnZUNoaWxkKG90aGVyLmdldENoaWxkKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUGF5bG9hZCgpKSB7CiAgICAgICAgICBtZXJnZVBheWxvYWQob3RoZXIuZ2V0UGF5bG9hZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQ2hpbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRDaGlsZF8gPSBvdGhlci5yZXBlYXRlZENoaWxkXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRDaGlsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkQ2hpbGRfLmFkZEFsbChvdGhlci5yZXBlYXRlZENoaWxkXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRDaGlsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZENoaWxkQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZENoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkQ2hpbGRfID0gb3RoZXIucmVwZWF0ZWRDaGlsZF87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgICAgICAgIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZENoaWxkRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZENoaWxkXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0xhenlQYXlsb2FkKCkpIHsKICAgICAgICAgIG1lcmdlTGF6eVBheWxvYWQob3RoZXIuZ2V0TGF6eVBheWxvYWQoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldENoaWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldFBheWxvYWRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMucGFyc2VyKCksCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZENoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZENoaWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQ2hpbGRfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0TGF6eVBheWxvYWRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBjaGlsZEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNoaWxkLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcyBnZXRDaGlsZCgpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY2hpbGRfID09IG51bGwgPyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDaGlsZChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGNoaWxkXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDaGlsZCgKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGNoaWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUNoaWxkKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBjaGlsZF8gIT0gbnVsbCAmJgogICAgICAgICAgICBjaGlsZF8gIT0gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldENoaWxkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjaGlsZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoY2hpbGRfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ2hpbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGNoaWxkXyA9IG51bGw7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0Q2hpbGRCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0Q2hpbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldENoaWxkT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldENoaWxkRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRDaGlsZCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgY2hpbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNoaWxkQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIHBheWxvYWRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IHBheWxvYWRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXlsb2FkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1BheWxvYWQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHBheWxvYWQuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIGdldFBheWxvYWQoKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBheWxvYWRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcGF5bG9hZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBheWxvYWQocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHBheWxvYWRfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHBheWxvYWRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYXlsb2FkKAogICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBwYXlsb2FkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VQYXlsb2FkKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApICYmCiAgICAgICAgICAgIHBheWxvYWRfICE9IG51bGwgJiYKICAgICAgICAgICAgcGF5bG9hZF8gIT0gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldFBheWxvYWRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHBheWxvYWRfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHBheWxvYWRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAocGF5bG9hZF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBheWxvYWQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIHBheWxvYWRfID0gbnVsbDsKICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHBheWxvYWRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldFBheWxvYWRCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRQYXlsb2FkT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHBheWxvYWRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBwYXlsb2FkXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBwYXlsb2FkXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcywgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRQYXlsb2FkRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0UGF5bG9hZCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcGF5bG9hZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcGF5bG9hZEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcz4gcmVwZWF0ZWRDaGlsZF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQ2hpbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRDaGlsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXM+KHJlcGVhdGVkQ2hpbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcywgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlcj4gcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzPiBnZXRSZXBlYXRlZENoaWxkTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZENoaWxkXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZENoaWxkQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQ2hpbGRDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZENoaWxkXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZENoaWxkQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQ2hpbGQoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRDaGlsZF8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZENoaWxkKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRDaGlsZElzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRDaGlsZF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZENoaWxkKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQ2hpbGRJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRDaGlsZChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRDaGlsZElzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRDaGlsZF8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZENoaWxkQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRDaGlsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQ2hpbGRJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRDaGlsZCgKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZENoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRDaGlsZElzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRDaGlsZF8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZENoaWxkQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRDaGlsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZENoaWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZENoaWxkXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZENoaWxkQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkQ2hpbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcz4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZENoaWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZENoaWxkXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZENoaWxkKCkgewogICAgICAgIGlmIChyZXBlYXRlZENoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRDaGlsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRDaGlsZChpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQ2hpbGRJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldFJlcGVhdGVkQ2hpbGRCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQ2hpbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRDaGlsZE9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZENoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQ2hpbGRfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRDaGlsZE9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZENoaWxkXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2FyZW5hX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyIGFkZFJlcGVhdGVkQ2hpbGRCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZENoaWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciBhZGRSZXBlYXRlZENoaWxkQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZENoaWxkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkQ2hpbGRCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRDaGlsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRDaGlsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRDaGlsZF8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRDaGlsZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcyBsYXp5UGF5bG9hZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcywgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gbGF6eVBheWxvYWRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGxhenlfcGF5bG9hZCA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbGF6eVBheWxvYWQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTGF6eVBheWxvYWQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBsYXp5X3BheWxvYWQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBsYXp5UGF5bG9hZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMgZ2V0TGF6eVBheWxvYWQoKSB7CiAgICAgICAgaWYgKGxhenlQYXlsb2FkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGxhenlQYXlsb2FkXyA9PSBudWxsID8gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbGF6eVBheWxvYWRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbGF6eVBheWxvYWRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBsYXp5X3BheWxvYWQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TGF6eVBheWxvYWQocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKGxhenlQYXlsb2FkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBsYXp5UGF5bG9hZF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGF6eVBheWxvYWRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBsYXp5X3BheWxvYWQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TGF6eVBheWxvYWQoCiAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAobGF6eVBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBsYXp5UGF5bG9hZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGF6eVBheWxvYWRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBsYXp5X3BheWxvYWQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VMYXp5UGF5bG9hZChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAobGF6eVBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkgJiYKICAgICAgICAgICAgbGF6eVBheWxvYWRfICE9IG51bGwgJiYKICAgICAgICAgICAgbGF6eVBheWxvYWRfICE9IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRMYXp5UGF5bG9hZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGF6eVBheWxvYWRfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGxhenlQYXlsb2FkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGxhenlQYXlsb2FkXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGxhenlfcGF5bG9hZCA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxhenlQYXlsb2FkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBsYXp5UGF5bG9hZF8gPSBudWxsOwogICAgICAgIGlmIChsYXp5UGF5bG9hZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGxhenlQYXlsb2FkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgbGF6eVBheWxvYWRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBsYXp5X3BheWxvYWQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldExhenlQYXlsb2FkQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldExhenlQYXlsb2FkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBsYXp5X3BheWxvYWQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRMYXp5UGF5bG9hZE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAobGF6eVBheWxvYWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbGF6eVBheWxvYWRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBsYXp5UGF5bG9hZF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbGF6eVBheWxvYWRfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMgbGF6eV9wYXlsb2FkID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlcywgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRMYXp5UGF5bG9hZEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAobGF6eVBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBsYXp5UGF5bG9hZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TGF6eVBheWxvYWQoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGxhenlQYXlsb2FkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBsYXp5UGF5bG9hZEJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM19hcmVuYV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5OZXN0ZWRUZXN0QWxsVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRUZXN0QWxsVHlwZXM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkVGVzdEFsbFR5cGVzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkVGVzdEFsbFR5cGVzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZFRlc3RBbGxUeXBlcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuTmVzdGVkVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgYyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYy4KICAgICAqLwogICAgaW50IGdldEMoKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBEZWZpbmUgdGhlc2UgYWZ0ZXIgVGVzdEFsbFR5cGVzIHRvIG1ha2Ugc3VyZSB0aGUgY29tcGlsZXIgY2FuIGhhbmRsZQogICAqIHRoYXQuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGb3JlaWduTWVzc2FnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UpCiAgICAgIEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBGb3JlaWduTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBGb3JlaWduTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEZvcmVpZ25NZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEZvcmVpZ25NZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZS5jbGFzcywgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ19GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgY18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBjID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEMoKSB7CiAgICAgIHJldHVybiBjXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmIChjXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgY18pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoY18gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgY18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSBvdGhlciA9IChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKGdldEMoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0QygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ19GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEMoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIERlZmluZSB0aGVzZSBhZnRlciBUZXN0QWxsVHlwZXMgdG8gbWFrZSBzdXJlIHRoZSBjb21waWxlciBjYW4gaGFuZGxlCiAgICAgKiB0aGF0LgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlKQogICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZS5jbGFzcywgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgY18gPSAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5jXyA9IGNfOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmdldEMoKSAhPSAwKSB7CiAgICAgICAgICBzZXRDKG90aGVyLmdldEMoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgY18gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGMgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDKCkgewogICAgICAgIHJldHVybiBjXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgYyA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDKGludCB2YWx1ZSkgewoKICAgICAgICBjXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgYyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLkZvcmVpZ25NZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5Gb3JlaWduTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvcmVpZ25NZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZvcmVpZ25NZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgRm9yZWlnbk1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb3JlaWduTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb3JlaWduTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuRm9yZWlnbk1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0RW1wdHlNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0RW1wdHlNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRlc3RFbXB0eU1lc3NhZ2UgaXMgdXNlZCB0byB0ZXN0IGJlaGF2aW9yIG9mIHVua25vd24gZmllbGRzLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0RW1wdHlNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0RW1wdHlNZXNzYWdlKQogICAgICBUZXN0RW1wdHlNZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0RW1wdHlNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RFbXB0eU1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0RW1wdHlNZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RFbXB0eU1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlLmNsYXNzLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RFbXB0eU1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RFbXB0eU1lc3NhZ2Ugb3RoZXIgPSAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEVtcHR5TWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0RW1wdHlNZXNzYWdlIGlzIHVzZWQgdG8gdGVzdCBiZWhhdmlvciBvZiB1bmtub3duIGZpZWxkcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0RW1wdHlNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2UpCiAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEVtcHR5TWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RFbXB0eU1lc3NhZ2UuY2xhc3MsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RFbXB0eU1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RFbXB0eU1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEVtcHR5TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEVtcHR5TWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEVtcHR5TWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEVtcHR5TWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEVtcHR5TWVzc2FnZSh0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RFbXB0eU1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RFbXB0eU1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdEVtcHR5TWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RFbXB0eU1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RFbXB0eU1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RW1wdHlNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RFbXB0eU1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0RW1wdHlNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEVtcHR5TWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RW1wdHlNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0RW1wdHlNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiA8cHJlPgogICAqIE5lZWRlZCBmb3IgYSBQeXRob24gdGVzdC4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSkKICAgICAgVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLmNsYXNzLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJiLgogICAgICAgKi8KICAgICAgaW50IGdldEJiKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZE1lc3NhZ2UgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKQogICAgICAgIE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBOZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgTmVzdGVkTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLmNsYXNzLCBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwdWJsaWMgaW50ZXJmYWNlIE5lc3RlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UpCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5pbnQzMiBjYyA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGNjLgogICAgICAgICAqLwogICAgICAgIGludCBnZXRDYygpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBOZXN0ZWROZXN0ZWRNZXNzYWdlIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSkKICAgICAgICAgIE5lc3RlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgICAvLyBVc2UgTmVzdGVkTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICAgIHByaXZhdGUgTmVzdGVkTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIE5lc3RlZE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICAgIHJldHVybiBuZXcgTmVzdGVkTmVzdGVkTWVzc2FnZSgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfTmVzdGVkTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX05lc3RlZE5lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0NfRklFTERfTlVNQkVSID0gMTsKICAgICAgICBwcml2YXRlIGludCBjY18gPSAwOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPmludDMyIGNjID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgY2MuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0Q2MoKSB7CiAgICAgICAgICByZXR1cm4gY2NfOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoY2NfICE9IDApIHsKICAgICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgY2NfKTsKICAgICAgICAgIH0KICAgICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICAgIHNpemUgPSAwOwogICAgICAgICAgaWYgKGNjXyAhPSAwKSB7CiAgICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIGNjXyk7CiAgICAgICAgICB9CiAgICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICAgIHJldHVybiBzaXplOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UpKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICAgIH0KICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBvdGhlciA9IChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UpIG9iajsKCiAgICAgICAgICBpZiAoZ2V0Q2MoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldENjKCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICAgIH0KICAgICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIENDX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldENjKCk7CiAgICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZX0KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlKQogICAgICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX05lc3RlZE5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfTmVzdGVkTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgICAgfQoKICAgICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgICAgY2NfID0gMDsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX05lc3RlZE5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlKHRoaXMpOwogICAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICB9CgogICAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIHJlc3VsdCkgewogICAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgICByZXN1bHQuY2NfID0gY2NfOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UpIHsKICAgICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2Upb3RoZXIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgICBpZiAob3RoZXIuZ2V0Q2MoKSAhPSAwKSB7CiAgICAgICAgICAgICAgc2V0Q2Mob3RoZXIuZ2V0Q2MoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICAgICAgY2NfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICAgIHByaXZhdGUgaW50IGNjXyA7CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPmludDMyIGNjID0gMTs8L2NvZGU+CiAgICAgICAgICAgKiBAcmV0dXJuIFRoZSBjYy4KICAgICAgICAgICAqLwogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGludCBnZXRDYygpIHsKICAgICAgICAgICAgcmV0dXJuIGNjXzsKICAgICAgICAgIH0KICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+aW50MzIgY2MgPSAxOzwvY29kZT4KICAgICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgY2MgdG8gc2V0LgogICAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRDYyhpbnQgdmFsdWUpIHsKCiAgICAgICAgICAgIGNjXyA9IHZhbHVlOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+aW50MzIgY2MgPSAxOzwvY29kZT4KICAgICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJDYygpIHsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgICBjY18gPSAwOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICAgIH0KCgogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSkKICAgICAgICB9CgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlKQogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgICAgIHN0YXRpYyB7CiAgICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWROZXN0ZWRNZXNzYWdlPgogICAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxOZXN0ZWROZXN0ZWRNZXNzYWdlPigpIHsKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBOZXN0ZWROZXN0ZWRNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTmVzdGVkTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTmVzdGVkTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgICAgfQoKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkJfRklFTERfTlVNQkVSID0gMTsKICAgICAgcHJpdmF0ZSBpbnQgYmJfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJiLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEJiKCkgewogICAgICAgIHJldHVybiBiYl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGJiXyAhPSAwKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBiYl8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoYmJfICE9IDApIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBiYl8pOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG90aGVyID0gKHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpIG9iajsKCiAgICAgICAgaWYgKGdldEJiKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QmIoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCQl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QmIoKTsKICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSkKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuY2xhc3MsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGJiXyA9IDA7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICAgIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LmJiXyA9IGJiXzsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSlvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuZ2V0QmIoKSAhPSAwKSB7CiAgICAgICAgICAgIHNldEJiKG90aGVyLmdldEJiKCkpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICAgIGJiXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IGJiXyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+aW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBiYi4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRCYigpIHsKICAgICAgICAgIHJldHVybiBiYl87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPmludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBiYiB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJiKGludCB2YWx1ZSkgewoKICAgICAgICAgIGJiXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+aW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJCYigpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIGJiXyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE5lc3RlZE1lc3NhZ2U+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTmVzdGVkTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5lZWRlZCBmb3IgYSBQeXRob24gdGVzdC4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSkKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLmludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuY2xhc3MsIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zQXJlbmEuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19hcmVuYV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0FyZW5hLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UGlja2xlTmVzdGVkTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfYXJlbmFfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNBcmVuYS5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX05lc3RlZE5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfTmVzdGVkTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuK2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcm90bzNfYXJlbmEuIiArCiAgICAgICJwcm90b1wwMjJcMDI1cHJvdG8zX2FyZW5hX3VuaXR0ZXN0XDAzMiVnb29nbGUvcHJvIiArCiAgICAgICJ0b2J1Zi91bml0dGVzdF9pbXBvcnQucHJvdG9cIlwzNTVcMDMxXG5cMDE0VGVzdEFsbFQiICsKICAgICAgInlwZXNcMDIyXDAyNlxuXDAxNm9wdGlvbmFsX2ludDMyXDAzMFwwMDEgXDAwMShcMDA1XDAyMlwwMjZcblwwMTZvcHRpb25hbCIgKwogICAgICAiX2ludDY0XDAzMFwwMDIgXDAwMShcMDAzXDAyMlwwMjdcblwwMTdvcHRpb25hbF91aW50MzJcMDMwXDAwMyBcMDAxKFxyXDAyMlwwMjdcbiIgKwogICAgICAiXDAxN29wdGlvbmFsX3VpbnQ2NFwwMzBcMDA0IFwwMDEoXDAwNFwwMjJcMDI3XG5cMDE3b3B0aW9uYWxfc2ludDMiICsKICAgICAgIjJcMDMwXDAwNSBcMDAxKFwwMjFcMDIyXDAyN1xuXDAxN29wdGlvbmFsX3NpbnQ2NFwwMzBcMDA2IFwwMDEoXDAyMlwwMjJcMDMwXG5cMDIwb3B0aSIgKwogICAgICAib25hbF9maXhlZDMyXDAzMFwwMDcgXDAwMShcMDA3XDAyMlwwMzBcblwwMjBvcHRpb25hbF9maXhlZDY0XDAzMFwwMTAiICsKICAgICAgIiBcMDAxKFwwMDZcMDIyXDAzMVxuXDAyMW9wdGlvbmFsX3NmaXhlZDMyXDAzMFx0IFwwMDEoXDAxN1wwMjJcMDMxXG5cMDIxb3B0aW8iICsKICAgICAgIm5hbF9zZml4ZWQ2NFwwMzBcbiBcMDAxKFwwMjBcMDIyXDAyNlxuXDAxNm9wdGlvbmFsX2Zsb2F0XDAzMFwwMTMgXDAwMSIgKwogICAgICAiKFwwMDJcMDIyXDAyN1xuXDAxN29wdGlvbmFsX2RvdWJsZVwwMzBcMDE0IFwwMDEoXDAwMVwwMjJcMDI1XG5ccm9wdGlvbmFsXyIgKwogICAgICAiYm9vbFwwMzBcciBcMDAxKFwwMTBcMDIyXDAyN1xuXDAxN29wdGlvbmFsX3N0cmluZ1wwMzBcMDE2IFwwMDEoXHRcMDIyXDAyNlxuXDAxNm8iICsKICAgICAgInB0aW9uYWxfYnl0ZXNcMDMwXDAxNyBcMDAxKFwwMTRcMDIyUlxuXDAyN29wdGlvbmFsX25lc3RlZF9tIiArCiAgICAgICJlc3NhZ2VcMDMwXDAyMiBcMDAxKFwwMTMyMS5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzIiArCiAgICAgICJ0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZVwwMjJHXG5cMDMwb3B0aW9uYWxfZm9yZSIgKwogICAgICAiaWduX21lc3NhZ2VcMDMwXDAyMyBcMDAxKFwwMTMyJS5wcm90bzNfYXJlbmFfdW5pdHRlcyIgKwogICAgICAidC5Gb3JlaWduTWVzc2FnZVwwMjJIXG5cMDI3b3B0aW9uYWxfaW1wb3J0X21lc3MiICsKICAgICAgImFnZVwwMzBcMDI0IFwwMDEoXDAxMzJcJy5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wIiArCiAgICAgICJvcnRNZXNzYWdlXDAyMkxcblwwMjRvcHRpb25hbF9uZXN0ZWRfZW51bVwwMzBcMDI1IFwwMDEoXDAxNiIgKwogICAgICAiMi4ucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZSIgKwogICAgICAic3RlZEVudW1cMDIyQVxuXDAyNW9wdGlvbmFsX2ZvcmVpZ25fZW51bVwwMzBcMDI2IFwwMDEoXDAxNjIiICsKICAgICAgIlwiLnByb3RvM19hcmVuYV91bml0dGVzdC5Gb3JlaWduRW51bVwwMjIhXG5cMDI1byIgKwogICAgICAicHRpb25hbF9zdHJpbmdfcGllY2VcMDMwXDAzMCBcMDAxKFx0QlwwMDJcMDEwXDAwMlwwMjJcMDMxXG5ccm9wdGlvbiIgKwogICAgICAiYWxfY29yZFwwMzBcMDMxIFwwMDEoXHRCXDAwMlwwMTBcMDAxXDAyMlVcblwwMzZvcHRpb25hbF9wdWJsaWNfaW1wIiArCiAgICAgICJvcnRfbWVzc2FnZVwwMzBcMDMyIFwwMDEoXDAxMzItLnByb3RvYnVmX3VuaXR0ZXN0X2ltIiArCiAgICAgICJwb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2VcMDIyVFxuXDAyNW9wdGlvbmFsX2xheiIgKwogICAgICAieV9tZXNzYWdlXDAzMFwwMzMgXDAwMShcMDEzMjEucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LiIgKwogICAgICAiVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VCXDAwMihcMDAxXDAyMl9cbiBvcHRpb24iICsKICAgICAgImFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlXDAzMFwwMzQgXDAwMShcMDEzMjEucHJvdG8iICsKICAgICAgIjNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3MiICsKICAgICAgImFnZUJcMDAyeFwwMDFcMDIyUVxuXDAzNG9wdGlvbmFsX2xhenlfaW1wb3J0X21lc3NhZ2VcMDMwIiArCiAgICAgICJzIFwwMDEoXDAxMzJcJy5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TSIgKwogICAgICAiZXNzYWdlQlwwMDIoXDAwMVwwMjJcMDI2XG5cMDE2cmVwZWF0ZWRfaW50MzJcMDMwXDAzNyBcMDAzKFwwMDVcMDIyXDAyNlxuXDAxNnJlIiArCiAgICAgICJwZWF0ZWRfaW50NjRcMDMwICBcMDAzKFwwMDNcMDIyXDAyN1xuXDAxN3JlcGVhdGVkX3VpbnQzMlwwMzAhICIgKwogICAgICAiXDAwMyhcclwwMjJcMDI3XG5cMDE3cmVwZWF0ZWRfdWludDY0XDAzMFwiIFwwMDMoXDAwNFwwMjJcMDI3XG5cMDE3cmVwZWF0ZWQiICsKICAgICAgIl9zaW50MzJcMDMwIyBcMDAzKFwwMjFcMDIyXDAyN1xuXDAxN3JlcGVhdGVkX3NpbnQ2NFwwMzAkIFwwMDMoXDAyMlwwMjJcMDMwIiArCiAgICAgICJcblwwMjByZXBlYXRlZF9maXhlZDMyXDAzMCUgXDAwMyhcMDA3XDAyMlwwMzBcblwwMjByZXBlYXRlZF9maXgiICsKICAgICAgImVkNjRcMDMwJiBcMDAzKFwwMDZcMDIyXDAzMVxuXDAyMXJlcGVhdGVkX3NmaXhlZDMyXDAzMFwnIFwwMDMoXDAxN1wwMjJcMDMxXG4iICsKICAgICAgIlwwMjFyZXBlYXRlZF9zZml4ZWQ2NFwwMzAoIFwwMDMoXDAyMFwwMjJcMDI2XG5cMDE2cmVwZWF0ZWRfZmxvIiArCiAgICAgICJhdFwwMzApIFwwMDMoXDAwMlwwMjJcMDI3XG5cMDE3cmVwZWF0ZWRfZG91YmxlXDAzMCogXDAwMyhcMDAxXDAyMlwwMjVcblxycmVwIiArCiAgICAgICJlYXRlZF9ib29sXDAzMCsgXDAwMyhcMDEwXDAyMlwwMjdcblwwMTdyZXBlYXRlZF9zdHJpbmdcMDMwLCBcMDAzKCIgKwogICAgICAiXHRcMDIyXDAyNlxuXDAxNnJlcGVhdGVkX2J5dGVzXDAzMC0gXDAwMyhcMDE0XDAyMlwiXG5cMDI1cHJvdG8zX29wdGkiICsKICAgICAgIm9uYWxfaW50MzJcMDMwdCBcMDAxKFwwMDVIXDAwMVwyMTBcMDAxXDAwMVwwMjJcIlxuXDAyNXByb3RvM19vcHRpb25hbCIgKwogICAgICAiX2ludDY0XDAzMHUgXDAwMShcMDAzSFwwMDJcMjEwXDAwMVwwMDFcMDIyI1xuXDAyNnByb3RvM19vcHRpb25hbF91aW4iICsKICAgICAgInQzMlwwMzB2IFwwMDEoXHJIXDAwM1wyMTBcMDAxXDAwMVwwMjIjXG5cMDI2cHJvdG8zX29wdGlvbmFsX3VpbnQ2NCIgKwogICAgICAiXDAzMHcgXDAwMShcMDA0SFwwMDRcMjEwXDAwMVwwMDFcMDIyI1xuXDAyNnByb3RvM19vcHRpb25hbF9zaW50MzJcMDMweCAiICsKICAgICAgIlwwMDEoXDAyMUhcMDA1XDIxMFwwMDFcMDAxXDAyMiNcblwwMjZwcm90bzNfb3B0aW9uYWxfc2ludDY0XDAzMHkgXDAwMShcMDIyIiArCiAgICAgICJIXDAwNlwyMTBcMDAxXDAwMVwwMjIkXG5cMDI3cHJvdG8zX29wdGlvbmFsX2ZpeGVkMzJcMDMweiBcMDAxKFwwMDdIXDAwNyIgKwogICAgICAiXDIxMFwwMDFcMDAxXDAyMiRcblwwMjdwcm90bzNfb3B0aW9uYWxfZml4ZWQ2NFwwMzB7IFwwMDEoXDAwNkhcMDEwXDIxMFwwMDEiICsKICAgICAgIlwwMDFcMDIyJVxuXDAzMHByb3RvM19vcHRpb25hbF9zZml4ZWQzMlwwMzB8IFwwMDEoXDAxN0hcdFwyMTBcMDAxXDAwMSIgKwogICAgICAiXDAyMiVcblwwMzBwcm90bzNfb3B0aW9uYWxfc2ZpeGVkNjRcMDMwfSBcMDAxKFwwMjBIXG5cMjEwXDAwMVwwMDFcMDIyIiArCiAgICAgICJcIlxuXDAyNXByb3RvM19vcHRpb25hbF9mbG9hdFwwMzB+IFwwMDEoXDAwMkhcMDEzXDIxMFwwMDFcMDAxXDAyMiNcblwwMjZwIiArCiAgICAgICJyb3RvM19vcHRpb25hbF9kb3VibGVcMDMwXDE3NyBcMDAxKFwwMDFIXDAxNFwyMTBcMDAxXDAwMVwwMjJcIlxuXDAyNHByb3QiICsKICAgICAgIm8zX29wdGlvbmFsX2Jvb2xcMDMwXDIwMFwwMDEgXDAwMShcMDEwSFxyXDIxMFwwMDFcMDAxXDAyMiRcblwwMjZwcm90bzNfbyIgKwogICAgICAicHRpb25hbF9zdHJpbmdcMDMwXDIwMVwwMDEgXDAwMShcdEhcMDE2XDIxMFwwMDFcMDAxXDAyMiNcblwwMjVwcm90bzNfb3B0IiArCiAgICAgICJpb25hbF9ieXRlc1wwMzBcMjAyXDAwMSBcMDAxKFwwMTRIXDAxN1wyMTBcMDAxXDAwMVwwMjJSXG5cMDI3cmVwZWF0ZWRfbmVzdCIgKwogICAgICAiZWRfbWVzc2FnZVwwMzAwIFwwMDMoXDAxMzIxLnByb3RvM19hcmVuYV91bml0dGVzdCIgKwogICAgICAiLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlXDAyMkdcblwwMzByZXBlYXRlZF8iICsKICAgICAgImZvcmVpZ25fbWVzc2FnZVwwMzAxIFwwMDMoXDAxMzIlLnByb3RvM19hcmVuYV91bmkiICsKICAgICAgInR0ZXN0LkZvcmVpZ25NZXNzYWdlXDAyMkhcblwwMjdyZXBlYXRlZF9pbXBvcnRfIiArCiAgICAgICJtZXNzYWdlXDAzMDIgXDAwMyhcMDEzMlwnLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydCIgKwogICAgICAiLkltcG9ydE1lc3NhZ2VcMDIyTFxuXDAyNHJlcGVhdGVkX25lc3RlZF9lbnVtXDAzMDMiICsKICAgICAgIiBcMDAzKFwwMTYyLi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuVGVzdEFsbFR5cGUiICsKICAgICAgInMuTmVzdGVkRW51bVwwMjJBXG5cMDI1cmVwZWF0ZWRfZm9yZWlnbl9lbnVtXDAzMDQgIiArCiAgICAgICJcMDAzKFwwMTYyXCIucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LkZvcmVpZ25FbnVtXDAyMiIgKwogICAgICAiIVxuXDAyNXJlcGVhdGVkX3N0cmluZ19waWVjZVwwMzA2IFwwMDMoXHRCXDAwMlwwMTBcMDAyXDAyMlwwMzFcblxycmUiICsKICAgICAgInBlYXRlZF9jb3JkXDAzMDcgXDAwMyhcdEJcMDAyXDAxMFwwMDFcMDIyVFxuXDAyNXJlcGVhdGVkX2xhenlfbSIgKwogICAgICAiZXNzYWdlXDAzMDkgXDAwMyhcMDEzMjEucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlcyIgKwogICAgICAidEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VCXDAwMihcMDAxXDAyMlwwMjZcblwwMTRvbmVvZl91aW4iICsKICAgICAgInQzMlwwMzBvIFwwMDEoXHJIXDAwMFwwMjJRXG5cMDI0b25lb2ZfbmVzdGVkX21lc3NhZ2VcMDMwcCBcMDAxKCIgKwogICAgICAiXDAxMzIxLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTiIgKwogICAgICAiZXN0ZWRNZXNzYWdlSFwwMDBcMDIyXDAyNlxuXDAxNG9uZW9mX3N0cmluZ1wwMzBxIFwwMDEoXHRIXDAwMFwwMjJcMDI1IiArCiAgICAgICJcblwwMTNvbmVvZl9ieXRlc1wwMzByIFwwMDEoXDAxNEhcMDAwXDAzMlwwMzNcblxyTmVzdGVkTWVzc2FnZVwwMjJcbiIgKwogICAgICAiXG5cMDAyYmJcMDMwXDAwMSBcMDAxKFwwMDVcIkNcblxuTmVzdGVkRW51bVwwMjJcMDEwXG5cMDA0WkVST1wwMjBcMDAwXDAyMlwwMDdcblwwMDNGTyIgKwogICAgICAiT1wwMjBcMDAxXDAyMlwwMDdcblwwMDNCQVJcMDIwXDAwMlwwMjJcMDA3XG5cMDAzQkFaXDAyMFwwMDNcMDIyXDAyMFxuXDAwM05FR1wwMjBcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMDAxQiIgKwogICAgICAiXHJcblwwMTNvbmVvZl9maWVsZEJcMDMwXG5cMDI2X3Byb3RvM19vcHRpb25hbF9pbnQzMiIgKwogICAgICAiQlwwMzBcblwwMjZfcHJvdG8zX29wdGlvbmFsX2ludDY0QlwwMzFcblwwMjdfcHJvdG8zX29wIiArCiAgICAgICJ0aW9uYWxfdWludDMyQlwwMzFcblwwMjdfcHJvdG8zX29wdGlvbmFsX3VpbnQ2NCIgKwogICAgICAiQlwwMzFcblwwMjdfcHJvdG8zX29wdGlvbmFsX3NpbnQzMkJcMDMxXG5cMDI3X3Byb3RvM19vIiArCiAgICAgICJwdGlvbmFsX3NpbnQ2NEJcMDMyXG5cMDMwX3Byb3RvM19vcHRpb25hbF9maXhlZCIgKwogICAgICAiMzJCXDAzMlxuXDAzMF9wcm90bzNfb3B0aW9uYWxfZml4ZWQ2NEJcMDMzXG5cMDMxX3Byb3RvIiArCiAgICAgICIzX29wdGlvbmFsX3NmaXhlZDMyQlwwMzNcblwwMzFfcHJvdG8zX29wdGlvbmFsXyIgKwogICAgICAic2ZpeGVkNjRCXDAzMFxuXDAyNl9wcm90bzNfb3B0aW9uYWxfZmxvYXRCXDAzMVxuXDAyN19wIiArCiAgICAgICJyb3RvM19vcHRpb25hbF9kb3VibGVCXDAyN1xuXDAyNV9wcm90bzNfb3B0aW9uYSIgKwogICAgICAibF9ib29sQlwwMzFcblwwMjdfcHJvdG8zX29wdGlvbmFsX3N0cmluZ0JcMDMwXG5cMDI2X3ByIiArCiAgICAgICJvdG8zX29wdGlvbmFsX2J5dGVzXCJcMjU2XDAwM1xuXDAxN1Rlc3RQYWNrZWRUeXBlc1wwMjIiICsKICAgICAgIlwwMzBcblwwMTRwYWNrZWRfaW50MzJcMDMwWiBcMDAzKFwwMDVCXDAwMlwwMjBcMDAxXDAyMlwwMzBcblwwMTRwYWNrZWRfaW50NiIgKwogICAgICAiNFwwMzBbIFwwMDMoXDAwM0JcMDAyXDAyMFwwMDFcMDIyXDAzMVxuXHJwYWNrZWRfdWludDMyXDAzMFxcIFwwMDMoXHJCXDAwMlwwMjBcMDAxXDAyMlwwMzEiICsKICAgICAgIlxuXHJwYWNrZWRfdWludDY0XDAzMF0gXDAwMyhcMDA0QlwwMDJcMDIwXDAwMVwwMjJcMDMxXG5ccnBhY2tlZF9zaW50IiArCiAgICAgICIzMlwwMzBeIFwwMDMoXDAyMUJcMDAyXDAyMFwwMDFcMDIyXDAzMVxuXHJwYWNrZWRfc2ludDY0XDAzMF8gXDAwMyhcMDIyQlwwMDJcMDIwXDAwMVwwMjIiICsKICAgICAgIlwwMzJcblwwMTZwYWNrZWRfZml4ZWQzMlwwMzBgIFwwMDMoXDAwN0JcMDAyXDAyMFwwMDFcMDIyXDAzMlxuXDAxNnBhY2tlZF9maSIgKwogICAgICAieGVkNjRcMDMwYSBcMDAzKFwwMDZCXDAwMlwwMjBcMDAxXDAyMlwwMzNcblwwMTdwYWNrZWRfc2ZpeGVkMzJcMDMwYiBcMDAzKFwwMTciICsKICAgICAgIkJcMDAyXDAyMFwwMDFcMDIyXDAzM1xuXDAxN3BhY2tlZF9zZml4ZWQ2NFwwMzBjIFwwMDMoXDAyMEJcMDAyXDAyMFwwMDFcMDIyXDAzMFxuXDAxNHBhYyIgKwogICAgICAia2VkX2Zsb2F0XDAzMGQgXDAwMyhcMDAyQlwwMDJcMDIwXDAwMVwwMjJcMDMxXG5ccnBhY2tlZF9kb3VibGVcMDMwZSBcMDAzIiArCiAgICAgICIoXDAwMUJcMDAyXDAyMFwwMDFcMDIyXDAyN1xuXDAxM3BhY2tlZF9ib29sXDAzMGYgXDAwMyhcMDEwQlwwMDJcMDIwXDAwMVwwMjI7XG5cMDEzcGFja2UiICsKICAgICAgImRfZW51bVwwMzBnIFwwMDMoXDAxNjJcIi5wcm90bzNfYXJlbmFfdW5pdHRlc3QuRm9yIiArCiAgICAgICJlaWduRW51bUJcMDAyXDAyMFwwMDFcIlwzMzdcMDAzXG5cMDIxVGVzdFVucGFja2VkVHlwZXNcMDIyXDAzMlxuXDAxNnJlIiArCiAgICAgICJwZWF0ZWRfaW50MzJcMDMwXDAwMSBcMDAzKFwwMDVCXDAwMlwwMjBcMDAwXDAyMlwwMzJcblwwMTZyZXBlYXRlZF9pbnQ2NCIgKwogICAgICAiXDAzMFwwMDIgXDAwMyhcMDAzQlwwMDJcMDIwXDAwMFwwMjJcMDMzXG5cMDE3cmVwZWF0ZWRfdWludDMyXDAzMFwwMDMgXDAwMyhcckJcMDAyXDAyMFwwMDBcMDIyIiArCiAgICAgICJcMDMzXG5cMDE3cmVwZWF0ZWRfdWludDY0XDAzMFwwMDQgXDAwMyhcMDA0QlwwMDJcMDIwXDAwMFwwMjJcMDMzXG5cMDE3cmVwZWF0ZWQiICsKICAgICAgIl9zaW50MzJcMDMwXDAwNSBcMDAzKFwwMjFCXDAwMlwwMjBcMDAwXDAyMlwwMzNcblwwMTdyZXBlYXRlZF9zaW50NjRcMDMwXDAwNiBcMDAzIiArCiAgICAgICIoXDAyMkJcMDAyXDAyMFwwMDBcMDIyXDAzNFxuXDAyMHJlcGVhdGVkX2ZpeGVkMzJcMDMwXDAwNyBcMDAzKFwwMDdCXDAwMlwwMjBcMDAwXDAyMlwwMzRcblwwMjAiICsKICAgICAgInJlcGVhdGVkX2ZpeGVkNjRcMDMwXDAxMCBcMDAzKFwwMDZCXDAwMlwwMjBcMDAwXDAyMlwwMzVcblwwMjFyZXBlYXRlZF9zIiArCiAgICAgICJmaXhlZDMyXDAzMFx0IFwwMDMoXDAxN0JcMDAyXDAyMFwwMDBcMDIyXDAzNVxuXDAyMXJlcGVhdGVkX3NmaXhlZDY0XDAzMFxuIiArCiAgICAgICIgXDAwMyhcMDIwQlwwMDJcMDIwXDAwMFwwMjJcMDMyXG5cMDE2cmVwZWF0ZWRfZmxvYXRcMDMwXDAxMyBcMDAzKFwwMDJCXDAwMlwwMjBcMDAwXDAyMlwwMzNcblwwMTciICsKICAgICAgInJlcGVhdGVkX2RvdWJsZVwwMzBcMDE0IFwwMDMoXDAwMUJcMDAyXDAyMFwwMDBcMDIyXDAzMVxuXHJyZXBlYXRlZF9ibyIgKwogICAgICAib2xcMDMwXHIgXDAwMyhcMDEwQlwwMDJcMDIwXDAwMFwwMjJQXG5cMDI0cmVwZWF0ZWRfbmVzdGVkX2VudW1cMDMwXDAxNiBcMDAzIiArCiAgICAgICIoXDAxNjIuLnByb3RvM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXMuIiArCiAgICAgICJOZXN0ZWRFbnVtQlwwMDJcMDIwXDAwMFwiXDIwNlwwMDJcblwwMjJOZXN0ZWRUZXN0QWxsVHlwZXNcMDIyOFxuIiArCiAgICAgICJcMDA1Y2hpbGRcMDMwXDAwMSBcMDAxKFwwMTMyKS5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmVzIiArCiAgICAgICJ0ZWRUZXN0QWxsVHlwZXNcMDIyNFxuXDAwN3BheWxvYWRcMDMwXDAwMiBcMDAxKFwwMTMyIy5wcm90byIgKwogICAgICAiM19hcmVuYV91bml0dGVzdC5UZXN0QWxsVHlwZXNcMDIyQVxuXDAxNnJlcGVhdGUiICsKICAgICAgImRfY2hpbGRcMDMwXDAwMyBcMDAzKFwwMTMyKS5wcm90bzNfYXJlbmFfdW5pdHRlc3QuTmUiICsKICAgICAgInN0ZWRUZXN0QWxsVHlwZXNcMDIyPVxuXDAxNGxhenlfcGF5bG9hZFwwMzBcMDA0IFwwMDEoXDAxMzIjIiArCiAgICAgICIucHJvdG8zX2FyZW5hX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc0JcMDAyKFwwMDFcIiIgKwogICAgICAiXDAzM1xuXDAxNkZvcmVpZ25NZXNzYWdlXDAyMlx0XG5cMDAxY1wwMzBcMDAxIFwwMDEoXDAwNVwiXDAyMlxuXDAyMFRlc3RFbXB0IiArCiAgICAgICJ5TWVzc2FnZVwiWVxuXDAyN1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlXDAzMj5cblxyTiIgKwogICAgICAiZXN0ZWRNZXNzYWdlXDAyMlxuXG5cMDAyYmJcMDMwXDAwMSBcMDAxKFwwMDVcMDMyIVxuXDAyM05lc3RlZE5lc3RlZCIgKwogICAgICAiTWVzc2FnZVwwMjJcblxuXDAwMmNjXDAzMFwwMDEgXDAwMShcMDA1KlJcblwwMTNGb3JlaWduRW51bVwwMjJcMDIwXG5cMDE0Rk8iICsKICAgICAgIlJFSUdOX1pFUk9cMDIwXDAwMFwwMjJcMDE3XG5cMDEzRk9SRUlHTl9GT09cMDIwXDAwNFwwMjJcMDE3XG5cMDEzRk9SRUlHTiIgKwogICAgICAiX0JBUlwwMjBcMDA1XDAyMlwwMTdcblwwMTNGT1JFSUdOX0JBWlwwMjBcMDA2QlwwMDNcMzcwXDAwMVwwMDFiXDAwNnByb3RvMyIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LmdldERlc2NyaXB0b3IoKSwKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiT3B0aW9uYWxJbnQzMiIsICJPcHRpb25hbEludDY0IiwgIk9wdGlvbmFsVWludDMyIiwgIk9wdGlvbmFsVWludDY0IiwgIk9wdGlvbmFsU2ludDMyIiwgIk9wdGlvbmFsU2ludDY0IiwgIk9wdGlvbmFsRml4ZWQzMiIsICJPcHRpb25hbEZpeGVkNjQiLCAiT3B0aW9uYWxTZml4ZWQzMiIsICJPcHRpb25hbFNmaXhlZDY0IiwgIk9wdGlvbmFsRmxvYXQiLCAiT3B0aW9uYWxEb3VibGUiLCAiT3B0aW9uYWxCb29sIiwgIk9wdGlvbmFsU3RyaW5nIiwgIk9wdGlvbmFsQnl0ZXMiLCAiT3B0aW9uYWxOZXN0ZWRNZXNzYWdlIiwgIk9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UiLCAiT3B0aW9uYWxJbXBvcnRNZXNzYWdlIiwgIk9wdGlvbmFsTmVzdGVkRW51bSIsICJPcHRpb25hbEZvcmVpZ25FbnVtIiwgIk9wdGlvbmFsU3RyaW5nUGllY2UiLCAiT3B0aW9uYWxDb3JkIiwgIk9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSIsICJPcHRpb25hbExhenlNZXNzYWdlIiwgIk9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlIiwgIk9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UiLCAiUmVwZWF0ZWRJbnQzMiIsICJSZXBlYXRlZEludDY0IiwgIlJlcGVhdGVkVWludDMyIiwgIlJlcGVhdGVkVWludDY0IiwgIlJlcGVhdGVkU2ludDMyIiwgIlJlcGVhdGVkU2ludDY0IiwgIlJlcGVhdGVkRml4ZWQzMiIsICJSZXBlYXRlZEZpeGVkNjQiLCAiUmVwZWF0ZWRTZml4ZWQzMiIsICJSZXBlYXRlZFNmaXhlZDY0IiwgIlJlcGVhdGVkRmxvYXQiLCAiUmVwZWF0ZWREb3VibGUiLCAiUmVwZWF0ZWRCb29sIiwgIlJlcGVhdGVkU3RyaW5nIiwgIlJlcGVhdGVkQnl0ZXMiLCAiUHJvdG8zT3B0aW9uYWxJbnQzMiIsICJQcm90bzNPcHRpb25hbEludDY0IiwgIlByb3RvM09wdGlvbmFsVWludDMyIiwgIlByb3RvM09wdGlvbmFsVWludDY0IiwgIlByb3RvM09wdGlvbmFsU2ludDMyIiwgIlByb3RvM09wdGlvbmFsU2ludDY0IiwgIlByb3RvM09wdGlvbmFsRml4ZWQzMiIsICJQcm90bzNPcHRpb25hbEZpeGVkNjQiLCAiUHJvdG8zT3B0aW9uYWxTZml4ZWQzMiIsICJQcm90bzNPcHRpb25hbFNmaXhlZDY0IiwgIlByb3RvM09wdGlvbmFsRmxvYXQiLCAiUHJvdG8zT3B0aW9uYWxEb3VibGUiLCAiUHJvdG8zT3B0aW9uYWxCb29sIiwgIlByb3RvM09wdGlvbmFsU3RyaW5nIiwgIlByb3RvM09wdGlvbmFsQnl0ZXMiLCAiUmVwZWF0ZWROZXN0ZWRNZXNzYWdlIiwgIlJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UiLCAiUmVwZWF0ZWRJbXBvcnRNZXNzYWdlIiwgIlJlcGVhdGVkTmVzdGVkRW51bSIsICJSZXBlYXRlZEZvcmVpZ25FbnVtIiwgIlJlcGVhdGVkU3RyaW5nUGllY2UiLCAiUmVwZWF0ZWRDb3JkIiwgIlJlcGVhdGVkTGF6eU1lc3NhZ2UiLCAiT25lb2ZVaW50MzIiLCAiT25lb2ZOZXN0ZWRNZXNzYWdlIiwgIk9uZW9mU3RyaW5nIiwgIk9uZW9mQnl0ZXMiLCAiT25lb2ZGaWVsZCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJCYiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJQYWNrZWRJbnQzMiIsICJQYWNrZWRJbnQ2NCIsICJQYWNrZWRVaW50MzIiLCAiUGFja2VkVWludDY0IiwgIlBhY2tlZFNpbnQzMiIsICJQYWNrZWRTaW50NjQiLCAiUGFja2VkRml4ZWQzMiIsICJQYWNrZWRGaXhlZDY0IiwgIlBhY2tlZFNmaXhlZDMyIiwgIlBhY2tlZFNmaXhlZDY0IiwgIlBhY2tlZEZsb2F0IiwgIlBhY2tlZERvdWJsZSIsICJQYWNrZWRCb29sIiwgIlBhY2tlZEVudW0iLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdFVucGFja2VkVHlwZXNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUmVwZWF0ZWRJbnQzMiIsICJSZXBlYXRlZEludDY0IiwgIlJlcGVhdGVkVWludDMyIiwgIlJlcGVhdGVkVWludDY0IiwgIlJlcGVhdGVkU2ludDMyIiwgIlJlcGVhdGVkU2ludDY0IiwgIlJlcGVhdGVkRml4ZWQzMiIsICJSZXBlYXRlZEZpeGVkNjQiLCAiUmVwZWF0ZWRTZml4ZWQzMiIsICJSZXBlYXRlZFNmaXhlZDY0IiwgIlJlcGVhdGVkRmxvYXQiLCAiUmVwZWF0ZWREb3VibGUiLCAiUmVwZWF0ZWRCb29sIiwgIlJlcGVhdGVkTmVzdGVkRW51bSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9OZXN0ZWRUZXN0QWxsVHlwZXNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJDaGlsZCIsICJQYXlsb2FkIiwgIlJlcGVhdGVkQ2hpbGQiLCAiTGF6eVBheWxvYWQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkJiIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfTmVzdGVkTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19hcmVuYV91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2FyZW5hX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfTmVzdGVkTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfYXJlbmFfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9OZXN0ZWROZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJDYyIsIH0pOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LmdldERlc2NyaXB0b3IoKTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhADBFJIE0pwoANKcKACwAAABwcm90bzNfbGl0ZV91bml0dGVzdC9Vbml0dGVzdFByb3RvM0xpdGUuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3Byb3RvM19saXRlLnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90bzNfbGl0ZV91bml0dGVzdDsKCnB1YmxpYyBmaW5hbCBjbGFzcyBVbml0dGVzdFByb3RvM0xpdGUgewogIHByaXZhdGUgVW5pdHRlc3RQcm90bzNMaXRlKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bX0KICAgKi8KICBwdWJsaWMgZW51bSBGb3JlaWduRW51bQogICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAvKioKICAgICAqIDxjb2RlPkZPUkVJR05fWkVSTyA9IDA7PC9jb2RlPgogICAgICovCiAgICBGT1JFSUdOX1pFUk8oMCksCiAgICAvKioKICAgICAqIDxjb2RlPkZPUkVJR05fRk9PID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEZPUkVJR05fRk9PKDQpLAogICAgLyoqCiAgICAgKiA8Y29kZT5GT1JFSUdOX0JBUiA9IDU7PC9jb2RlPgogICAgICovCiAgICBGT1JFSUdOX0JBUig1KSwKICAgIC8qKgogICAgICogPGNvZGU+Rk9SRUlHTl9CQVogPSA2OzwvY29kZT4KICAgICAqLwogICAgRk9SRUlHTl9CQVooNiksCiAgICBVTlJFQ09HTklaRUQoLTEpLAogICAgOwoKICAgIC8qKgogICAgICogPGNvZGU+Rk9SRUlHTl9aRVJPID0gMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPUkVJR05fWkVST19WQUxVRSA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPkZPUkVJR05fRk9PID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPUkVJR05fRk9PX1ZBTFVFID0gNDsKICAgIC8qKgogICAgICogPGNvZGU+Rk9SRUlHTl9CQVIgPSA1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9SRUlHTl9CQVJfVkFMVUUgPSA1OwogICAgLyoqCiAgICAgKiA8Y29kZT5GT1JFSUdOX0JBWiA9IDY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT1JFSUdOX0JBWl9WQUxVRSA9IDY7CgoKICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgbnVtYmVyIG9mIGFuIHVua25vd24gZW51bSB2YWx1ZS4iKTsKICAgICAgfQogICAgICByZXR1cm4gdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBzdGF0aWMgRm9yZWlnbkVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBGb3JlaWduRW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICBjYXNlIDA6IHJldHVybiBGT1JFSUdOX1pFUk87CiAgICAgICAgY2FzZSA0OiByZXR1cm4gRk9SRUlHTl9GT087CiAgICAgICAgY2FzZSA1OiByZXR1cm4gRk9SRUlHTl9CQVI7CiAgICAgICAgY2FzZSA2OiByZXR1cm4gRk9SRUlHTl9CQVo7CiAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8Rm9yZWlnbkVudW0+CiAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgIEZvcmVpZ25FbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPEZvcmVpZ25FbnVtPigpIHsKICAgICAgICAgICAgcHVibGljIEZvcmVpZ25FbnVtIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gRm9yZWlnbkVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oCiAgICAgICAgICAgICJDYW4ndCBnZXQgdGhlIGRlc2NyaXB0b3Igb2YgYW4gdW5yZWNvZ25pemVkIGVudW0gdmFsdWUuIik7CiAgICAgIH0KICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgIH0KICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgRm9yZWlnbkVudW1bXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICBwdWJsaWMgc3RhdGljIEZvcmVpZ25FbnVtIHZhbHVlT2YoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgIH0KICAgICAgaWYgKGRlc2MuZ2V0SW5kZXgoKSA9PSAtMSkgewogICAgICAgIHJldHVybiBVTlJFQ09HTklaRUQ7CiAgICAgIH0KICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgfQoKICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgIHByaXZhdGUgRm9yZWlnbkVudW0oaW50IHZhbHVlKSB7CiAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSkKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBTaW5ndWxhcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+aW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBvcHRpb25hbF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbEludDY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsVWludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT51aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbFVpbnQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbFNpbnQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTaW50NjQuCiAgICAgKi8KICAgIGxvbmcgZ2V0T3B0aW9uYWxTaW50NjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxGaXhlZDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbEZpeGVkNjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxTZml4ZWQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDY0LgogICAgICovCiAgICBsb25nIGdldE9wdGlvbmFsU2ZpeGVkNjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGbG9hdC4KICAgICAqLwogICAgZmxvYXQgZ2V0T3B0aW9uYWxGbG9hdCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+ZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRG91YmxlLgogICAgICovCiAgICBkb3VibGUgZ2V0T3B0aW9uYWxEb3VibGUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQm9vbC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRPcHRpb25hbEJvb2woKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFN0cmluZ0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvcHRpb25hbF9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQnl0ZXMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZS4KICAgICAqLwogICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAqLwogICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxGb3JlaWduRW51bS4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsRm9yZWlnbkVudW1WYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGb3JlaWduRW51bS4KICAgICAqLwogICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtIGdldE9wdGlvbmFsRm9yZWlnbkVudW0oKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmdQaWVjZS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQ29yZC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbENvcmQoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxDb3JkLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbENvcmRCeXRlcygpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbExhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbExhenlNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbExhenlNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBSZXBlYXRlZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZEludDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50NjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkSW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkVWludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFVpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkVWludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDY0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UmVwZWF0ZWRVaW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkU2ludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU2ludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDY0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UmVwZWF0ZWRTaW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkNjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRSZXBlYXRlZEZpeGVkNjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNmaXhlZDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkU2ZpeGVkNjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGbG9hdC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PiBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmxvYXQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEZsb2F0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBmbG9hdCBnZXRSZXBlYXRlZEZsb2F0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWREb3VibGUuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+IGdldFJlcGVhdGVkRG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWREb3VibGUuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZERvdWJsZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZG91YmxlIGdldFJlcGVhdGVkRG91YmxlKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2wuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPiBnZXRSZXBlYXRlZEJvb2xMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQm9vbENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2woaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCeXRlcy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEJ5dGVzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQnl0ZXMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IAogICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZT4gCiAgICAgICAgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICovCiAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gCiAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IGdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bT4gZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGb3JlaWduRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bSBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFJlcGVhdGVkRm9yZWlnbkVudW1WYWx1ZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZEZvcmVpZ25FbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRm9yZWlnbkVudW1WYWx1ZShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmdQaWVjZS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZ1BpZWNlLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZENvcmQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQ29yZC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQ29yZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZENvcmQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkQ29yZChpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZENvcmQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZENvcmRCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IAogICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2UoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDExMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mVWludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPbmVvZlVpbnQzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mVWludDMyLgogICAgICovCiAgICBpbnQgZ2V0T25lb2ZVaW50MzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZOZXN0ZWRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZk5lc3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9uZW9mTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPbmVvZlN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mU3RyaW5nLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9uZW9mU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9uZW9mU3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPbmVvZlN0cmluZ0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDExNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09uZW9mQnl0ZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZCeXRlcy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9uZW9mQnl0ZXMoKTsKCiAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk9uZW9mRmllbGRDYXNlIGdldE9uZW9mRmllbGRDYXNlKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVGhpcyBwcm90byBpbmNsdWRlcyBldmVyeSB0eXBlIG9mIGZpZWxkIGluIGJvdGggc2luZ3VsYXIgYW5kIHJlcGVhdGVkCiAgICogZm9ybXMuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0QWxsVHlwZXMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzKQogICAgICBUZXN0QWxsVHlwZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0QWxsVHlwZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0QWxsVHlwZXMoKSB7CiAgICAgIG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgICBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gMDsKICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSAiIjsKICAgICAgb3B0aW9uYWxDb3JkXyA9ICIiOwogICAgICByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcmVwZWF0ZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRCeXRlc18gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkQ29yZF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0QWxsVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5jbGFzcywgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtfQogICAgICovCiAgICBwdWJsaWMgZW51bSBOZXN0ZWRFbnVtCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgICAvKioKICAgICAgICogPGNvZGU+WkVSTyA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgWkVSTygwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgRk9PKDEpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QkFSID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVIoMiksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVogPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEJBWigzKSwKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEludGVudGlvbmFsbHkgbmVnYXRpdmUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5ORUcgPSAtMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBORUcoLTEpLAogICAgICBVTlJFQ09HTklaRUQoLTEpLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+WkVSTyA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgWkVST19WQUxVRSA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19WQUxVRSA9IDE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9WQUxVRSA9IDI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVogPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBWl9WQUxVRSA9IDM7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBJbnRlbnRpb25hbGx5IG5lZ2F0aXZlLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+TkVHID0gLTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkVHX1ZBTFVFID0gLTE7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBudW1iZXIgb2YgYW4gdW5rbm93biBlbnVtIHZhbHVlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIFpFUk87CiAgICAgICAgICBjYXNlIDE6IHJldHVybiBGT087CiAgICAgICAgICBjYXNlIDI6IHJldHVybiBCQVI7CiAgICAgICAgICBjYXNlIDM6IHJldHVybiBCQVo7CiAgICAgICAgICBjYXNlIC0xOiByZXR1cm4gTkVHOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIE5lc3RlZEVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxOZXN0ZWRFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgTmVzdGVkRW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gTmVzdGVkRW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBkZXNjcmlwdG9yIG9mIGFuIHVucmVjb2duaXplZCBlbnVtIHZhbHVlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgICB9CiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBOZXN0ZWRFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICBpZiAoZGVzYy5nZXRJbmRleCgpID09IC0xKSB7CiAgICAgICAgICByZXR1cm4gVU5SRUNPR05JWkVEOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBOZXN0ZWRFbnVtKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0pCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPmludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJiLgogICAgICAgKi8KICAgICAgaW50IGdldEJiKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZE1lc3NhZ2UgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKQogICAgICAgIE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBOZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgTmVzdGVkTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQl9GSUVMRF9OVU1CRVIgPSAxOwogICAgICBwcml2YXRlIGludCBiYl8gPSAwOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICogVGhpcyBmaWxlIG5lZWRzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIHRvIHRlc3QgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5pbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBiYi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRCYigpIHsKICAgICAgICByZXR1cm4gYmJfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChiYl8gIT0gMCkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgYmJfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKGJiXyAhPSAwKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgYmJfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICAgIGlmIChnZXRCYigpCiAgICAgICAgICAgICE9IG90aGVyLmdldEJiKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEJiKCk7CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkKICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuY2xhc3MsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBiYl8gPSAwOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LmJiXyA9IGJiXzsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Upb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5nZXRCYigpICE9IDApIHsKICAgICAgICAgICAgc2V0QmIob3RoZXIuZ2V0QmIoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgICAgYmJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBpbnQgYmJfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIDxjb2RlPmludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgYmIuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0QmIoKSB7CiAgICAgICAgICByZXR1cm4gYmJfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIDxjb2RlPmludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBiYiB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJiKGludCB2YWx1ZSkgewoKICAgICAgICAgIGJiXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPHByZT4KICAgICAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICAgICAqIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCiAgICAgICAgICogVGhpcyBmaWxlIG5lZWRzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIHRvIHRlc3QgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICoKICAgICAgICAgKiA8Y29kZT5pbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJiKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgYmJfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkTWVzc2FnZT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBOZXN0ZWRNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHByaXZhdGUgaW50IG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBvbmVvZkZpZWxkXzsKICAgIHB1YmxpYyBlbnVtIE9uZW9mRmllbGRDYXNlCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZS5JbnRlcm5hbE9uZU9mRW51bSB7CiAgICAgIE9ORU9GX1VJTlQzMigxMTEpLAogICAgICBPTkVPRl9ORVNURURfTUVTU0FHRSgxMTIpLAogICAgICBPTkVPRl9TVFJJTkcoMTEzKSwKICAgICAgT05FT0ZfQllURVMoMTE0KSwKICAgICAgT05FT0ZGSUVMRF9OT1RfU0VUKDApOwogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKICAgICAgcHJpdmF0ZSBPbmVvZkZpZWxkQ2FzZShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtYmVyIG9mIHRoZSBlbnVtIHRvIGxvb2sgZm9yLgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtYmVyLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIE9uZW9mRmllbGRDYXNlIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgT25lb2ZGaWVsZENhc2UgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMTExOiByZXR1cm4gT05FT0ZfVUlOVDMyOwogICAgICAgICAgY2FzZSAxMTI6IHJldHVybiBPTkVPRl9ORVNURURfTUVTU0FHRTsKICAgICAgICAgIGNhc2UgMTEzOiByZXR1cm4gT05FT0ZfU1RSSU5HOwogICAgICAgICAgY2FzZSAxMTQ6IHJldHVybiBPTkVPRl9CWVRFUzsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIE9ORU9GRklFTERfTk9UX1NFVDsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgT25lb2ZGaWVsZENhc2UKICAgIGdldE9uZW9mRmllbGRDYXNlKCkgewogICAgICByZXR1cm4gT25lb2ZGaWVsZENhc2UuZm9yTnVtYmVyKAogICAgICAgICAgb25lb2ZGaWVsZENhc2VfKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogU2luZ3VsYXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPmludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQ2NF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsSW50NjRfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPmludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbEludDY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQ2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UNjRfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFVpbnQ2NF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+dWludDY0IG9wdGlvbmFsX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsVWludDY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxVaW50NjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NJTlQzMl9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTaW50MzJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+c2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxTaW50MzIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFNpbnQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0lOVDY0X0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxTaW50NjRfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQ2NCBvcHRpb25hbF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbFNpbnQ2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsU2ludDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9GSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEZpeGVkMzJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZpeGVkMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxGaXhlZDMyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGaXhlZDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9GSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDg7CiAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxGaXhlZDY0XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxGaXhlZDY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGaXhlZDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZml4ZWQzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5zZml4ZWQzMiBvcHRpb25hbF9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFNmaXhlZDMyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxTZml4ZWQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0ZJWEVENjRfRklFTERfTlVNQkVSID0gMTA7CiAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxTZml4ZWQ2NF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbFNmaXhlZDY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxTZml4ZWQ2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRkxPQVRfRklFTERfTlVNQkVSID0gMTE7CiAgICBwcml2YXRlIGZsb2F0IG9wdGlvbmFsRmxvYXRfID0gMEY7CiAgICAvKioKICAgICAqIDxjb2RlPmZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGbG9hdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldE9wdGlvbmFsRmxvYXQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEZsb2F0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9ET1VCTEVfRklFTERfTlVNQkVSID0gMTI7CiAgICBwcml2YXRlIGRvdWJsZSBvcHRpb25hbERvdWJsZV8gPSAwRDsKICAgIC8qKgogICAgICogPGNvZGU+ZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRG91YmxlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldE9wdGlvbmFsRG91YmxlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxEb3VibGVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0JPT0xfRklFTERfTlVNQkVSID0gMTM7CiAgICBwcml2YXRlIGJvb2xlYW4gb3B0aW9uYWxCb29sXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8Y29kZT5ib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJvb2wuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldE9wdGlvbmFsQm9vbCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsQm9vbF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDE0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gczsKICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0JZVEVTX0ZJRUxEX05VTUJFUiA9IDE1OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgb3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxCeXRlc187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTg7CiAgICBwcml2YXRlIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRk9SRUlHTl9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDE5OwogICAgcHJpdmF0ZSBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxGb3JlaWduTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25NZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyA9PSBudWxsID8gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxGb3JlaWduTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID09IG51bGwgPyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAyMDsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxJbXBvcnRNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEltcG9ydE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbXBvcnRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEltcG9ydE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsSW1wb3J0TWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSID0gMjE7CiAgICBwcml2YXRlIGludCBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGludCBnZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkRW51bV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlc3VsdCA9IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5mb3JOdW1iZXIob3B0aW9uYWxOZXN0ZWRFbnVtXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRk9SRUlHTl9FTlVNX0ZJRUxEX05VTUJFUiA9IDIyOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxGb3JlaWduRW51bV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxGb3JlaWduRW51bVZhbHVlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduRW51bV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbkVudW0gZ2V0T3B0aW9uYWxGb3JlaWduRW51bSgpIHsKICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtIHJlc3VsdCA9IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bS5mb3JOdW1iZXIob3B0aW9uYWxGb3JlaWduRW51bV8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbkVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NUUklOR19QSUVDRV9GSUVMRF9OVU1CRVIgPSAyNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsU3RyaW5nUGllY2VfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nUGllY2UoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdQaWVjZV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IHM7CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFN0cmluZ1BpZWNlQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdQaWVjZV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQ09SRF9GSUVMRF9OVU1CRVIgPSAyNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsQ29yZF8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbENvcmQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsQ29yZCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbENvcmRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgb3B0aW9uYWxDb3JkXyA9IHM7CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxDb3JkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxDb3JkQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxDb3JkXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0aW9uYWxDb3JkXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1BVQkxJQ19JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAyNjsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXzsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDI3OwogICAgcHJpdmF0ZSBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxMYXp5TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxMYXp5TWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID09IG51bGwgPyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAzMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRJbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUmVwZWF0ZWQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkSW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBSZXBlYXRlZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDMyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRJbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+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+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdldFJlcGVhdGVkQm9vbChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDQ0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZ18gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZy4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZ0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQllURVNfRklFTERfTlVNQkVSID0gNDU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiByZXBlYXRlZEJ5dGVzXyA9CiAgICAgICAgZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCeXRlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCeXRlc0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCeXRlcyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gNDg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRk9SRUlHTl9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDQ5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZT4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2U+IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSA1MDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2U+IGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSID0gNTE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkTmVzdGVkRW51bV87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVzdWx0ID0gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IGdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+KHJlcGVhdGVkTmVzdGVkRW51bV8sIHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRSZXBlYXRlZE5lc3RlZEVudW0oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZE5lc3RlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0ZPUkVJR05fRU5VTV9GSUVMRF9OVU1CRVIgPSA1MjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWRGb3JlaWduRW51bV87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtPiByZXBlYXRlZEZvcmVpZ25FbnVtX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtIHJlc3VsdCA9IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbkVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbkVudW0+IGdldFJlcGVhdGVkRm9yZWlnbkVudW1MaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtPihyZXBlYXRlZEZvcmVpZ25FbnVtXywgcmVwZWF0ZWRGb3JlaWduRW51bV9jb252ZXJ0ZXJfKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bSBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRGb3JlaWduRW51bV8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWVMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcmVwZWF0ZWRGb3JlaWduRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGb3JlaWduRW51bVZhbHVlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHJlcGVhdGVkRm9yZWlnbkVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR19QSUVDRV9GSUVMRF9OVU1CRVIgPSA1NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmdQaWVjZV8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmdQaWVjZS4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmdQaWVjZS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nUGllY2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9DT1JEX0ZJRUxEX05VTUJFUiA9IDU1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZENvcmRfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRDb3JkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZENvcmRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZENvcmQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRDb3JkQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZENvcmRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQ29yZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkQ29yZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZF8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRDb3JkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkQ29yZEJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9MQVpZX01FU1NBR0VfRklFTERfTlVNQkVSID0gNTc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiByZXBlYXRlZExhenlNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiBnZXRSZXBlYXRlZExhenlNZXNzYWdlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZExhenlNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZExhenlNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9VSU5UMzJfRklFTERfTlVNQkVSID0gMTExOwogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZVaW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlVpbnQzMigpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTE7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZVaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T25lb2ZVaW50MzIoKSB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTExKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FT0ZfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTEyOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZk5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZk5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9uZW9mTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICAgcmV0dXJuIChwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICByZXR1cm4gKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgcmV0dXJuIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9TVFJJTkdfRklFTERfTlVNQkVSID0gMTEzOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlN0cmluZygpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZTdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9uZW9mU3RyaW5nKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvbmVvZlN0cmluZy4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9uZW9mU3RyaW5nQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX0JZVEVTX0ZJRUxEX05VTUJFUiA9IDExNDsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZkJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZCeXRlcygpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTQ7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mQnl0ZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T25lb2ZCeXRlcygpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTQpIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIGlmIChvcHRpb25hbEludDMyXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgb3B0aW9uYWxJbnQzMl8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEludDY0XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDIsIG9wdGlvbmFsSW50NjRfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxVaW50MzJfICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoMywgb3B0aW9uYWxVaW50MzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxVaW50NjRfICE9IDBMKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDY0KDQsIG9wdGlvbmFsVWludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ludDMyXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyKDUsIG9wdGlvbmFsU2ludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ludDY0XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NCg2LCBvcHRpb25hbFNpbnQ2NF8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEZpeGVkMzJfICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDMyKDcsIG9wdGlvbmFsRml4ZWQzMl8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEZpeGVkNjRfICE9IDBMKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NCg4LCBvcHRpb25hbEZpeGVkNjRfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxTZml4ZWQzMl8gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyKDksIG9wdGlvbmFsU2ZpeGVkMzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxTZml4ZWQ2NF8gIT0gMEwpIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQ2NCgxMCwgb3B0aW9uYWxTZml4ZWQ2NF8pOwogICAgICB9CiAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMob3B0aW9uYWxGbG9hdF8pICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdCgxMSwgb3B0aW9uYWxGbG9hdF8pOwogICAgICB9CiAgICAgIGlmIChqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMob3B0aW9uYWxEb3VibGVfKSAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKDEyLCBvcHRpb25hbERvdWJsZV8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEJvb2xfICE9IGZhbHNlKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgxMywgb3B0aW9uYWxCb29sXyk7CiAgICAgIH0KICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KG9wdGlvbmFsU3RyaW5nXykpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDE0LCBvcHRpb25hbFN0cmluZ18pOwogICAgICB9CiAgICAgIGlmICghb3B0aW9uYWxCeXRlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMTUsIG9wdGlvbmFsQnl0ZXNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDE4LCBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxOSwgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIwLCBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkRW51bV8gIT0gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDIxLCBvcHRpb25hbE5lc3RlZEVudW1fKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxGb3JlaWduRW51bV8gIT0gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtLkZPUkVJR05fWkVSTy5nZXROdW1iZXIoKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMjIsIG9wdGlvbmFsRm9yZWlnbkVudW1fKTsKICAgICAgfQogICAgICBpZiAoIWNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmlzU3RyaW5nRW1wdHkob3B0aW9uYWxTdHJpbmdQaWVjZV8pKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyNCwgb3B0aW9uYWxTdHJpbmdQaWVjZV8pOwogICAgICB9CiAgICAgIGlmICghY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuaXNTdHJpbmdFbXB0eShvcHRpb25hbENvcmRfKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjUsIG9wdGlvbmFsQ29yZF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMjYsIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDI3LCBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEludDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyNTApOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkSW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzJOb1RhZyhyZXBlYXRlZEludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEludDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyNTgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkSW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjROb1RhZyhyZXBlYXRlZEludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI2Nik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRVaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkVWludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjc0KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZFVpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRVaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDY0Tm9UYWcocmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjgyKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZFNpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyTm9UYWcocmVwZWF0ZWRTaW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2ludDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyOTApOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkU2ludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50NjROb1RhZyhyZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjk4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRml4ZWQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDMyTm9UYWcocmVwZWF0ZWRGaXhlZDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMwNik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRGaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZpeGVkNjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NE5vVGFnKHJlcGVhdGVkRml4ZWQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMxNCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRTZml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTZml4ZWQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQzMk5vVGFnKHJlcGVhdGVkU2ZpeGVkMzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDMyMik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRTZml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTZml4ZWQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQ2NE5vVGFnKHJlcGVhdGVkU2ZpeGVkNjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZsb2F0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMzApOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkRmxvYXRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRmxvYXRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXROb1RhZyhyZXBlYXRlZEZsb2F0Xy5nZXRGbG9hdChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRG91YmxlTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMzgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkRG91YmxlTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZERvdWJsZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVEb3VibGVOb1RhZyhyZXBlYXRlZERvdWJsZV8uZ2V0RG91YmxlKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRCb29sTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzNDYpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkQm9vbE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRCb29sXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJvb2xOb1RhZyhyZXBlYXRlZEJvb2xfLmdldEJvb2xlYW4oaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA0NCwgcmVwZWF0ZWRTdHJpbmdfLmdldFJhdyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEJ5dGVzXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDQ1LCByZXBlYXRlZEJ5dGVzXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNDgsIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg0OSwgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDUwLCByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNDEwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZE5lc3RlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZvcmVpZ25FbnVtTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg0MTgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkRm9yZWlnbkVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRm9yZWlnbkVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bU5vVGFnKHJlcGVhdGVkRm9yZWlnbkVudW1fLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZ1BpZWNlXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNTQsIHJlcGVhdGVkU3RyaW5nUGllY2VfLmdldFJhdyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZENvcmRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA1NSwgcmVwZWF0ZWRDb3JkXy5nZXRSYXcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDU3LCByZXBlYXRlZExhenlNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTExKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKAogICAgICAgICAgICAxMTEsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF8pKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTEyLCAocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDExMywgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0KSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoCiAgICAgICAgICAgIDExNCwgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAob3B0aW9uYWxJbnQzMl8gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgb3B0aW9uYWxJbnQzMl8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEludDY0XyAhPSAwTCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemUoMiwgb3B0aW9uYWxJbnQ2NF8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbFVpbnQzMl8gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKDMsIG9wdGlvbmFsVWludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsVWludDY0XyAhPSAwTCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplKDQsIG9wdGlvbmFsVWludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ludDMyXyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemUoNSwgb3B0aW9uYWxTaW50MzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxTaW50NjRfICE9IDBMKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemUoNiwgb3B0aW9uYWxTaW50NjRfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxGaXhlZDMyXyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkMzJTaXplKDcsIG9wdGlvbmFsRml4ZWQzMl8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEZpeGVkNjRfICE9IDBMKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkNjRTaXplKDgsIG9wdGlvbmFsRml4ZWQ2NF8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbFNmaXhlZDMyXyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDMyU2l6ZSg5LCBvcHRpb25hbFNmaXhlZDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ZpeGVkNjRfICE9IDBMKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDY0U2l6ZSgxMCwgb3B0aW9uYWxTZml4ZWQ2NF8pOwogICAgICB9CiAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb1Jhd0ludEJpdHMob3B0aW9uYWxGbG9hdF8pICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRmxvYXRTaXplKDExLCBvcHRpb25hbEZsb2F0Xyk7CiAgICAgIH0KICAgICAgaWYgKGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9SYXdMb25nQml0cyhvcHRpb25hbERvdWJsZV8pICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRG91YmxlU2l6ZSgxMiwgb3B0aW9uYWxEb3VibGVfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxCb29sXyAhPSBmYWxzZSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSgxMywgb3B0aW9uYWxCb29sXyk7CiAgICAgIH0KICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KG9wdGlvbmFsU3RyaW5nXykpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDE0LCBvcHRpb25hbFN0cmluZ18pOwogICAgICB9CiAgICAgIGlmICghb3B0aW9uYWxCeXRlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgxNSwgb3B0aW9uYWxCeXRlc18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOCwgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOSwgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAsIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxOZXN0ZWRFbnVtXyAhPSBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uWkVSTy5nZXROdW1iZXIoKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSgyMSwgb3B0aW9uYWxOZXN0ZWRFbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbkVudW1fICE9IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bS5GT1JFSUdOX1pFUk8uZ2V0TnVtYmVyKCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMjIsIG9wdGlvbmFsRm9yZWlnbkVudW1fKTsKICAgICAgfQogICAgICBpZiAoIWNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmlzU3RyaW5nRW1wdHkob3B0aW9uYWxTdHJpbmdQaWVjZV8pKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyNCwgb3B0aW9uYWxTdHJpbmdQaWVjZV8pOwogICAgICB9CiAgICAgIGlmICghY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuaXNTdHJpbmdFbXB0eShvcHRpb25hbENvcmRfKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMjUsIG9wdGlvbmFsQ29yZF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyNiwgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyNywgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcocmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkSW50MzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplTm9UYWcocmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkSW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcocmVwZWF0ZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZFVpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZFVpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemVOb1RhZyhyZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkU2ludDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkU2ludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZU5vVGFnKHJlcGVhdGVkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkU2ludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkU2ludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZEZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkRml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZFNmaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkRmxvYXRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRGbG9hdE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkRG91YmxlTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkRG91YmxlTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gMSAqIGdldFJlcGVhdGVkQm9vbExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkQm9vbExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZ18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmdfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRTdHJpbmdMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemVOb1RhZyhyZXBlYXRlZEJ5dGVzXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkQnl0ZXNMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0OCwgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDksIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUwLCByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkuaXNFbXB0eSgpKSB7ICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH1yZXBlYXRlZE5lc3RlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZvcmVpZ25FbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocmVwZWF0ZWRGb3JlaWduRW51bV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkRm9yZWlnbkVudW1MaXN0KCkuaXNFbXB0eSgpKSB7ICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH1yZXBlYXRlZEZvcmVpZ25FbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmdQaWVjZV8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQ29yZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRDb3JkXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkQ29yZExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZExhenlNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1NywgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKAogICAgICAgICAgICAgIDExMSwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSBvbmVvZkZpZWxkXykpOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExMiwgKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxMTMsIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemUoCiAgICAgICAgICAgICAgMTE0LCAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyBvdGhlciA9IChwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzKSBvYmo7CgogICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMigpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsSW50NjQoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQzMigpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFVpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQ2NCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFVpbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbFNpbnQzMigpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFNpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbFNpbnQ2NCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFNpbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbEZpeGVkMzIoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxGaXhlZDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsRml4ZWQ2NCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEZpeGVkNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0T3B0aW9uYWxTZml4ZWQzMigpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFNmaXhlZDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsU2ZpeGVkNjQoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0T3B0aW9uYWxGbG9hdCgpKQogICAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICAgIG90aGVyLmdldE9wdGlvbmFsRmxvYXQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRPcHRpb25hbERvdWJsZSgpKQogICAgICAgICAgIT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKAogICAgICAgICAgICAgIG90aGVyLmdldE9wdGlvbmFsRG91YmxlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbEJvb2woKQogICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxCb29sKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRPcHRpb25hbFN0cmluZygpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsU3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0T3B0aW9uYWxCeXRlcygpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsQnl0ZXMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxOZXN0ZWRFbnVtXyAhPSBvdGhlci5vcHRpb25hbE5lc3RlZEVudW1fKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25FbnVtXyAhPSBvdGhlci5vcHRpb25hbEZvcmVpZ25FbnVtXykgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldE9wdGlvbmFsU3RyaW5nUGllY2UoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbFN0cmluZ1BpZWNlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0T3B0aW9uYWxDb3JkKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxDb3JkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSAhPSBvdGhlci5oYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSAhPSBvdGhlci5oYXNPcHRpb25hbExhenlNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkSW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZsb2F0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRmxvYXRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRCb29sTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQm9vbExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZ0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQnl0ZXNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFyZXBlYXRlZE5lc3RlZEVudW1fLmVxdWFscyhvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXJlcGVhdGVkRm9yZWlnbkVudW1fLmVxdWFscyhvdGhlci5yZXBlYXRlZEZvcmVpZ25FbnVtXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nUGllY2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQ29yZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZExhenlNZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkTGF6eU1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0T25lb2ZGaWVsZENhc2UoKS5lcXVhbHMob3RoZXIuZ2V0T25lb2ZGaWVsZENhc2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgc3dpdGNoIChvbmVvZkZpZWxkQ2FzZV8pIHsKICAgICAgICBjYXNlIDExMToKICAgICAgICAgIGlmIChnZXRPbmVvZlVpbnQzMigpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T25lb2ZVaW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMTI6CiAgICAgICAgICBpZiAoIWdldE9uZW9mTmVzdGVkTWVzc2FnZSgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTEzOgogICAgICAgICAgaWYgKCFnZXRPbmVvZlN0cmluZygpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPbmVvZlN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMTQ6CiAgICAgICAgICBpZiAoIWdldE9uZW9mQnl0ZXMoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T25lb2ZCeXRlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzIoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0T3B0aW9uYWxJbnQ2NCgpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxVaW50MzIoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgIGdldE9wdGlvbmFsVWludDY0KCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TSU5UMzJfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFNpbnQzMigpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TSU5UNjRfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0T3B0aW9uYWxTaW50NjQoKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEZpeGVkMzIoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBnZXRPcHRpb25hbEZpeGVkNjQoKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1NGSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxTZml4ZWQzMigpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBnZXRPcHRpb25hbFNmaXhlZDY0KCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9GTE9BVF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgIGdldE9wdGlvbmFsRmxvYXQoKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0T3B0aW9uYWxEb3VibGUoKSkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9CT09MX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgIGdldE9wdGlvbmFsQm9vbCgpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9CWVRFU19GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRk9SRUlHTl9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIG9wdGlvbmFsTmVzdGVkRW51bV87CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0ZPUkVJR05fRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIG9wdGlvbmFsRm9yZWlnbkVudW1fOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TVFJJTkdfUElFQ0VfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFN0cmluZ1BpZWNlKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfQ09SRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsQ29yZCgpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1BVQkxJQ19JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRCb29sQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9CT09MX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEJvb2xMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmdDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmdMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRCeXRlc0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQllURVNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkQnl0ZXNMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZPUkVJR05fTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0lNUE9SVF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcmVwZWF0ZWROZXN0ZWRFbnVtXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZvcmVpZ25FbnVtQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GT1JFSUdOX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkRm9yZWlnbkVudW1fLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nUGllY2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR19QSUVDRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZENvcmRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0NPUkRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkQ29yZExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZExhenlNZXNzYWdlQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9MQVpZX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBzd2l0Y2ggKG9uZW9mRmllbGRDYXNlXykgewogICAgICAgIGNhc2UgMTExOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mVWludDMyKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDExMjoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9ORU9GX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mTmVzdGVkTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDExMzoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9ORU9GX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPbmVvZlN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDExNDoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9ORU9GX0JZVEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhpcyBwcm90byBpbmNsdWRlcyBldmVyeSB0eXBlIG9mIGZpZWxkIGluIGJvdGggc2luZ3VsYXIgYW5kIHJlcGVhdGVkCiAgICAgKiBmb3Jtcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcykKICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuY2xhc3MsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBiaXRGaWVsZDFfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyXyA9IDA7CiAgICAgICAgb3B0aW9uYWxJbnQ2NF8gPSAwTDsKICAgICAgICBvcHRpb25hbFVpbnQzMl8gPSAwOwogICAgICAgIG9wdGlvbmFsVWludDY0XyA9IDBMOwogICAgICAgIG9wdGlvbmFsU2ludDMyXyA9IDA7CiAgICAgICAgb3B0aW9uYWxTaW50NjRfID0gMEw7CiAgICAgICAgb3B0aW9uYWxGaXhlZDMyXyA9IDA7CiAgICAgICAgb3B0aW9uYWxGaXhlZDY0XyA9IDBMOwogICAgICAgIG9wdGlvbmFsU2ZpeGVkMzJfID0gMDsKICAgICAgICBvcHRpb25hbFNmaXhlZDY0XyA9IDBMOwogICAgICAgIG9wdGlvbmFsRmxvYXRfID0gMEY7CiAgICAgICAgb3B0aW9uYWxEb3VibGVfID0gMEQ7CiAgICAgICAgb3B0aW9uYWxCb29sXyA9IGZhbHNlOwogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgICAgIG9wdGlvbmFsQnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgICAgICBvcHRpb25hbEZvcmVpZ25FbnVtXyA9IDA7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSAiIjsKICAgICAgICBvcHRpb25hbENvcmRfID0gIiI7CiAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZEJ5dGVzXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRDb3JkXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzIGJ1aWxkKCkgewogICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzIHJlc3VsdCA9IG5ldyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQxXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDEocmVzdWx0KTsgfQogICAgICAgIGJ1aWxkUGFydGlhbE9uZW9mcyhyZXN1bHQpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyByZXN1bHQpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwODApOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8pOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8pOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IHJlcGVhdGVkSW1wb3J0TWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5yZXBlYXRlZE5lc3RlZEVudW1fID0gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRGb3JlaWduRW51bV8pOwogICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA4MDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQucmVwZWF0ZWRGb3JlaWduRW51bV8gPSByZXBlYXRlZEZvcmVpZ25FbnVtXzsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTGF6eU1lc3NhZ2VfKTsKICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDQwMDApOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gcmVwZWF0ZWRMYXp5TWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZExhenlNZXNzYWdlXyA9IHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzJfID0gb3B0aW9uYWxJbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQ2NF8gPSBvcHRpb25hbEludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMl8gPSBvcHRpb25hbFVpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxVaW50NjRfID0gb3B0aW9uYWxVaW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsU2ludDMyXyA9IG9wdGlvbmFsU2ludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFNpbnQ2NF8gPSBvcHRpb25hbFNpbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxGaXhlZDMyXyA9IG9wdGlvbmFsRml4ZWQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxGaXhlZDY0XyA9IG9wdGlvbmFsRml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTZml4ZWQzMl8gPSBvcHRpb25hbFNmaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFNmaXhlZDY0XyA9IG9wdGlvbmFsU2ZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRmxvYXRfID0gb3B0aW9uYWxGbG9hdF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxEb3VibGVfID0gb3B0aW9uYWxEb3VibGVfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsQm9vbF8gPSBvcHRpb25hbEJvb2xfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsU3RyaW5nXyA9IG9wdGlvbmFsU3RyaW5nXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEJ5dGVzXyA9IG9wdGlvbmFsQnl0ZXNfOwogICAgICAgIH0KICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXwogICAgICAgICAgICAgIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEZvcmVpZ25NZXNzYWdlXyA9IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXwogICAgICAgICAgICAgIDogb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9IG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxOZXN0ZWRFbnVtXyA9IG9wdGlvbmFsTmVzdGVkRW51bV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxGb3JlaWduRW51bV8gPSBvcHRpb25hbEZvcmVpZ25FbnVtXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFN0cmluZ1BpZWNlXyA9IG9wdGlvbmFsU3RyaW5nUGllY2VfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsQ29yZF8gPSBvcHRpb25hbENvcmRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsTGF6eU1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEludDMyXyA9IHJlcGVhdGVkSW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW50NjRfID0gcmVwZWF0ZWRJbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkVWludDMyXyA9IHJlcGVhdGVkVWludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRVaW50NjRfID0gcmVwZWF0ZWRVaW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNpbnQzMl8gPSByZXBlYXRlZFNpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2ludDY0XyA9IHJlcGVhdGVkU2ludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRml4ZWQzMl8gPSByZXBlYXRlZEZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRGaXhlZDY0XyA9IHJlcGVhdGVkRml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwxKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQxXyA9IGJpdEZpZWxkMV87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNmaXhlZDMyXyA9IHJlcGVhdGVkU2ZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2ZpeGVkNjRfID0gcmVwZWF0ZWRTZml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRGbG9hdF8gPSByZXBlYXRlZEZsb2F0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWREb3VibGVfID0gcmVwZWF0ZWREb3VibGVfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRCb29sXyA9IHJlcGVhdGVkQm9vbF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nXyA9IHJlcGVhdGVkU3RyaW5nXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQnl0ZXNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEJ5dGVzXyA9IHJlcGVhdGVkQnl0ZXNfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nUGllY2VfID0gcmVwZWF0ZWRTdHJpbmdQaWVjZV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZENvcmRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZENvcmRfID0gcmVwZWF0ZWRDb3JkXzsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxPbmVvZnMocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyByZXN1bHQpIHsKICAgICAgICByZXN1bHQub25lb2ZGaWVsZENhc2VfID0gb25lb2ZGaWVsZENhc2VfOwogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IHRoaXMub25lb2ZGaWVsZF87CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIgJiYKICAgICAgICAgICAgb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRfID0gb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsSW50MzIoKSAhPSAwKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyKG90aGVyLmdldE9wdGlvbmFsSW50MzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbEludDY0KCkgIT0gMEwpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50NjQob3RoZXIuZ2V0T3B0aW9uYWxJbnQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsVWludDMyKCkgIT0gMCkgewogICAgICAgICAgc2V0T3B0aW9uYWxVaW50MzIob3RoZXIuZ2V0T3B0aW9uYWxVaW50MzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbFVpbnQ2NCgpICE9IDBMKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFVpbnQ2NChvdGhlci5nZXRPcHRpb25hbFVpbnQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsU2ludDMyKCkgIT0gMCkgewogICAgICAgICAgc2V0T3B0aW9uYWxTaW50MzIob3RoZXIuZ2V0T3B0aW9uYWxTaW50MzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbFNpbnQ2NCgpICE9IDBMKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFNpbnQ2NChvdGhlci5nZXRPcHRpb25hbFNpbnQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsRml4ZWQzMigpICE9IDApIHsKICAgICAgICAgIHNldE9wdGlvbmFsRml4ZWQzMihvdGhlci5nZXRPcHRpb25hbEZpeGVkMzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbEZpeGVkNjQoKSAhPSAwTCkgewogICAgICAgICAgc2V0T3B0aW9uYWxGaXhlZDY0KG90aGVyLmdldE9wdGlvbmFsRml4ZWQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsU2ZpeGVkMzIoKSAhPSAwKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFNmaXhlZDMyKG90aGVyLmdldE9wdGlvbmFsU2ZpeGVkMzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbFNmaXhlZDY0KCkgIT0gMEwpIHsKICAgICAgICAgIHNldE9wdGlvbmFsU2ZpeGVkNjQob3RoZXIuZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsRmxvYXQoKSAhPSAwRikgewogICAgICAgICAgc2V0T3B0aW9uYWxGbG9hdChvdGhlci5nZXRPcHRpb25hbEZsb2F0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxEb3VibGUoKSAhPSAwRCkgewogICAgICAgICAgc2V0T3B0aW9uYWxEb3VibGUob3RoZXIuZ2V0T3B0aW9uYWxEb3VibGUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbEJvb2woKSAhPSBmYWxzZSkgewogICAgICAgICAgc2V0T3B0aW9uYWxCb29sKG90aGVyLmdldE9wdGlvbmFsQm9vbCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5nZXRPcHRpb25hbFN0cmluZygpLmlzRW1wdHkoKSkgewogICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gb3RoZXIub3B0aW9uYWxTdHJpbmdfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbEJ5dGVzKCkgIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEJ5dGVzKG90aGVyLmdldE9wdGlvbmFsQnl0ZXMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbE5lc3RlZE1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsRm9yZWlnbk1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsSW1wb3J0TWVzc2FnZShvdGhlci5nZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5vcHRpb25hbE5lc3RlZEVudW1fICE9IDApIHsKICAgICAgICAgIHNldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIub3B0aW9uYWxGb3JlaWduRW51bV8gIT0gMCkgewogICAgICAgICAgc2V0T3B0aW9uYWxGb3JlaWduRW51bVZhbHVlKG90aGVyLmdldE9wdGlvbmFsRm9yZWlnbkVudW1WYWx1ZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5nZXRPcHRpb25hbFN0cmluZ1BpZWNlKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IG90aGVyLm9wdGlvbmFsU3RyaW5nUGllY2VfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIuZ2V0T3B0aW9uYWxDb3JkKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBvcHRpb25hbENvcmRfID0gb3RoZXIub3B0aW9uYWxDb3JkXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbExhenlNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRJbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfID0gb3RoZXIucmVwZWF0ZWRJbnQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRJbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRJbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfID0gb3RoZXIucmVwZWF0ZWRJbnQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRJbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRVaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkVWludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gb3RoZXIucmVwZWF0ZWRVaW50MzJfOwogICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkVWludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFVpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRVaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBvdGhlci5yZXBlYXRlZFVpbnQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRVaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2ludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IG90aGVyLnJlcGVhdGVkU2ludDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNpbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gb3RoZXIucmVwZWF0ZWRTaW50NjRfOwogICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBvdGhlci5yZXBlYXRlZEZpeGVkMzJfOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRml4ZWQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gb3RoZXIucmVwZWF0ZWRGaXhlZDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEZpeGVkNjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2ZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IG90aGVyLnJlcGVhdGVkU2ZpeGVkMzJfOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ZpeGVkMzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2ZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IG90aGVyLnJlcGVhdGVkU2ZpeGVkNjRfOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ZpeGVkNjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRmxvYXRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRmxvYXRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEZsb2F0XyA9IG90aGVyLnJlcGVhdGVkRmxvYXRfOwogICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRmxvYXRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRG91YmxlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZERvdWJsZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IG90aGVyLnJlcGVhdGVkRG91YmxlXzsKICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfLmFkZEFsbChvdGhlci5yZXBlYXRlZERvdWJsZV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRCb29sXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEJvb2xfID0gb3RoZXIucmVwZWF0ZWRCb29sXzsKICAgICAgICAgICAgcmVwZWF0ZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEFsbChvdGhlci5yZXBlYXRlZEJvb2xfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFN0cmluZ18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nXzsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmdfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZ18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRCeXRlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRCeXRlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQnl0ZXNfID0gb3RoZXIucmVwZWF0ZWRCeXRlc187CiAgICAgICAgICAgIHJlcGVhdGVkQnl0ZXNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEJ5dGVzXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRCeXRlc18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZEFsbChvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRGb3JlaWduTWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAxMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIucmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZEltcG9ydE1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmFkZEFsbChvdGhlci5yZXBlYXRlZEltcG9ydE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRJbXBvcnRNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkSW1wb3J0TWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gb3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA0MDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGb3JlaWduRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fID0gb3RoZXIucmVwZWF0ZWRGb3JlaWduRW51bV87CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbkVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRm9yZWlnbkVudW1fKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nUGllY2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU3RyaW5nUGllY2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nUGllY2VfOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZ1BpZWNlXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZENvcmRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkQ29yZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQ29yZF8gPSBvdGhlci5yZXBlYXRlZENvcmRfOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZENvcmRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRDb3JkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRDb3JkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTGF6eU1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZExhenlNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmFkZEFsbChvdGhlci5yZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRMYXp5TWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRMYXp5TWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDQwMDApOwogICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc3dpdGNoIChvdGhlci5nZXRPbmVvZkZpZWxkQ2FzZSgpKSB7CiAgICAgICAgICBjYXNlIE9ORU9GX1VJTlQzMjogewogICAgICAgICAgICBzZXRPbmVvZlVpbnQzMihvdGhlci5nZXRPbmVvZlVpbnQzMigpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GX05FU1RFRF9NRVNTQUdFOiB7CiAgICAgICAgICAgIG1lcmdlT25lb2ZOZXN0ZWRNZXNzYWdlKG90aGVyLmdldE9uZW9mTmVzdGVkTWVzc2FnZSgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GX1NUUklORzogewogICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTM7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gb3RoZXIub25lb2ZGaWVsZF87CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgT05FT0ZfQllURVM6IHsKICAgICAgICAgICAgc2V0T25lb2ZCeXRlcyhvdGhlci5nZXRPbmVvZkJ5dGVzKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgT05FT0ZGSUVMRF9OT1RfU0VUOiB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50NjRfID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFVpbnQzMl8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQKICAgICAgICAgICAgICBjYXNlIDMyOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFVpbnQ2NF8gPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIKICAgICAgICAgICAgICBjYXNlIDQwOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFNpbnQzMl8gPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAKICAgICAgICAgICAgICBjYXNlIDQ4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFNpbnQ2NF8gPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDgKICAgICAgICAgICAgICBjYXNlIDYxOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEZpeGVkMzJfID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MQogICAgICAgICAgICAgIGNhc2UgNjU6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsRml4ZWQ2NF8gPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY1CiAgICAgICAgICAgICAgY2FzZSA3NzogewogICAgICAgICAgICAgICAgb3B0aW9uYWxTZml4ZWQzMl8gPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NwogICAgICAgICAgICAgIGNhc2UgODE6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsU2ZpeGVkNjRfID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODEKICAgICAgICAgICAgICBjYXNlIDkzOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEZsb2F0XyA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkzCiAgICAgICAgICAgICAgY2FzZSA5NzogewogICAgICAgICAgICAgICAgb3B0aW9uYWxEb3VibGVfID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk3CiAgICAgICAgICAgICAgY2FzZSAxMDQ6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsQm9vbF8gPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNAogICAgICAgICAgICAgIGNhc2UgMTE0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTQKICAgICAgICAgICAgICBjYXNlIDEyMjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxCeXRlc18gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjIKICAgICAgICAgICAgICBjYXNlIDE0NjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDYKICAgICAgICAgICAgICBjYXNlIDE1NDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU0CiAgICAgICAgICAgICAgY2FzZSAxNjI6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYyCiAgICAgICAgICAgICAgY2FzZSAxNjg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkRW51bV8gPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2OAogICAgICAgICAgICAgIGNhc2UgMTc2OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEZvcmVpZ25FbnVtXyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTc2CiAgICAgICAgICAgICAgY2FzZSAxOTQ6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTk0CiAgICAgICAgICAgICAgY2FzZSAyMDI6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsQ29yZF8gPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMDIKICAgICAgICAgICAgICBjYXNlIDIxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMTAKICAgICAgICAgICAgICBjYXNlIDIxODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjE4CiAgICAgICAgICAgICAgY2FzZSAyNDg6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQ4CiAgICAgICAgICAgICAgY2FzZSAyNTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQoaW5wdXQucmVhZEludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1MAogICAgICAgICAgICAgIGNhc2UgMjU2OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjU2CiAgICAgICAgICAgICAgY2FzZSAyNTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKGlucHV0LnJlYWRJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTgKICAgICAgICAgICAgICBjYXNlIDI2NDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNjQKICAgICAgICAgICAgICBjYXNlIDI2NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8uYWRkSW50KGlucHV0LnJlYWRVSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjY2CiAgICAgICAgICAgICAgY2FzZSAyNzI6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRVSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNzIKICAgICAgICAgICAgICBjYXNlIDI3NDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkVUludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI3NAogICAgICAgICAgICAgIGNhc2UgMjgwOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI4MAogICAgICAgICAgICAgIGNhc2UgMjgyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5hZGRJbnQoaW5wdXQucmVhZFNJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODIKICAgICAgICAgICAgICBjYXNlIDI4ODogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI4OAogICAgICAgICAgICAgIGNhc2UgMjkwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRMb25nKGlucHV0LnJlYWRTSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjkwCiAgICAgICAgICAgICAgY2FzZSAzMDE6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzAxCiAgICAgICAgICAgICAgY2FzZSAyOTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRJbnQoaW5wdXQucmVhZEZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjk4CiAgICAgICAgICAgICAgY2FzZSAzMDU6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMDUKICAgICAgICAgICAgICBjYXNlIDMwNjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZExvbmcoaW5wdXQucmVhZEZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzA2CiAgICAgICAgICAgICAgY2FzZSAzMTc6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFNGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzE3CiAgICAgICAgICAgICAgY2FzZSAzMTQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLmFkZEludChpbnB1dC5yZWFkU0ZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzE0CiAgICAgICAgICAgICAgY2FzZSAzMjE6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMjEKICAgICAgICAgICAgICBjYXNlIDMyMjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIyCiAgICAgICAgICAgICAgY2FzZSAzMzM6IHsKICAgICAgICAgICAgICAgIGZsb2F0IHYgPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLmFkZEZsb2F0KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzMwogICAgICAgICAgICAgIGNhc2UgMzMwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdChpbnB1dC5yZWFkRmxvYXQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzMwCiAgICAgICAgICAgICAgY2FzZSAzMzc6IHsKICAgICAgICAgICAgICAgIGRvdWJsZSB2ID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5hZGREb3VibGUodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzM3CiAgICAgICAgICAgICAgY2FzZSAzMzg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkRG91YmxlKGlucHV0LnJlYWREb3VibGUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzM4CiAgICAgICAgICAgICAgY2FzZSAzNDQ6IHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdiA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8uYWRkQm9vbGVhbih2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNDQKICAgICAgICAgICAgICBjYXNlIDM0NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEJvb2xlYW4oaW5wdXQucmVhZEJvb2woKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQ2CiAgICAgICAgICAgICAgY2FzZSAzNTQ6IHsKICAgICAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nXy5hZGQocyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzU0CiAgICAgICAgICAgICAgY2FzZSAzNjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2ID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJ5dGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEJ5dGVzXy5hZGQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzYyCiAgICAgICAgICAgICAgY2FzZSAzODY6IHsKICAgICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLnBhcnNlcigpLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM4NgogICAgICAgICAgICAgIGNhc2UgMzk0OiB7CiAgICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZS5wYXJzZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzk0CiAgICAgICAgICAgICAgY2FzZSA0MDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAyCiAgICAgICAgICAgICAgY2FzZSA0MDg6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQwOAogICAgICAgICAgICAgIGNhc2UgNDEwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDEwCiAgICAgICAgICAgICAgY2FzZSA0MTY6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDE2CiAgICAgICAgICAgICAgY2FzZSA0MTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQxOAogICAgICAgICAgICAgIGNhc2UgNDM0OiB7CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfLmFkZChzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MzQKICAgICAgICAgICAgICBjYXNlIDQ0MjogewogICAgICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZENvcmRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkQ29yZF8uYWRkKHMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ0MgogICAgICAgICAgICAgIGNhc2UgNDU4OiB7CiAgICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5wYXJzZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDU4CiAgICAgICAgICAgICAgY2FzZSA4ODg6IHsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTExOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDg4OAogICAgICAgICAgICAgIGNhc2UgODk4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPbmVvZk5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTEyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDg5OAogICAgICAgICAgICAgIGNhc2UgOTA2OiB7CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMzsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRfID0gczsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MDYKICAgICAgICAgICAgICBjYXNlIDkxNDogewogICAgICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MTQKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb25lb2ZGaWVsZF87CiAgICAgIHB1YmxpYyBPbmVvZkZpZWxkQ2FzZQogICAgICAgICAgZ2V0T25lb2ZGaWVsZENhc2UoKSB7CiAgICAgICAgcmV0dXJuIE9uZW9mRmllbGRDYXNlLmZvck51bWJlcigKICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfKTsKICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZkZpZWxkKCkgewogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDFfOwoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMl8gOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogU2luZ3VsYXIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPmludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMigpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFNpbmd1bGFyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5pbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogU2luZ3VsYXIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPmludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb3B0aW9uYWxJbnQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxJbnQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+aW50NjQgb3B0aW9uYWxfaW50NjQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxJbnQ2NCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50NjQgb3B0aW9uYWxfaW50NjQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvcHRpb25hbEludDY0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9wdGlvbmFsX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMigpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxVaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxVaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFVpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxVaW50MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9wdGlvbmFsVWludDMyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFVpbnQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDY0IG9wdGlvbmFsX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxVaW50NjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDY0IG9wdGlvbmFsX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsVWludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbFVpbnQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFVpbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb3B0aW9uYWxVaW50NjRfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsU2ludDMyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ludDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsU2ludDMyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFNpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQzMiBvcHRpb25hbF9zaW50MzIgPSA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFNpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU2ludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbFNpbnQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQzMiBvcHRpb25hbF9zaW50MzIgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFNpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb3B0aW9uYWxTaW50MzJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsU2ludDY0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50NjQgb3B0aW9uYWxfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ludDY0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbFNpbnQ2NCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxTaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50NjQgb3B0aW9uYWxfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTaW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFNpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsU2ludDY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU2ludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvcHRpb25hbFNpbnQ2NF8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxGaXhlZDMyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGaXhlZDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsRml4ZWQzMigpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxGaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxGaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxGaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEZpeGVkMzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEZpeGVkMzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9wdGlvbmFsRml4ZWQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxGaXhlZDY0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGaXhlZDY0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbEZpeGVkNjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsRml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRml4ZWQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsRml4ZWQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRml4ZWQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb3B0aW9uYWxGaXhlZDY0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFNmaXhlZDMyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQzMiBvcHRpb25hbF9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsU2ZpeGVkMzIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsU2ZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQzMiBvcHRpb25hbF9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU2ZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFNmaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbFNmaXhlZDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFNmaXhlZDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvcHRpb25hbFNmaXhlZDMyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFNmaXhlZDY0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZml4ZWQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxTZml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU2ZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFNmaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxTZml4ZWQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU2ZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9wdGlvbmFsU2ZpeGVkNjRfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmxvYXQgb3B0aW9uYWxGbG9hdF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+ZmxvYXQgb3B0aW9uYWxfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRmxvYXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRPcHRpb25hbEZsb2F0KCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEZsb2F0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZmxvYXQgb3B0aW9uYWxfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxGbG9hdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRmxvYXQoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxGbG9hdF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRmxvYXQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9wdGlvbmFsRmxvYXRfID0gMEY7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZG91YmxlIG9wdGlvbmFsRG91YmxlXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5kb3VibGUgb3B0aW9uYWxfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbERvdWJsZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRPcHRpb25hbERvdWJsZSgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxEb3VibGVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5kb3VibGUgb3B0aW9uYWxfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRG91YmxlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxEb3VibGUoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsRG91YmxlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbERvdWJsZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb3B0aW9uYWxEb3VibGVfID0gMEQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYm9vbGVhbiBvcHRpb25hbEJvb2xfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCb29sLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRPcHRpb25hbEJvb2woKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsQm9vbF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEJvb2wgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEJvb2woYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEJvb2xfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxCb29sKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvcHRpb25hbEJvb2xfID0gZmFsc2U7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFN0cmluZ18gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBzOwogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU3RyaW5nKCkgewogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldE9wdGlvbmFsU3RyaW5nKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJ5dGVzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9wdGlvbmFsQnl0ZXMoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsQnl0ZXNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvcHRpb25hbF9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEJ5dGVzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxCeXRlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsQnl0ZXNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvcHRpb25hbF9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEJ5dGVzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBvcHRpb25hbEJ5dGVzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldE9wdGlvbmFsQnl0ZXMoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTmVzdGVkTWVzc2FnZShwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfICE9IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbEZvcmVpZ25NZXNzYWdlKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gIT0gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbEltcG9ydE1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsSW1wb3J0TWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbEltcG9ydE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VfICE9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDIwMDAwKTsKICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEltcG9ydE1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsTmVzdGVkRW51bV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGludCBnZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRFbnVtXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxOZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRFbnVtVmFsdWUoaW50IHZhbHVlKSB7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtKCkgewogICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZm9yTnVtYmVyKG9wdGlvbmFsTmVzdGVkRW51bV8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbE5lc3RlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbE5lc3RlZEVudW0ocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxOZXN0ZWRFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxGb3JlaWduRW51bV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldE9wdGlvbmFsRm9yZWlnbkVudW1WYWx1ZSgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduRW51bV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbEZvcmVpZ25FbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxGb3JlaWduRW51bVZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtIGdldE9wdGlvbmFsRm9yZWlnbkVudW0oKSB7CiAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtIHJlc3VsdCA9IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bS5mb3JOdW1iZXIob3B0aW9uYWxGb3JlaWduRW51bV8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxGb3JlaWduRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRm9yZWlnbkVudW0ocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb3B0aW9uYWxGb3JlaWduRW51bV8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEZvcmVpZ25FbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBvcHRpb25hbEZvcmVpZ25FbnVtXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFN0cmluZ1BpZWNlXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZ1BpZWNlLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nUGllY2VfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSBzOwogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmdQaWVjZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9wdGlvbmFsU3RyaW5nUGllY2VCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nUGllY2VfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFN0cmluZ1BpZWNlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTdHJpbmdQaWVjZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTdHJpbmdQaWVjZSgpIHsKICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldE9wdGlvbmFsU3RyaW5nUGllY2UoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmdQaWVjZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU3RyaW5nUGllY2VCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsQ29yZF8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbENvcmQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbENvcmQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbENvcmRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgb3B0aW9uYWxDb3JkXyA9IHM7CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsQ29yZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9wdGlvbmFsQ29yZEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxDb3JkXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgb3B0aW9uYWxDb3JkXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsQ29yZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQ29yZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsQ29yZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsQ29yZCgpIHsKICAgICAgICBvcHRpb25hbENvcmRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0T3B0aW9uYWxDb3JkKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxDb3JkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxDb3JkQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgICAgb3B0aW9uYWxDb3JkXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfICE9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLkJ1aWxkZXIgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbExhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTGF6eU1lc3NhZ2UocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbExhenlNZXNzYWdlKAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbExhenlNZXNzYWdlKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gIT0gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbExhenlNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkSW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEludDMyKCkgewogICAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRJbnQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkSW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkSW50NjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkSW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRJbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRJbnQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRJbnQ2NCgpIHsKICAgICAgICByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFVpbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkVWludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFVpbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVWludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRVaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVWludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFVpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkVWludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRVaW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFVpbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFVpbnQzMigpIHsKICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkVWludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkVWludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkVWludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkVWludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFVpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFVpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkVWludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkVWludDY0KCkgewogICAgICAgIHJlcGVhdGVkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwODAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNpbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNpbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2ludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTaW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFNpbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNpbnQzMigpIHsKICAgICAgICByZXBlYXRlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgxMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2ludDY0KCkgewogICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgyMDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaXhlZDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGaXhlZDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRml4ZWQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRml4ZWQzMigpIHsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkNjRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRGaXhlZDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpeGVkNjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGaXhlZDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRml4ZWQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRml4ZWQ2NCgpIHsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQzMl8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNmaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTZml4ZWQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNmaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNmaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTZml4ZWQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTZml4ZWQzMigpIHsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDY0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRTZml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ZpeGVkNjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNmaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2ZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNmaXhlZDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFNmaXhlZDY0Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNmaXhlZDY0KCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRmxvYXRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRmxvYXRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRmxvYXRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGZsb2F0IGdldFJlcGVhdGVkRmxvYXQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZsb2F0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGbG9hdCgKICAgICAgICAgIGludCBpbmRleCwgZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfLnNldEZsb2F0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZsb2F0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkRmxvYXQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZsb2F0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRGbG9hdF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRGbG9hdCgpIHsKICAgICAgICByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWREb3VibGVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWREb3VibGVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRG91YmxlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRG91YmxlXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRG91YmxlLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZERvdWJsZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0UmVwZWF0ZWREb3VibGUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXy5nZXREb3VibGUoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWREb3VibGUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZERvdWJsZSgKICAgICAgICAgIGludCBpbmRleCwgZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfLnNldERvdWJsZShpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZERvdWJsZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRG91YmxlKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRG91YmxlXy5hZGREb3VibGUodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWREb3VibGUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZERvdWJsZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWREb3VibGVfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWREb3VibGUoKSB7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgcmVwZWF0ZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQm9vbF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkQm9vbF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRCb29sXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRCb29sXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEJvb2xfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2wuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRSZXBlYXRlZEJvb2xMaXN0KCkgewogICAgICAgIHJlcGVhdGVkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCb29sQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJvb2wgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gZ2V0UmVwZWF0ZWRCb29sKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJvb2wgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEJvb2woCiAgICAgICAgICBpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCb29sXy5zZXRCb29sZWFuKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRCb29sIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRCb29sKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCb29sXy5hZGRCb29sZWFuKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRCb29sIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRCb29sKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkQm9vbF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQm9vbCgpIHsKICAgICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTdHJpbmdfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZ18gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KHJlcGVhdGVkU3RyaW5nXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZ0NvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0J5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTdHJpbmcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFN0cmluZyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU3RyaW5nXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nKCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMjApOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gcmVwZWF0ZWRCeXRlc18gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEJ5dGVzXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRCeXRlc18gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRCeXRlc18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJ5dGVzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldFJlcGVhdGVkQnl0ZXNMaXN0KCkgewogICAgICAgIHJlcGVhdGVkQnl0ZXNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJ5dGVzLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJ5dGVzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJ5dGVzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc18uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJ5dGVzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRCeXRlcygKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEJ5dGVzSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCeXRlc18uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJ5dGVzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRCeXRlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJ5dGVzXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkQnl0ZXMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEJ5dGVzKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRCeXRlc18pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRCeXRlcygpIHsKICAgICAgICByZXBlYXRlZEJ5dGVzXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQxXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPihyZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZShwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwODApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDgwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlPiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQxXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZT4ocmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8pOwogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2U+IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUNvdW50KCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDFfICYgMHgwMDAwMDEwMCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2U+IHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQxXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2U+KHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8pOwogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyPiByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2U+IGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEltcG9ydE1lc3NhZ2VfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUNvdW50KCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEltcG9ydE1lc3NhZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEltcG9ydE1lc3NhZ2VfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEltcG9ydE1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkSW1wb3J0TWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMjAwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkTmVzdGVkRW51bV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQxXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocmVwZWF0ZWROZXN0ZWRFbnVtXywgcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRSZXBlYXRlZE5lc3RlZEVudW0oaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWRFbnVtKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZEVudW0ocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRFbnVtKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWROZXN0ZWRFbnVtKCkgewogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAoaW50IHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZEZvcmVpZ25FbnVtXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQxXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZEZvcmVpZ25FbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bT4gZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtPihyZXBlYXRlZEZvcmVpZ25FbnVtXywgcmVwZWF0ZWRGb3JlaWduRW51bV9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGb3JlaWduRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25FbnVtXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbkVudW0gZ2V0UmVwZWF0ZWRGb3JlaWduRW51bShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRGb3JlaWduRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGb3JlaWduRW51bSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGb3JlaWduRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbkVudW0ocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGb3JlaWduRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRm9yZWlnbkVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZvcmVpZ25FbnVtKCkgewogICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWRGb3JlaWduRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0UmVwZWF0ZWRGb3JlaWduRW51bVZhbHVlTGlzdCgpIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRGb3JlaWduRW51bV8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZEZvcmVpZ25FbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGb3JlaWduRW51bVZhbHVlKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25FbnVtXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZEZvcmVpZ25FbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGb3JlaWduRW51bVZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZEZvcmVpZ25FbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGb3JlaWduRW51bVZhbHVlKGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbkVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXy5hZGQodmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZEZvcmVpZ25FbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGb3JlaWduRW51bVZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChpbnQgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZ1BpZWNlXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTdHJpbmdQaWVjZV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFN0cmluZ1BpZWNlXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nUGllY2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nUGllY2VDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nUGllY2UoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmdQaWVjZSgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdQaWVjZUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nUGllY2UgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZ1BpZWNlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdQaWVjZUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU3RyaW5nUGllY2UgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFN0cmluZ1BpZWNlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTdHJpbmdQaWVjZV8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nUGllY2UoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAxMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nUGllY2VCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkQ29yZF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRDb3JkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRDb3JkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRDb3JkXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRDb3JkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQ29yZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpIHsKICAgICAgICByZXBlYXRlZENvcmRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQ29yZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRDb3JkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQ29yZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZENvcmQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZF8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkQ29yZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRSZXBlYXRlZENvcmRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZENvcmQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZENvcmQoCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQ29yZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQ29yZF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZENvcmQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZENvcmQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZENvcmRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZENvcmRfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRDb3JkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRDb3JkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkQ29yZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZENvcmRfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQ29yZCgpIHsKICAgICAgICByZXBlYXRlZENvcmRfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMjAwMCk7OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRDb3JkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRDb3JkQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRDb3JkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRDb3JkXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPihyZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiBnZXRSZXBlYXRlZExhenlNZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUNvdW50KCkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRSZXBlYXRlZExhenlNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZExhenlNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTGF6eU1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTGF6eU1lc3NhZ2UocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRMYXp5TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZExhenlNZXNzYWdlKAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTGF6eU1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkTGF6eU1lc3NhZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkTGF6eU1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZExhenlNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZV8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRMYXp5TWVzc2FnZV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMV8gJiAweDAwMDA0MDAwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mVWludDMyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mVWludDMyKCkgewogICAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTExOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb25lb2ZVaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldE9uZW9mVWludDMyKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTExKSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9uZW9mVWludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZVaW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMTsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZlVpbnQzMigpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMSkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZk5lc3RlZE1lc3NhZ2UuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICAgICByZXR1cm4gKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF87CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICAgICByZXR1cm4gb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZk5lc3RlZE1lc3NhZ2UocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTEyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZOZXN0ZWRNZXNzYWdlKAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT25lb2ZOZXN0ZWRNZXNzYWdlKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMiAmJgogICAgICAgICAgICAgIG9uZW9mRmllbGRfICE9IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKChwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfKQogICAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTEyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZk5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldE9uZW9mTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPbmVvZk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSAmJiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICAgIHJldHVybiBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgICAgIHJldHVybiAocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9uZW9mTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCEob25lb2ZGaWVsZENhc2VfID09IDExMikpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIChwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlN0cmluZygpIHsKICAgICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExMzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9uZW9mU3RyaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPbmVvZlN0cmluZygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgICByZWYgPSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9uZW9mU3RyaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRPbmVvZlN0cmluZ0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVvZlN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTEzOwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mU3RyaW5nKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZlN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMzsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZCeXRlcygpIHsKICAgICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExNDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZkJ5dGVzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPbmVvZkJ5dGVzKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0KSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVvZkJ5dGVzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZCeXRlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExNDsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDExNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZCeXRlcygpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNCkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RBbGxUeXBlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0QWxsVHlwZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0QWxsVHlwZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0QWxsVHlwZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEFsbFR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFBhY2tlZFR5cGVzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFBhY2tlZEludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRJbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRQYWNrZWRJbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDY0LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkSW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UGFja2VkSW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFVpbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFBhY2tlZFVpbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDMyLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkVWludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRVaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkVWludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRVaW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRQYWNrZWRVaW50NjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFVpbnQ2NC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZFVpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkVWludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRQYWNrZWRVaW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNpbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFBhY2tlZFNpbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ludDMyLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2ludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2ludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTaW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRQYWNrZWRTaW50NjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNpbnQ2NC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZFNpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRQYWNrZWRTaW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRml4ZWQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFBhY2tlZEZpeGVkMzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEZpeGVkMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRGaXhlZDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEZpeGVkNjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRQYWNrZWRGaXhlZDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEZpeGVkNjQuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRGaXhlZDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFBhY2tlZEZpeGVkNjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZml4ZWQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFBhY2tlZFNmaXhlZDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ZpeGVkMzIuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRTZml4ZWQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZFNmaXhlZDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ZpeGVkNjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNmaXhlZDY0LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2ZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UGFja2VkU2ZpeGVkNjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRmxvYXQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4gZ2V0UGFja2VkRmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRmxvYXQuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRGbG9hdENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRGbG9hdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGZsb2F0IGdldFBhY2tlZEZsb2F0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRG91YmxlLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPiBnZXRQYWNrZWREb3VibGVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWREb3VibGUuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWREb3VibGVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBkb3VibGUgZ2V0UGFja2VkRG91YmxlKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRCb29sLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0UGFja2VkQm9vbExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkQm9vbC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEJvb2xDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEJvb2wgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBib29sZWFuIGdldFBhY2tlZEJvb2woaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtPiBnZXRQYWNrZWRFbnVtTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEVudW0uCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRFbnVtQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbkVudW0gZ2V0UGFja2VkRW51bShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHBhY2tlZEVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UGFja2VkRW51bVZhbHVlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEVudW1WYWx1ZShpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0UGFja2VkVHlwZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0UGFja2VkVHlwZXMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzKQogICAgICBUZXN0UGFja2VkVHlwZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RQYWNrZWRUeXBlcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0UGFja2VkVHlwZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0UGFja2VkVHlwZXMoKSB7CiAgICAgIHBhY2tlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHBhY2tlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcGFja2VkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcGFja2VkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwYWNrZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcGFja2VkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHBhY2tlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcGFja2VkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcGFja2VkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBwYWNrZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcGFja2VkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFBhY2tlZFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0UGFja2VkVHlwZXMuY2xhc3MsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0UGFja2VkVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDkwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRJbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRQYWNrZWRJbnQzMkxpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkSW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkSW50MzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfSU5UNjRfRklFTERfTlVNQkVSID0gOTE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBwYWNrZWRJbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UGFja2VkSW50NjRMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkSW50NjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UGFja2VkSW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRJbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDkyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRVaW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkVWludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UGFja2VkVWludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFVpbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFVpbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFVpbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkVWludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkVWludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkVWludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9VSU5UNjRfRklFTERfTlVNQkVSID0gOTM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBwYWNrZWRVaW50NjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFVpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFBhY2tlZFVpbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRVaW50NjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRVaW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkVWludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRVaW50NjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRVaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRVaW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRVaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkVWludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9TSU5UMzJfRklFTERfTlVNQkVSID0gOTQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZFNpbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRQYWNrZWRTaW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkU2ludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkU2ludDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRTaW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRTaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1NJTlQ2NF9GSUVMRF9OVU1CRVIgPSA5NTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFNpbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UGFja2VkU2ludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNpbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNpbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRTaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNpbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZFNpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRTaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0ZJWEVEMzJfRklFTERfTlVNQkVSID0gOTY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZEZpeGVkMzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UGFja2VkRml4ZWQzMkxpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRGaXhlZDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGaXhlZDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRGaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkRml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSA5NzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZEZpeGVkNjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFBhY2tlZEZpeGVkNjRMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkRml4ZWQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRml4ZWQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRGaXhlZDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRGaXhlZDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UGFja2VkRml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkRml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfU0ZJWEVEMzJfRklFTERfTlVNQkVSID0gOTg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZFNmaXhlZDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFBhY2tlZFNmaXhlZDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNmaXhlZDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNmaXhlZDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZFNmaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9TRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSA5OTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFNmaXhlZDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ZpeGVkNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZml4ZWQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRTZml4ZWQ2NENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkU2ZpeGVkNjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRTZml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZFNmaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9GTE9BVF9GSUVMRF9OVU1CRVIgPSAxMDA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5GbG9hdExpc3QgcGFja2VkRmxvYXRfID0KICAgICAgICBlbXB0eUZsb2F0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEZsb2F0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgIGdldFBhY2tlZEZsb2F0TGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZsb2F0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGbG9hdC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRGbG9hdENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkRmxvYXRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGZsb2F0IGdldFBhY2tlZEZsb2F0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkRmxvYXRfLmdldEZsb2F0KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEZsb2F0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9ET1VCTEVfRklFTERfTlVNQkVSID0gMTAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCBwYWNrZWREb3VibGVfID0KICAgICAgICBlbXB0eURvdWJsZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZERvdWJsZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZ2V0UGFja2VkRG91YmxlTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZERvdWJsZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWREb3VibGUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRG91YmxlQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWREb3VibGVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGRvdWJsZSBnZXRQYWNrZWREb3VibGUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWREb3VibGVfLmdldERvdWJsZShpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWREb3VibGVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0JPT0xfRklFTERfTlVNQkVSID0gMTAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgcGFja2VkQm9vbF8gPQogICAgICAgIGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkQm9vbC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGdldFBhY2tlZEJvb2xMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkQm9vbF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEJvb2wuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkQm9vbENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkQm9vbF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEJvb2wgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRQYWNrZWRCb29sKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkQm9vbF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRCb29sTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9FTlVNX0ZJRUxEX05VTUJFUiA9IDEwMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2VkRW51bV87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtPiBwYWNrZWRFbnVtX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtIHJlc3VsdCA9IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbkVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtPiBnZXRQYWNrZWRFbnVtTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bT4ocGFja2VkRW51bV8sIHBhY2tlZEVudW1fY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQYWNrZWRFbnVtQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRFbnVtXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bSBnZXRQYWNrZWRFbnVtKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocGFja2VkRW51bV8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcGFja2VkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UGFja2VkRW51bVZhbHVlTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEVudW1fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQYWNrZWRFbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRFbnVtXy5nZXQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemU7CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBpZiAoZ2V0UGFja2VkSW50MzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDcyMik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkSW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyTm9UYWcocGFja2VkSW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEludDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3MzApOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRJbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NE5vVGFnKHBhY2tlZEludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkVWludDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3MzgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZFVpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkVWludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZFVpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkVWludDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3NDYpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZFVpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NE5vVGFnKHBhY2tlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNpbnQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzU0KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRTaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzJOb1RhZyhwYWNrZWRTaW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNpbnQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzYyKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRTaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50NjROb1RhZyhwYWNrZWRTaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRGaXhlZDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3NzApOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEZpeGVkMzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMk5vVGFnKHBhY2tlZEZpeGVkMzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEZpeGVkNjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDc3OCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkRml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkRml4ZWQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0Tm9UYWcocGFja2VkRml4ZWQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNmaXhlZDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3ODYpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZFNmaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRTZml4ZWQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQzMk5vVGFnKHBhY2tlZFNmaXhlZDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzk0KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRTZml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2ZpeGVkNjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjROb1RhZyhwYWNrZWRTZml4ZWQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEZsb2F0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MDIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEZsb2F0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRGbG9hdF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdE5vVGFnKHBhY2tlZEZsb2F0Xy5nZXRGbG9hdChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZERvdWJsZUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoODEwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWREb3VibGVNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZERvdWJsZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVEb3VibGVOb1RhZyhwYWNrZWREb3VibGVfLmdldERvdWJsZShpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEJvb2xMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDgxOCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkQm9vbE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkQm9vbF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sTm9UYWcocGFja2VkQm9vbF8uZ2V0Qm9vbGVhbihpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEVudW1MaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDgyNik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcocGFja2VkRW51bV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhwYWNrZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEludDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkSW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplTm9UYWcocGFja2VkSW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkSW50NjRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkSW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRVaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKHBhY2tlZFVpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZFVpbnQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRVaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRVaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDY0U2l6ZU5vVGFnKHBhY2tlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRVaW50NjRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkVWludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2ludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemVOb1RhZyhwYWNrZWRTaW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRTaW50MzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkU2ludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2ludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemVOb1RhZyhwYWNrZWRTaW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkU2ludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZFNpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRQYWNrZWRGaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkRml4ZWQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRGaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFBhY2tlZEZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRGaXhlZDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRTZml4ZWQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRTZml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZFNmaXhlZDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZFNmaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFBhY2tlZEZsb2F0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkRmxvYXRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkRmxvYXRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UGFja2VkRG91YmxlTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkRG91YmxlTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZERvdWJsZU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDEgKiBnZXRQYWNrZWRCb29sTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkQm9vbExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRCb29sTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHBhY2tlZEVudW1fLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRFbnVtTGlzdCgpLmlzRW1wdHkoKSkgeyAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9cGFja2VkRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFBhY2tlZFR5cGVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFBhY2tlZFR5cGVzIG90aGVyID0gKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0UGFja2VkVHlwZXMpIG9iajsKCiAgICAgIGlmICghZ2V0UGFja2VkSW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkSW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkSW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkSW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkVWludDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZFVpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRVaW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkVWludDY0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZFNpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRTaW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkU2ludDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZFNpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRGaXhlZDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEZpeGVkMzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkRml4ZWQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRGaXhlZDY0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZFNmaXhlZDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZFNmaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZFNmaXhlZDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZFNmaXhlZDY0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEZsb2F0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEZsb2F0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZERvdWJsZUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWREb3VibGVMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkQm9vbExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRCb29sTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXBhY2tlZEVudW1fLmVxdWFscyhvdGhlci5wYWNrZWRFbnVtXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoZ2V0UGFja2VkSW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9JTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkSW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkSW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9JTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkSW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkVWludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRVaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkVWludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfVUlOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRVaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2ludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfU0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRTaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2ludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfU0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRTaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkRml4ZWQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkRml4ZWQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2ZpeGVkMzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9TRklYRUQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2ZpeGVkNjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9TRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkU2ZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkRmxvYXRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9GTE9BVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkRmxvYXRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkRG91YmxlQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfRE9VQkxFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWREb3VibGVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkQm9vbENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX0JPT0xfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEJvb2xMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkRW51bUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHBhY2tlZEVudW1fLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RQYWNrZWRUeXBlcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RQYWNrZWRUeXBlcyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RQYWNrZWRUeXBlcyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0UGFja2VkVHlwZXN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMpCiAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RQYWNrZWRUeXBlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFBhY2tlZFR5cGVzLmNsYXNzLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFBhY2tlZFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RQYWNrZWRUeXBlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgcGFja2VkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcGFja2VkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHBhY2tlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBwYWNrZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHBhY2tlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBwYWNrZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHBhY2tlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcGFja2VkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcGFja2VkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcGFja2VkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHBhY2tlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgcGFja2VkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIHBhY2tlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIHBhY2tlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RQYWNrZWRUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFBhY2tlZFR5cGVzIGJ1aWxkKCkgewogICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0UGFja2VkVHlwZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFBhY2tlZFR5cGVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFBhY2tlZFR5cGVzIHJlc3VsdCA9IG5ldyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFBhY2tlZFR5cGVzKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0UGFja2VkVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHBhY2tlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnBhY2tlZEVudW1fID0gcGFja2VkRW51bV87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0UGFja2VkVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkSW50MzJfID0gcGFja2VkSW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRJbnQ2NF8gPSBwYWNrZWRJbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRVaW50MzJfID0gcGFja2VkVWludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZFVpbnQ2NF8gPSBwYWNrZWRVaW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkU2ludDMyXyA9IHBhY2tlZFNpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRTaW50NjRfID0gcGFja2VkU2ludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRGaXhlZDMyXyA9IHBhY2tlZEZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZEZpeGVkNjRfID0gcGFja2VkRml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZFNmaXhlZDMyXyA9IHBhY2tlZFNmaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkU2ZpeGVkNjRfID0gcGFja2VkU2ZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRGbG9hdF8gPSBwYWNrZWRGbG9hdF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWREb3VibGVfID0gcGFja2VkRG91YmxlXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRCb29sXyA9IHBhY2tlZEJvb2xfOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0UGFja2VkVHlwZXMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0UGFja2VkVHlwZXMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RQYWNrZWRUeXBlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRJbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEludDMyXyA9IG90aGVyLnBhY2tlZEludDMyXzsKICAgICAgICAgICAgcGFja2VkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkSW50MzJfLmFkZEFsbChvdGhlci5wYWNrZWRJbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkSW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkSW50NjRfID0gb3RoZXIucGFja2VkSW50NjRfOwogICAgICAgICAgICBwYWNrZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRJbnQ2NF8uYWRkQWxsKG90aGVyLnBhY2tlZEludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRVaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFVpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZFVpbnQzMl8gPSBvdGhlci5wYWNrZWRVaW50MzJfOwogICAgICAgICAgICBwYWNrZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFVpbnQzMl8uYWRkQWxsKG90aGVyLnBhY2tlZFVpbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkVWludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRVaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRVaW50NjRfID0gb3RoZXIucGFja2VkVWludDY0XzsKICAgICAgICAgICAgcGFja2VkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRVaW50NjRfLmFkZEFsbChvdGhlci5wYWNrZWRVaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZFNpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkU2ludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkU2ludDMyXyA9IG90aGVyLnBhY2tlZFNpbnQzMl87CiAgICAgICAgICAgIHBhY2tlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkU2ludDMyXy5hZGRBbGwob3RoZXIucGFja2VkU2ludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRTaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFNpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZFNpbnQ2NF8gPSBvdGhlci5wYWNrZWRTaW50NjRfOwogICAgICAgICAgICBwYWNrZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFNpbnQ2NF8uYWRkQWxsKG90aGVyLnBhY2tlZFNpbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEZpeGVkMzJfID0gb3RoZXIucGFja2VkRml4ZWQzMl87CiAgICAgICAgICAgIHBhY2tlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRGaXhlZDMyXy5hZGRBbGwob3RoZXIucGFja2VkRml4ZWQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEZpeGVkNjRfID0gb3RoZXIucGFja2VkRml4ZWQ2NF87CiAgICAgICAgICAgIHBhY2tlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRGaXhlZDY0Xy5hZGRBbGwob3RoZXIucGFja2VkRml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkU2ZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFNmaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkU2ZpeGVkMzJfID0gb3RoZXIucGFja2VkU2ZpeGVkMzJfOwogICAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8uYWRkQWxsKG90aGVyLnBhY2tlZFNmaXhlZDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkU2ZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRTZml4ZWQ2NF8gPSBvdGhlci5wYWNrZWRTZml4ZWQ2NF87CiAgICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5hZGRBbGwob3RoZXIucGFja2VkU2ZpeGVkNjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEZsb2F0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEZsb2F0XyA9IG90aGVyLnBhY2tlZEZsb2F0XzsKICAgICAgICAgICAgcGFja2VkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkRmxvYXRfLmFkZEFsbChvdGhlci5wYWNrZWRGbG9hdF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkRG91YmxlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWREb3VibGVfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWREb3VibGVfID0gb3RoZXIucGFja2VkRG91YmxlXzsKICAgICAgICAgICAgcGFja2VkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWREb3VibGVfLmFkZEFsbChvdGhlci5wYWNrZWREb3VibGVfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRCb29sXyA9IG90aGVyLnBhY2tlZEJvb2xfOwogICAgICAgICAgICBwYWNrZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkQm9vbF8uYWRkQWxsKG90aGVyLnBhY2tlZEJvb2xfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRFbnVtXyA9IG90aGVyLnBhY2tlZEVudW1fOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEVudW1fLmFkZEFsbChvdGhlci5wYWNrZWRFbnVtXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA3MjA6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkSW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MjAKICAgICAgICAgICAgICBjYXNlIDcyMjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRJbnQzMl8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MjIKICAgICAgICAgICAgICBjYXNlIDcyODogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkSW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzI4CiAgICAgICAgICAgICAgY2FzZSA3MzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkSW50NjRfLmFkZExvbmcoaW5wdXQucmVhZEludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDczMAogICAgICAgICAgICAgIGNhc2UgNzM2OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkVWludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzM2CiAgICAgICAgICAgICAgY2FzZSA3Mzg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZFVpbnQzMl8uYWRkSW50KGlucHV0LnJlYWRVSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzM4CiAgICAgICAgICAgICAgY2FzZSA3NDQ6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRVSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkVWludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0NAogICAgICAgICAgICAgIGNhc2UgNzQ2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRVaW50NjRfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NDYKICAgICAgICAgICAgICBjYXNlIDc1MjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZFNpbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc1MgogICAgICAgICAgICAgIGNhc2UgNzU0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRTaW50MzJfLmFkZEludChpbnB1dC5yZWFkU0ludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc1NAogICAgICAgICAgICAgIGNhc2UgNzYwOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZFNpbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NjAKICAgICAgICAgICAgICBjYXNlIDc2MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkU2ludDY0Xy5hZGRMb25nKGlucHV0LnJlYWRTSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzYyCiAgICAgICAgICAgICAgY2FzZSA3NzM6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZEZpeGVkMzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzMKICAgICAgICAgICAgICBjYXNlIDc3MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkMzJJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkRml4ZWQzMl8uYWRkSW50KGlucHV0LnJlYWRGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc3MAogICAgICAgICAgICAgIGNhc2UgNzc3OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkRml4ZWQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzcKICAgICAgICAgICAgICBjYXNlIDc3ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkRml4ZWQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzgKICAgICAgICAgICAgICBjYXNlIDc4OTogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc4OQogICAgICAgICAgICAgIGNhc2UgNzg2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkMzJJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkU2ZpeGVkMzJfLmFkZEludChpbnB1dC5yZWFkU0ZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzg2CiAgICAgICAgICAgICAgY2FzZSA3OTM6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc5MwogICAgICAgICAgICAgIGNhc2UgNzk0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkU2ZpeGVkNjRfLmFkZExvbmcoaW5wdXQucmVhZFNGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc5NAogICAgICAgICAgICAgIGNhc2UgODA1OiB7CiAgICAgICAgICAgICAgICBmbG9hdCB2ID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkRmxvYXRfLmFkZEZsb2F0KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwNQogICAgICAgICAgICAgIGNhc2UgODAyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkRmxvYXRfLmFkZEZsb2F0KGlucHV0LnJlYWRGbG9hdCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDIKICAgICAgICAgICAgICBjYXNlIDgwOTogewogICAgICAgICAgICAgICAgZG91YmxlIHYgPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZERvdWJsZV8uYWRkRG91YmxlKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwOQogICAgICAgICAgICAgIGNhc2UgODEwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZERvdWJsZV8uYWRkRG91YmxlKGlucHV0LnJlYWREb3VibGUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODEwCiAgICAgICAgICAgICAgY2FzZSA4MTY6IHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdiA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRCb29sXy5hZGRCb29sZWFuKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxNgogICAgICAgICAgICAgIGNhc2UgODE4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkQm9vbElzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRCb29sXy5hZGRCb29sZWFuKGlucHV0LnJlYWRCb29sKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxOAogICAgICAgICAgICAgIGNhc2UgODI0OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgyNAogICAgICAgICAgICAgIGNhc2UgODI2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBwYWNrZWRFbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MjYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkSW50MzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRQYWNrZWRJbnQzMkxpc3QoKSB7CiAgICAgICAgcGFja2VkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkSW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkSW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRJbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkSW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRJbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEludDMyKCkgewogICAgICAgIHBhY2tlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkSW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRJbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkSW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFBhY2tlZEludDY0TGlzdCgpIHsKICAgICAgICBwYWNrZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRJbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UGFja2VkSW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkSW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRJbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRJbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRJbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRJbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkSW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkSW50NjQoKSB7CiAgICAgICAgcGFja2VkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkVWludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkVWludDMyXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRVaW50MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFBhY2tlZFVpbnQzMkxpc3QoKSB7CiAgICAgICAgcGFja2VkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZFVpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkVWludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFVpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkVWludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRVaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRVaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRVaW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFVpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFVpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkVWludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRVaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRVaW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkVWludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkVWludDMyKCkgewogICAgICAgIHBhY2tlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBwYWNrZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkVWludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkVWludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkVWludDY0XyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRVaW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFBhY2tlZFVpbnQ2NExpc3QoKSB7CiAgICAgICAgcGFja2VkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkVWludDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRVaW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFVpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZFVpbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRVaW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRVaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRVaW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRVaW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkVWludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkVWludDY0KCkgewogICAgICAgIHBhY2tlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRTaW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTaW50MzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFNpbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UGFja2VkU2ludDMyTGlzdCgpIHsKICAgICAgICBwYWNrZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkU2ludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZFNpbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNpbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkU2ludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTaW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZFNpbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRTaW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRTaW50MzIoKSB7CiAgICAgICAgcGFja2VkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRTaW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRTaW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFNpbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UGFja2VkU2ludDY0TGlzdCgpIHsKICAgICAgICBwYWNrZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkU2ludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRTaW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZFNpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkU2ludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNpbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNpbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZFNpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRTaW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRTaW50NjQoKSB7CiAgICAgICAgcGFja2VkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEZpeGVkMzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRQYWNrZWRGaXhlZDMyTGlzdCgpIHsKICAgICAgICBwYWNrZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRml4ZWQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRGaXhlZDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEZpeGVkMzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRml4ZWQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRGaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkRml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEZpeGVkMzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkRml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEZpeGVkMzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEZpeGVkMzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEZpeGVkMzIoKSB7CiAgICAgICAgcGFja2VkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBwYWNrZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRml4ZWQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRml4ZWQ2NF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFBhY2tlZEZpeGVkNjRMaXN0KCkgewogICAgICAgIHBhY2tlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkRml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRGaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkNjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZEZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRGaXhlZDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRGaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkRml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRGaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkRml4ZWQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkRml4ZWQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkRml4ZWQ2NCgpIHsKICAgICAgICBwYWNrZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkU2ZpeGVkMzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRTZml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZFNmaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRTZml4ZWQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkU2ZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkU2ZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRQYWNrZWRTZml4ZWQzMkxpc3QoKSB7CiAgICAgICAgcGFja2VkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkU2ZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ZpeGVkMzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRTZml4ZWQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2ZpeGVkMzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRTZml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNmaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNmaXhlZDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkU2ZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRTZml4ZWQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZFNmaXhlZDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZFNmaXhlZDMyKCkgewogICAgICAgIHBhY2tlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTZml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkU2ZpeGVkNjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXBhY2tlZFNmaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkU2ZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFNmaXhlZDY0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNmaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UGFja2VkU2ZpeGVkNjRMaXN0KCkgewogICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNmaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRTZml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRTZml4ZWQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNmaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkU2ZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNmaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkU2ZpeGVkNjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRTZml4ZWQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRTZml4ZWQ2NCgpIHsKICAgICAgICBwYWNrZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IHBhY2tlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEZsb2F0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEZsb2F0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEZsb2F0XyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRGbG9hdF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0UGFja2VkRmxvYXRMaXN0KCkgewogICAgICAgIHBhY2tlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZsb2F0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEZsb2F0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRGbG9hdENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRGbG9hdF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRQYWNrZWRGbG9hdChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRmxvYXRfLmdldEZsb2F0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRGbG9hdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEZsb2F0KAogICAgICAgICAgaW50IGluZGV4LCBmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEZsb2F0Xy5zZXRGbG9hdChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEZsb2F0Xy5hZGRGbG9hdCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRGbG9hdCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRGbG9hdF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkRmxvYXQoKSB7CiAgICAgICAgcGFja2VkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHBhY2tlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZERvdWJsZV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZERvdWJsZV8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRG91YmxlXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkRG91YmxlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRG91YmxlXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWREb3VibGVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRG91YmxlLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRQYWNrZWREb3VibGVMaXN0KCkgewogICAgICAgIHBhY2tlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWREb3VibGVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWREb3VibGUuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZERvdWJsZUNvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWREb3VibGVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZERvdWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZG91YmxlIGdldFBhY2tlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRG91YmxlXy5nZXREb3VibGUoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRG91YmxlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkRG91YmxlKAogICAgICAgICAgaW50IGluZGV4LCBkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRG91YmxlXy5zZXREb3VibGUoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRG91YmxlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkRG91YmxlKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICBwYWNrZWREb3VibGVfLmFkZERvdWJsZSh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWREb3VibGUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWREb3VibGUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWREb3VibGVfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkRG91YmxlKCkgewogICAgICAgIHBhY2tlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCBwYWNrZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkQm9vbF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkQm9vbF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkQm9vbF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkQm9vbF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEJvb2wuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRQYWNrZWRCb29sTGlzdCgpIHsKICAgICAgICBwYWNrZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEJvb2xfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEJvb2wuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEJvb2xDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkQm9vbF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGdldFBhY2tlZEJvb2woaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEJvb2xfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRCb29sIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkQm9vbCgKICAgICAgICAgIGludCBpbmRleCwgYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkQm9vbF8uc2V0Qm9vbGVhbihpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEJvb2wgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRCb29sKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkQm9vbElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEJvb2xfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRCb29sIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkQm9vbCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkQm9vbF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEJvb2woKSB7CiAgICAgICAgcGFja2VkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrZWRFbnVtXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRFbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihwYWNrZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbkVudW0+IGdldFBhY2tlZEVudW1MaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bT4ocGFja2VkRW51bV8sIHBhY2tlZEVudW1fY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRFbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbkVudW0gZ2V0UGFja2VkRW51bShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocGFja2VkRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEVudW0oCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEVudW1fLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkRW51bShwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbkVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBwYWNrZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduRW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25FbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICBwYWNrZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkRW51bSgpIHsKICAgICAgICBwYWNrZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciBwYWNrZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRQYWNrZWRFbnVtVmFsdWVMaXN0KCkgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChwYWNrZWRFbnVtXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRW51bVZhbHVlKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRFbnVtXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgcGFja2VkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEVudW1WYWx1ZSgKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CiAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEVudW1fLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHBhY2tlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRFbnVtVmFsdWUoaW50IHZhbHVlKSB7CiAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciBwYWNrZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkRW51bVZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChpbnQgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHBhY2tlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RQYWNrZWRUeXBlcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFBhY2tlZFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFBhY2tlZFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFBhY2tlZFR5cGVzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RQYWNrZWRUeXBlcz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RQYWNrZWRUeXBlcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQYWNrZWRUeXBlcz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UGFja2VkVHlwZXM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0UGFja2VkVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0VW5wYWNrZWRUeXBlc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRSZXBlYXRlZEludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+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+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJvb2wuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEJvb2xDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2woaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IGdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1Db3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogRXhwbGljaXRseSBzZXQgcGFja2VkIHRvIGZhbHNlCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RVbnBhY2tlZFR5cGVzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZFR5cGVzKQogICAgICBUZXN0VW5wYWNrZWRUeXBlc09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFVucGFja2VkVHlwZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFVucGFja2VkVHlwZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0VW5wYWNrZWRUeXBlcygpIHsKICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcmVwZWF0ZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgIHJlcGVhdGVkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFVucGFja2VkVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcy5jbGFzcywgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RVbnBhY2tlZFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkSW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkSW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkSW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9VSU5UMzJfRklFTERfTlVNQkVSID0gMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRVaW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkVWludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1VJTlQ2NF9GSUVMRF9OVU1CRVIgPSA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRVaW50NjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkVWludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NJTlQzMl9GSUVMRF9OVU1CRVIgPSA1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFNpbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0lOVDY0X0ZJRUxEX05VTUJFUiA9IDY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNpbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkU2ludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRTaW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEZpeGVkMzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0ZJWEVENjRfRklFTERfTlVNQkVSID0gODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkRml4ZWQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkRml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0ZJWEVEMzJfRklFTERfTlVNQkVSID0gOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTZml4ZWQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0ZJWEVENjRfRklFTERfTlVNQkVSID0gMTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNmaXhlZDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9GTE9BVF9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCByZXBlYXRlZEZsb2F0XyA9CiAgICAgICAgZW1wdHlGbG9hdExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmxvYXQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGZsb2F0IGdldFJlcGVhdGVkRmxvYXQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0Xy5nZXRGbG9hdChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRE9VQkxFX0ZJRUxEX05VTUJFUiA9IDEyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCByZXBlYXRlZERvdWJsZV8gPQogICAgICAgIGVtcHR5RG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZERvdWJsZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZERvdWJsZS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZERvdWJsZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZERvdWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBkb3VibGUgZ2V0UmVwZWF0ZWREb3VibGUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV8uZ2V0RG91YmxlKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9CT09MX0ZJRUxEX05VTUJFUiA9IDEzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgcmVwZWF0ZWRCb29sXyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGdldFJlcGVhdGVkQm9vbExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJvb2xDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZ2V0UmVwZWF0ZWRCb29sKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVIgPSAxNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPihyZXBlYXRlZE5lc3RlZEVudW1fLCByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgcmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMiwgcmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoMywgcmVwZWF0ZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50NjQoNCwgcmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyKDUsIHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0KDYsIHJlcGVhdGVkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRml4ZWQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDMyKDcsIHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRml4ZWQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0KDgsIHJlcGVhdGVkRml4ZWQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNmaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyKDksIHJlcGVhdGVkU2ZpeGVkMzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNmaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0KDEwLCByZXBlYXRlZFNmaXhlZDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRmxvYXRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMTEsIHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRG91YmxlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgxMiwgcmVwZWF0ZWREb3VibGVfLmdldERvdWJsZShpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEJvb2xfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgxMywgcmVwZWF0ZWRCb29sXy5nZXRCb29sZWFuKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDE0LCByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhyZXBlYXRlZEludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkSW50MzJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZEludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZEludDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhyZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplTm9UYWcocmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkVWludDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemVOb1RhZyhyZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50NjRTaXplTm9UYWcocmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU2ludDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSAxICogZ2V0UmVwZWF0ZWRCb29sTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkQm9vbExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RVbnBhY2tlZFR5cGVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMgb3RoZXIgPSAocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RVbnBhY2tlZFR5cGVzKSBvYmo7CgogICAgICBpZiAoIWdldFJlcGVhdGVkSW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkSW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEZsb2F0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkRG91YmxlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRG91YmxlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkQm9vbExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEJvb2xMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghcmVwZWF0ZWROZXN0ZWRFbnVtXy5lcXVhbHMob3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRVaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRCb29sQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9CT09MX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEJvb2xMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcmVwZWF0ZWROZXN0ZWRFbnVtXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogRXhwbGljaXRseSBzZXQgcGFja2VkIHRvIGZhbHNlCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZFR5cGVzKQogICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0VW5wYWNrZWRUeXBlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdFVucGFja2VkVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RVbnBhY2tlZFR5cGVzLmNsYXNzLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBidWlsZCgpIHsKICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyByZXN1bHQgPSBuZXcgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RVbnBhY2tlZFR5cGVzKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyByZXN1bHQpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkTmVzdGVkRW51bV8gPSByZXBlYXRlZE5lc3RlZEVudW1fOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEludDMyXyA9IHJlcGVhdGVkSW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW50NjRfID0gcmVwZWF0ZWRJbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkVWludDMyXyA9IHJlcGVhdGVkVWludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRVaW50NjRfID0gcmVwZWF0ZWRVaW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNpbnQzMl8gPSByZXBlYXRlZFNpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2ludDY0XyA9IHJlcGVhdGVkU2ludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRml4ZWQzMl8gPSByZXBlYXRlZEZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRGaXhlZDY0XyA9IHJlcGVhdGVkRml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTZml4ZWQzMl8gPSByZXBlYXRlZFNmaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNmaXhlZDY0XyA9IHJlcGVhdGVkU2ZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRmxvYXRfID0gcmVwZWF0ZWRGbG9hdF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRG91YmxlXyA9IHJlcGVhdGVkRG91YmxlXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQm9vbF8gPSByZXBlYXRlZEJvb2xfOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RVbnBhY2tlZFR5cGVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRJbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfID0gb3RoZXIucmVwZWF0ZWRJbnQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRJbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRJbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfID0gb3RoZXIucmVwZWF0ZWRJbnQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRJbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRVaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkVWludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gb3RoZXIucmVwZWF0ZWRVaW50MzJfOwogICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkVWludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFVpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRVaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBvdGhlci5yZXBlYXRlZFVpbnQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRVaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2ludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IG90aGVyLnJlcGVhdGVkU2ludDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNpbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gb3RoZXIucmVwZWF0ZWRTaW50NjRfOwogICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBvdGhlci5yZXBlYXRlZEZpeGVkMzJfOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRml4ZWQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gb3RoZXIucmVwZWF0ZWRGaXhlZDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEZpeGVkNjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2ZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IG90aGVyLnJlcGVhdGVkU2ZpeGVkMzJfOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ZpeGVkMzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2ZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IG90aGVyLnJlcGVhdGVkU2ZpeGVkNjRfOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ZpeGVkNjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRmxvYXRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRmxvYXRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEZsb2F0XyA9IG90aGVyLnJlcGVhdGVkRmxvYXRfOwogICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRmxvYXRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRG91YmxlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZERvdWJsZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IG90aGVyLnJlcGVhdGVkRG91YmxlXzsKICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfLmFkZEFsbChvdGhlci5yZXBlYXRlZERvdWJsZV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRCb29sXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEJvb2xfID0gb3RoZXIucmVwZWF0ZWRCb29sXzsKICAgICAgICAgICAgcmVwZWF0ZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEFsbChvdGhlci5yZXBlYXRlZEJvb2xfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IG90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZEFsbChvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQoaW5wdXQucmVhZEludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZExvbmcoaW5wdXQucmVhZEludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEludChpbnB1dC5yZWFkVUludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzMjogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFVJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyCiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkVUludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MAogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEludChpbnB1dC5yZWFkU0ludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA0ODogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ4CiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA2MTogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MQogICAgICAgICAgICAgIGNhc2UgNTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRJbnQoaW5wdXQucmVhZEZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgICBjYXNlIDY1OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjUKICAgICAgICAgICAgICBjYXNlIDY2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NgogICAgICAgICAgICAgIGNhc2UgNzc6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFNGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzcKICAgICAgICAgICAgICBjYXNlIDc0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQoaW5wdXQucmVhZFNGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MTogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxCiAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBjYXNlIDkzOiB7CiAgICAgICAgICAgICAgICBmbG9hdCB2ID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MwogICAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLmFkZEZsb2F0KGlucHV0LnJlYWRGbG9hdCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICAgIGNhc2UgOTc6IHsKICAgICAgICAgICAgICAgIGRvdWJsZSB2ID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5hZGREb3VibGUodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTcKICAgICAgICAgICAgICBjYXNlIDk4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfLmFkZERvdWJsZShpbnB1dC5yZWFkRG91YmxlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk4CiAgICAgICAgICAgICAgY2FzZSAxMDQ6IHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdiA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8uYWRkQm9vbGVhbih2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDQKICAgICAgICAgICAgICBjYXNlIDEwNjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEJvb2xlYW4oaW5wdXQucmVhZEJvb2woKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA2CiAgICAgICAgICAgICAgY2FzZSAxMTI6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExMgogICAgICAgICAgICAgIGNhc2UgMTE0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE0CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRJbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50MzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkSW50MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZEludDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRJbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRJbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkSW50MzIoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRJbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkSW50NjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRJbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkSW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRJbnQ2NCgpIHsKICAgICAgICByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFVpbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkVWludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFVpbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkVWludDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkVWludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkVWludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkVWludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRVaW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFVpbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRVaW50MzIoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFVpbnQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkVWludDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFVpbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkVWludDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFVpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVWludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRVaW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFVpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkVWludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRVaW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFVpbnQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRVaW50NjQoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTaW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNpbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNpbnQzMigpIHsKICAgICAgICByZXBlYXRlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSA2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFNpbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNpbnQ2NCgpIHsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRml4ZWQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDMyXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpeGVkMzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRml4ZWQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEZpeGVkMzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRGaXhlZDMyKCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkNjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRml4ZWQ2NF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpeGVkNjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZpeGVkNjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRGaXhlZDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRml4ZWQ2NCgpIHsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQzMl8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ZpeGVkMzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNmaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTZml4ZWQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2ZpeGVkMzIoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQ2NF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNmaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ZpeGVkNjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNmaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTZml4ZWQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTZml4ZWQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNmaXhlZDY0KCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRmxvYXRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRmxvYXRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGbG9hdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZsb2F0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZsb2F0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGZsb2F0IGdldFJlcGVhdGVkRmxvYXQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZsb2F0KAogICAgICAgICAgaW50IGluZGV4LCBmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8uc2V0RmxvYXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGbG9hdCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmxvYXQoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfLmFkZEZsb2F0KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZsb2F0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRGbG9hdF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZsb2F0KCkgewogICAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZERvdWJsZV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZERvdWJsZV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWREb3VibGVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWREb3VibGVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZERvdWJsZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZERvdWJsZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWREb3VibGVDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGRvdWJsZSBnZXRSZXBlYXRlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLmdldERvdWJsZShpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAxMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRG91YmxlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWREb3VibGUoCiAgICAgICAgICBpbnQgaW5kZXgsIGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRG91YmxlXy5zZXREb3VibGUoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAxMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZERvdWJsZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRG91YmxlKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRG91YmxlXy5hZGREb3VibGUodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZERvdWJsZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRG91YmxlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZERvdWJsZV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRG91YmxlKCkgewogICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHJlcGVhdGVkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEJvb2xfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkQm9vbF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQm9vbF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkQm9vbF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRCb29sXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2wuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRSZXBlYXRlZEJvb2xMaXN0KCkgewogICAgICAgIHJlcGVhdGVkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCb29sLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJvb2xDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGdldFJlcGVhdGVkQm9vbChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXy5nZXRCb29sZWFuKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJvb2wgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEJvb2woCiAgICAgICAgICBpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCb29sXy5zZXRCb29sZWFuKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJvb2wgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEJvb2woYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkQm9vbCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkQm9vbCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEJvb2xfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQm9vbCgpIHsKICAgICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWROZXN0ZWRFbnVtXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4ocmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+KHJlcGVhdGVkTmVzdGVkRW51bV8sIHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkRW51bSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZEVudW0ocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE5lc3RlZEVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkTmVzdGVkRW51bSgpIHsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZSgKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChpbnQgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdFVucGFja2VkVHlwZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZFR5cGVzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0VW5wYWNrZWRUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RVbnBhY2tlZFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFVucGFja2VkVHlwZXM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFVucGFja2VkVHlwZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0VW5wYWNrZWRUeXBlcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbnBhY2tlZFR5cGVzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbnBhY2tlZFR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdFVucGFja2VkVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBOZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8zX2xpdGVfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQ2hpbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY2hpbGQuCiAgICAgKi8KICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMgZ2V0Q2hpbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldENoaWxkT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcGF5bG9hZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUGF5bG9hZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHBheWxvYWQuCiAgICAgKi8KICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMgZ2V0UGF5bG9hZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRQYXlsb2FkT3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVGhpcyBwcm90byBpbmNsdWRlcyBhIHJlY3Vyc2l2ZWx5IG5lc3RlZCBtZXNzYWdlLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2xpdGVfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTmVzdGVkVGVzdEFsbFR5cGVzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvM19saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcykKICAgICAgTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBOZXN0ZWRUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgTmVzdGVkVGVzdEFsbFR5cGVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgTmVzdGVkVGVzdEFsbFR5cGVzKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE5lc3RlZFRlc3RBbGxUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9OZXN0ZWRUZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLmNsYXNzLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDSElMRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkXzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0NoaWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNoaWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBnZXRDaGlsZCgpIHsKICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRDaGlsZE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQVlMT0FEX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMgcGF5bG9hZF87CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXlsb2FkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUGF5bG9hZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHBheWxvYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzIGdldFBheWxvYWQoKSB7CiAgICAgIHJldHVybiBwYXlsb2FkXyA9PSBudWxsID8gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBheWxvYWRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UGF5bG9hZE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHBheWxvYWRfID09IG51bGwgPyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcGF5bG9hZF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEsIGdldENoaWxkKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMiwgZ2V0UGF5bG9hZCgpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGdldENoaWxkKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBnZXRQYXlsb2FkKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMgb3RoZXIgPSAocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcykgb2JqOwoKICAgICAgaWYgKGhhc0NoaWxkKCkgIT0gb3RoZXIuaGFzQ2hpbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQ2hpbGQoKSkgewogICAgICAgIGlmICghZ2V0Q2hpbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldENoaWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1BheWxvYWQoKSAhPSBvdGhlci5oYXNQYXlsb2FkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1BheWxvYWQoKSkgewogICAgICAgIGlmICghZ2V0UGF5bG9hZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGF5bG9hZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0NoaWxkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDSElMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Q2hpbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNQYXlsb2FkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQVlMT0FEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYXlsb2FkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGlzIHByb3RvIGluY2x1ZGVzIGEgcmVjdXJzaXZlbHkgbmVzdGVkIG1lc3NhZ2UuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzNfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMpCiAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLmNsYXNzLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRDaGlsZEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgY2hpbGRfID0gbnVsbDsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBwYXlsb2FkXyA9IG51bGw7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBidWlsZCgpIHsKICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyByZXN1bHQgPSBuZXcgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNoaWxkXyA9IGNoaWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gY2hpbGRfCiAgICAgICAgICAgICAgOiBjaGlsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucGF5bG9hZF8gPSBwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gcGF5bG9hZF8KICAgICAgICAgICAgICA6IHBheWxvYWRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNDaGlsZCgpKSB7CiAgICAgICAgICBtZXJnZUNoaWxkKG90aGVyLmdldENoaWxkKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUGF5bG9hZCgpKSB7CiAgICAgICAgICBtZXJnZVBheWxvYWQob3RoZXIuZ2V0UGF5bG9hZCgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0Q2hpbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcywgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBjaGlsZEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNoaWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0NoaWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIGdldENoaWxkKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENoaWxkKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGNoaWxkXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENoaWxkKAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGNoaWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlQ2hpbGQocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBjaGlsZF8gIT0gbnVsbCAmJgogICAgICAgICAgICBjaGlsZF8gIT0gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRDaGlsZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY2hpbGRfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGNoaWxkXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ2hpbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGNoaWxkXyA9IG51bGw7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0Q2hpbGRCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0Q2hpbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldENoaWxkT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogY2hpbGRfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcywgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldENoaWxkRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRDaGlsZCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgY2hpbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNoaWxkQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyBwYXlsb2FkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcywgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBwYXlsb2FkQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXlsb2FkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1BheWxvYWQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcGF5bG9hZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzIGdldFBheWxvYWQoKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBwYXlsb2FkXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHBheWxvYWRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBheWxvYWQocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBwYXlsb2FkXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYXlsb2FkKAogICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcGF5bG9hZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VQYXlsb2FkKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSAmJgogICAgICAgICAgICBwYXlsb2FkXyAhPSBudWxsICYmCiAgICAgICAgICAgIHBheWxvYWRfICE9IHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0UGF5bG9hZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGF5bG9hZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChwYXlsb2FkXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYXlsb2FkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBwYXlsb2FkXyA9IG51bGw7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRQYXlsb2FkQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldFBheWxvYWRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UGF5bG9hZE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBwYXlsb2FkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBheWxvYWRfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHBheWxvYWRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldFBheWxvYWQoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHBheWxvYWRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHBheWxvYWRCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfbGl0ZV91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM19saXRlX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5OZXN0ZWRUZXN0QWxsVHlwZXMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLk5lc3RlZFRlc3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZFRlc3RBbGxUeXBlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxOZXN0ZWRUZXN0QWxsVHlwZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBOZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRUZXN0QWxsVHlwZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkVGVzdEFsbFR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuTmVzdGVkVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBjID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjLgogICAgICovCiAgICBpbnQgZ2V0QygpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIERlZmluZSB0aGVzZSBhZnRlciBUZXN0QWxsVHlwZXMgdG8gbWFrZSBzdXJlIHRoZSBjb21waWxlciBjYW4gaGFuZGxlCiAgICogdGhhdC4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRm9yZWlnbk1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UpCiAgICAgIEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBGb3JlaWduTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBGb3JlaWduTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEZvcmVpZ25NZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEZvcmVpZ25NZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UuY2xhc3MsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBjXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0QygpIHsKICAgICAgcmV0dXJuIGNfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKGNfICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBjXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmIChjXyAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBjXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2Ugb3RoZXIgPSAocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlKSBvYmo7CgogICAgICBpZiAoZ2V0QygpCiAgICAgICAgICAhPSBvdGhlci5nZXRDKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QygpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIERlZmluZSB0aGVzZSBhZnRlciBUZXN0QWxsVHlwZXMgdG8gbWFrZSBzdXJlIHRoZSBjb21waWxlciBjYW4gaGFuZGxlCiAgICAgKiB0aGF0LgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2xpdGVfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSkKICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZS5jbGFzcywgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBjXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY18gPSBjXzsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuZ2V0QygpICE9IDApIHsKICAgICAgICAgIHNldEMob3RoZXIuZ2V0QygpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBjXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgY18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgYyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEMoKSB7CiAgICAgICAgcmV0dXJuIGNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBjID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEMoaW50IHZhbHVlKSB7CgogICAgICAgIGNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBjID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgY18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvM19saXRlX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuRm9yZWlnbk1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5Gb3JlaWduTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvcmVpZ25NZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZvcmVpZ25NZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgRm9yZWlnbk1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb3JlaWduTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb3JlaWduTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLkZvcmVpZ25NZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEVtcHR5TWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0RW1wdHlNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRlc3RFbXB0eU1lc3NhZ2UgaXMgdXNlZCB0byB0ZXN0IGJlaGF2aW9yIG9mIHVua25vd24gZmllbGRzLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RFbXB0eU1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZSkKICAgICAgVGVzdEVtcHR5TWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdEVtcHR5TWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0RW1wdHlNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdEVtcHR5TWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0RW1wdHlNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RFbXB0eU1lc3NhZ2UuY2xhc3MsIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0RW1wdHlNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0RW1wdHlNZXNzYWdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSBvdGhlciA9IChwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdEVtcHR5TWVzc2FnZSBpcyB1c2VkIHRvIHRlc3QgYmVoYXZpb3Igb2YgdW5rbm93biBmaWVsZHMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0RW1wdHlNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZSkKICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0RW1wdHlNZXNzYWdlLmNsYXNzLCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0RW1wdHlNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLmludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0RW1wdHlNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0RW1wdHlNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM19saXRlX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zTGl0ZS5UZXN0RW1wdHlNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RFbXB0eU1lc3NhZ2UodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RFbXB0eU1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RFbXB0eU1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RFbXB0eU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX2xpdGVfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzNMaXRlLlRlc3RFbXB0eU1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RW1wdHlNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RFbXB0eU1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0RW1wdHlNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEVtcHR5TWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RW1wdHlNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfbGl0ZV91bml0dGVzdC5Vbml0dGVzdFByb3RvM0xpdGUuVGVzdEVtcHR5TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdFVucGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdFVucGFja2VkVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9OZXN0ZWRUZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwoKICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgIHJldHVybiBkZXNjcmlwdG9yOwogIH0KICBwcml2YXRlIHN0YXRpYyAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBkZXNjcmlwdG9yOwogIHN0YXRpYyB7CiAgICBqYXZhLmxhbmcuU3RyaW5nW10gZGVzY3JpcHRvckRhdGEgPSB7CiAgICAgICJcbipnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX2xpdGUucCIgKwogICAgICAicm90b1wwMjJcMDI0cHJvdG8zX2xpdGVfdW5pdHRlc3RcMDMyJWdvb2dsZS9wcm90byIgKwogICAgICAiYnVmL3VuaXR0ZXN0X2ltcG9ydC5wcm90b1wiXDM1M1wwMjBcblwwMTRUZXN0QWxsVHlwIiArCiAgICAgICJlc1wwMjJcMDI2XG5cMDE2b3B0aW9uYWxfaW50MzJcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXDAyNlxuXDAxNm9wdGlvbmFsX2kiICsKICAgICAgIm50NjRcMDMwXDAwMiBcMDAxKFwwMDNcMDIyXDAyN1xuXDAxN29wdGlvbmFsX3VpbnQzMlwwMzBcMDAzIFwwMDEoXHJcMDIyXDAyN1xuXDAxN28iICsKICAgICAgInB0aW9uYWxfdWludDY0XDAzMFwwMDQgXDAwMShcMDA0XDAyMlwwMjdcblwwMTdvcHRpb25hbF9zaW50MzJcMDMwIiArCiAgICAgICJcMDA1IFwwMDEoXDAyMVwwMjJcMDI3XG5cMDE3b3B0aW9uYWxfc2ludDY0XDAzMFwwMDYgXDAwMShcMDIyXDAyMlwwMzBcblwwMjBvcHRpb24iICsKICAgICAgImFsX2ZpeGVkMzJcMDMwXDAwNyBcMDAxKFwwMDdcMDIyXDAzMFxuXDAyMG9wdGlvbmFsX2ZpeGVkNjRcMDMwXDAxMCBcMDAxIiArCiAgICAgICIoXDAwNlwwMjJcMDMxXG5cMDIxb3B0aW9uYWxfc2ZpeGVkMzJcMDMwXHQgXDAwMShcMDE3XDAyMlwwMzFcblwwMjFvcHRpb25hIiArCiAgICAgICJsX3NmaXhlZDY0XDAzMFxuIFwwMDEoXDAyMFwwMjJcMDI2XG5cMDE2b3B0aW9uYWxfZmxvYXRcMDMwXDAxMyBcMDAxKFwwMDIiICsKICAgICAgIlwwMjJcMDI3XG5cMDE3b3B0aW9uYWxfZG91YmxlXDAzMFwwMTQgXDAwMShcMDAxXDAyMlwwMjVcblxyb3B0aW9uYWxfYm8iICsKICAgICAgIm9sXDAzMFxyIFwwMDEoXDAxMFwwMjJcMDI3XG5cMDE3b3B0aW9uYWxfc3RyaW5nXDAzMFwwMTYgXDAwMShcdFwwMjJcMDI2XG5cMDE2b3B0IiArCiAgICAgICJpb25hbF9ieXRlc1wwMzBcMDE3IFwwMDEoXDAxNFwwMjJRXG5cMDI3b3B0aW9uYWxfbmVzdGVkX21lcyIgKwogICAgICAic2FnZVwwMzBcMDIyIFwwMDEoXDAxMzIwLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBbCIgKwogICAgICAibFR5cGVzLk5lc3RlZE1lc3NhZ2VcMDIyRlxuXDAzMG9wdGlvbmFsX2ZvcmVpZ24iICsKICAgICAgIl9tZXNzYWdlXDAzMFwwMjMgXDAwMShcMDEzMiQucHJvdG8zX2xpdGVfdW5pdHRlc3QuRm8iICsKICAgICAgInJlaWduTWVzc2FnZVwwMjJIXG5cMDI3b3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VcMDMwIiArCiAgICAgICJcMDI0IFwwMDEoXDAxMzJcJy5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TSIgKwogICAgICAiZXNzYWdlXDAyMktcblwwMjRvcHRpb25hbF9uZXN0ZWRfZW51bVwwMzBcMDI1IFwwMDEoXDAxNjItLnAiICsKICAgICAgInJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEUiICsKICAgICAgIm51bVwwMjJAXG5cMDI1b3B0aW9uYWxfZm9yZWlnbl9lbnVtXDAzMFwwMjYgXDAwMShcMDE2MiEucHJvIiArCiAgICAgICJ0bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduRW51bVwwMjIhXG5cMDI1b3B0aW9uYSIgKwogICAgICAibF9zdHJpbmdfcGllY2VcMDMwXDAzMCBcMDAxKFx0QlwwMDJcMDEwXDAwMlwwMjJcMDMxXG5ccm9wdGlvbmFsX2NvciIgKwogICAgICAiZFwwMzBcMDMxIFwwMDEoXHRCXDAwMlwwMTBcMDAxXDAyMlVcblwwMzZvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lIiArCiAgICAgICJzc2FnZVwwMzBcMDMyIFwwMDEoXDAxMzItLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QIiArCiAgICAgICJ1YmxpY0ltcG9ydE1lc3NhZ2VcMDIyU1xuXDAyNW9wdGlvbmFsX2xhenlfbWVzcyIgKwogICAgICAiYWdlXDAzMFwwMzMgXDAwMShcMDEzMjAucHJvdG8zX2xpdGVfdW5pdHRlc3QuVGVzdEFsbCIgKwogICAgICAiVHlwZXMuTmVzdGVkTWVzc2FnZUJcMDAyKFwwMDFcMDIyXDAyNlxuXDAxNnJlcGVhdGVkX2ludDMiICsKICAgICAgIjJcMDMwXDAzNyBcMDAzKFwwMDVcMDIyXDAyNlxuXDAxNnJlcGVhdGVkX2ludDY0XDAzMCAgXDAwMyhcMDAzXDAyMlwwMjdcblwwMTdyZXBlYSIgKwogICAgICAidGVkX3VpbnQzMlwwMzAhIFwwMDMoXHJcMDIyXDAyN1xuXDAxN3JlcGVhdGVkX3VpbnQ2NFwwMzBcIiBcMDAzKCIgKwogICAgICAiXDAwNFwwMjJcMDI3XG5cMDE3cmVwZWF0ZWRfc2ludDMyXDAzMCMgXDAwMyhcMDIxXDAyMlwwMjdcblwwMTdyZXBlYXRlZF9zIiArCiAgICAgICJpbnQ2NFwwMzAkIFwwMDMoXDAyMlwwMjJcMDMwXG5cMDIwcmVwZWF0ZWRfZml4ZWQzMlwwMzAlIFwwMDMoXDAwN1wwMjJcMDMwXG4iICsKICAgICAgIlwwMjByZXBlYXRlZF9maXhlZDY0XDAzMCYgXDAwMyhcMDA2XDAyMlwwMzFcblwwMjFyZXBlYXRlZF9zZml4IiArCiAgICAgICJlZDMyXDAzMFwnIFwwMDMoXDAxN1wwMjJcMDMxXG5cMDIxcmVwZWF0ZWRfc2ZpeGVkNjRcMDMwKCBcMDAzKFwwMjBcMDIyXDAyNlxuIiArCiAgICAgICJcMDE2cmVwZWF0ZWRfZmxvYXRcMDMwKSBcMDAzKFwwMDJcMDIyXDAyN1xuXDAxN3JlcGVhdGVkX2RvdWJsZSIgKwogICAgICAiXDAzMCogXDAwMyhcMDAxXDAyMlwwMjVcblxycmVwZWF0ZWRfYm9vbFwwMzArIFwwMDMoXDAxMFwwMjJcMDI3XG5cMDE3cmVwZWF0ZSIgKwogICAgICAiZF9zdHJpbmdcMDMwLCBcMDAzKFx0XDAyMlwwMjZcblwwMTZyZXBlYXRlZF9ieXRlc1wwMzAtIFwwMDMoXDAxNFwwMjJRIiArCiAgICAgICJcblwwMjdyZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZVwwMzAwIFwwMDMoXDAxMzIwLnByb3RvMyIgKwogICAgICAiX2xpdGVfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZyIgKwogICAgICAiZVwwMjJGXG5cMDMwcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlXDAzMDEgXDAwMyhcMDEzMiQucHIiICsKICAgICAgIm90bzNfbGl0ZV91bml0dGVzdC5Gb3JlaWduTWVzc2FnZVwwMjJIXG5cMDI3cmVwIiArCiAgICAgICJlYXRlZF9pbXBvcnRfbWVzc2FnZVwwMzAyIFwwMDMoXDAxMzJcJy5wcm90b2J1Zl91biIgKwogICAgICAiaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlXDAyMktcblwwMjRyZXBlYXRlZF8iICsKICAgICAgIm5lc3RlZF9lbnVtXDAzMDMgXDAwMyhcMDE2Mi0ucHJvdG8zX2xpdGVfdW5pdHRlc3QiICsKICAgICAgIi5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bVwwMjJAXG5cMDI1cmVwZWF0ZWRfZm9yIiArCiAgICAgICJlaWduX2VudW1cMDMwNCBcMDAzKFwwMTYyIS5wcm90bzNfbGl0ZV91bml0dGVzdC5GIiArCiAgICAgICJvcmVpZ25FbnVtXDAyMiFcblwwMjVyZXBlYXRlZF9zdHJpbmdfcGllY2VcMDMwNiBcMDAzKCIgKwogICAgICAiXHRCXDAwMlwwMTBcMDAyXDAyMlwwMzFcblxycmVwZWF0ZWRfY29yZFwwMzA3IFwwMDMoXHRCXDAwMlwwMTBcMDAxXDAyMlNcblwwMjVyZXBlIiArCiAgICAgICJhdGVkX2xhenlfbWVzc2FnZVwwMzA5IFwwMDMoXDAxMzIwLnByb3RvM19saXRlX3VuIiArCiAgICAgICJpdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VCXDAwMihcMDAxXDAyMlwwMjZcbiIgKwogICAgICAiXDAxNG9uZW9mX3VpbnQzMlwwMzBvIFwwMDEoXHJIXDAwMFwwMjJQXG5cMDI0b25lb2ZfbmVzdGVkX21lIiArCiAgICAgICJzc2FnZVwwMzBwIFwwMDEoXDAxMzIwLnByb3RvM19saXRlX3VuaXR0ZXN0LlRlc3RBIiArCiAgICAgICJsbFR5cGVzLk5lc3RlZE1lc3NhZ2VIXDAwMFwwMjJcMDI2XG5cMDE0b25lb2Zfc3RyaW5nXDAzMCIgKwogICAgICAicSBcMDAxKFx0SFwwMDBcMDIyXDAyNVxuXDAxM29uZW9mX2J5dGVzXDAzMHIgXDAwMShcMDE0SFwwMDBcMDMyXDAzM1xuXHJOZXN0ZWQiICsKICAgICAgIk1lc3NhZ2VcMDIyXG5cblwwMDJiYlwwMzBcMDAxIFwwMDEoXDAwNVwiQ1xuXG5OZXN0ZWRFbnVtXDAyMlwwMTBcblwwMDRaRVIiICsKICAgICAgIk9cMDIwXDAwMFwwMjJcMDA3XG5cMDAzRk9PXDAyMFwwMDFcMDIyXDAwN1xuXDAwM0JBUlwwMjBcMDAyXDAyMlwwMDdcblwwMDNCQVpcMDIwXDAwM1wwMjJcMDIwXG5cMDAzTkVHXDAyMFwzNzdcMzc3IiArCiAgICAgICJcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDAwMUJcclxuXDAxM29uZW9mX2ZpZWxkXCJcMjU1XDAwM1xuXDAxN1Rlc3RQYWNrZWRUeSIgKwogICAgICAicGVzXDAyMlwwMzBcblwwMTRwYWNrZWRfaW50MzJcMDMwWiBcMDAzKFwwMDVCXDAwMlwwMjBcMDAxXDAyMlwwMzBcblwwMTRwYWNrZWRfIiArCiAgICAgICJpbnQ2NFwwMzBbIFwwMDMoXDAwM0JcMDAyXDAyMFwwMDFcMDIyXDAzMVxuXHJwYWNrZWRfdWludDMyXDAzMFxcIFwwMDMoXHJCXDAwMiIgKwogICAgICAiXDAyMFwwMDFcMDIyXDAzMVxuXHJwYWNrZWRfdWludDY0XDAzMF0gXDAwMyhcMDA0QlwwMDJcMDIwXDAwMVwwMjJcMDMxXG5ccnBhY2tlZF8iICsKICAgICAgInNpbnQzMlwwMzBeIFwwMDMoXDAyMUJcMDAyXDAyMFwwMDFcMDIyXDAzMVxuXHJwYWNrZWRfc2ludDY0XDAzMF8gXDAwMyhcMDIyQiIgKwogICAgICAiXDAwMlwwMjBcMDAxXDAyMlwwMzJcblwwMTZwYWNrZWRfZml4ZWQzMlwwMzBgIFwwMDMoXDAwN0JcMDAyXDAyMFwwMDFcMDIyXDAzMlxuXDAxNnBhY2tlIiArCiAgICAgICJkX2ZpeGVkNjRcMDMwYSBcMDAzKFwwMDZCXDAwMlwwMjBcMDAxXDAyMlwwMzNcblwwMTdwYWNrZWRfc2ZpeGVkMzJcMDMwYiIgKwogICAgICAiIFwwMDMoXDAxN0JcMDAyXDAyMFwwMDFcMDIyXDAzM1xuXDAxN3BhY2tlZF9zZml4ZWQ2NFwwMzBjIFwwMDMoXDAyMEJcMDAyXDAyMFwwMDFcMDIyXDAzMFxuIiArCiAgICAgICJcMDE0cGFja2VkX2Zsb2F0XDAzMGQgXDAwMyhcMDAyQlwwMDJcMDIwXDAwMVwwMjJcMDMxXG5ccnBhY2tlZF9kb3VibGUiICsKICAgICAgIlwwMzBlIFwwMDMoXDAwMUJcMDAyXDAyMFwwMDFcMDIyXDAyN1xuXDAxM3BhY2tlZF9ib29sXDAzMGYgXDAwMyhcMDEwQlwwMDJcMDIwXDAwMVwwMjI6XG5cMDEzcCIgKwogICAgICAiYWNrZWRfZW51bVwwMzBnIFwwMDMoXDAxNjIhLnByb3RvM19saXRlX3VuaXR0ZXN0LiIgKwogICAgICAiRm9yZWlnbkVudW1CXDAwMlwwMjBcMDAxXCJcMzM2XDAwM1xuXDAyMVRlc3RVbnBhY2tlZFR5cGVzXDAyMlwwMzJcbiIgKwogICAgICAiXDAxNnJlcGVhdGVkX2ludDMyXDAzMFwwMDEgXDAwMyhcMDA1QlwwMDJcMDIwXDAwMFwwMjJcMDMyXG5cMDE2cmVwZWF0ZWRfaW4iICsKICAgICAgInQ2NFwwMzBcMDAyIFwwMDMoXDAwM0JcMDAyXDAyMFwwMDBcMDIyXDAzM1xuXDAxN3JlcGVhdGVkX3VpbnQzMlwwMzBcMDAzIFwwMDMoXHJCXDAwMiIgKwogICAgICAiXDAyMFwwMDBcMDIyXDAzM1xuXDAxN3JlcGVhdGVkX3VpbnQ2NFwwMzBcMDA0IFwwMDMoXDAwNEJcMDAyXDAyMFwwMDBcMDIyXDAzM1xuXDAxN3JlcGVhIiArCiAgICAgICJ0ZWRfc2ludDMyXDAzMFwwMDUgXDAwMyhcMDIxQlwwMDJcMDIwXDAwMFwwMjJcMDMzXG5cMDE3cmVwZWF0ZWRfc2ludDY0XDAzMCIgKwogICAgICAiXDAwNiBcMDAzKFwwMjJCXDAwMlwwMjBcMDAwXDAyMlwwMzRcblwwMjByZXBlYXRlZF9maXhlZDMyXDAzMFwwMDcgXDAwMyhcMDA3QlwwMDJcMDIwXDAwMFwwMjIiICsKICAgICAgIlwwMzRcblwwMjByZXBlYXRlZF9maXhlZDY0XDAzMFwwMTAgXDAwMyhcMDA2QlwwMDJcMDIwXDAwMFwwMjJcMDM1XG5cMDIxcmVwZWF0ZSIgKwogICAgICAiZF9zZml4ZWQzMlwwMzBcdCBcMDAzKFwwMTdCXDAwMlwwMjBcMDAwXDAyMlwwMzVcblwwMjFyZXBlYXRlZF9zZml4ZWQ2IiArCiAgICAgICI0XDAzMFxuIFwwMDMoXDAyMEJcMDAyXDAyMFwwMDBcMDIyXDAzMlxuXDAxNnJlcGVhdGVkX2Zsb2F0XDAzMFwwMTMgXDAwMyhcMDAyQlwwMDJcMDIwXDAwMFwwMjIiICsKICAgICAgIlwwMzNcblwwMTdyZXBlYXRlZF9kb3VibGVcMDMwXDAxNCBcMDAzKFwwMDFCXDAwMlwwMjBcMDAwXDAyMlwwMzFcblxycmVwZWF0ZWQiICsKICAgICAgIl9ib29sXDAzMFxyIFwwMDMoXDAxMEJcMDAyXDAyMFwwMDBcMDIyT1xuXDAyNHJlcGVhdGVkX25lc3RlZF9lbnVtXDAzMCIgKwogICAgICAiXDAxNiBcMDAzKFwwMTYyLS5wcm90bzNfbGl0ZV91bml0dGVzdC5UZXN0QWxsVHlwZSIgKwogICAgICAicy5OZXN0ZWRFbnVtQlwwMDJcMDIwXDAwMFwiXDIwMlwwMDFcblwwMjJOZXN0ZWRUZXN0QWxsVHlwZXNcMDIyIiArCiAgICAgICI3XG5cMDA1Y2hpbGRcMDMwXDAwMSBcMDAxKFwwMTMyKC5wcm90bzNfbGl0ZV91bml0dGVzdC5OZSIgKwogICAgICAic3RlZFRlc3RBbGxUeXBlc1wwMjIzXG5cMDA3cGF5bG9hZFwwMzBcMDAyIFwwMDEoXDAxMzJcIi5wcm90IiArCiAgICAgICJvM19saXRlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wiXDAzM1xuXDAxNkZvcmVpZ24iICsKICAgICAgIk1lc3NhZ2VcMDIyXHRcblwwMDFjXDAzMFwwMDEgXDAwMShcMDA1XCJcMDIyXG5cMDIwVGVzdEVtcHR5TWVzc2FnZSpSIiArCiAgICAgICJcblwwMTNGb3JlaWduRW51bVwwMjJcMDIwXG5cMDE0Rk9SRUlHTl9aRVJPXDAyMFwwMDBcMDIyXDAxN1xuXDAxM0ZPUkVJIiArCiAgICAgICJHTl9GT09cMDIwXDAwNFwwMjJcMDE3XG5cMDEzRk9SRUlHTl9CQVJcMDIwXDAwNVwwMjJcMDE3XG5cMDEzRk9SRUlHTl9CQVoiICsKICAgICAgIlwwMjBcMDA2QlwwMDJIXDAwM2JcMDA2cHJvdG8zIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuZ2V0RGVzY3JpcHRvcigpLAogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbEludDMyIiwgIk9wdGlvbmFsSW50NjQiLCAiT3B0aW9uYWxVaW50MzIiLCAiT3B0aW9uYWxVaW50NjQiLCAiT3B0aW9uYWxTaW50MzIiLCAiT3B0aW9uYWxTaW50NjQiLCAiT3B0aW9uYWxGaXhlZDMyIiwgIk9wdGlvbmFsRml4ZWQ2NCIsICJPcHRpb25hbFNmaXhlZDMyIiwgIk9wdGlvbmFsU2ZpeGVkNjQiLCAiT3B0aW9uYWxGbG9hdCIsICJPcHRpb25hbERvdWJsZSIsICJPcHRpb25hbEJvb2wiLCAiT3B0aW9uYWxTdHJpbmciLCAiT3B0aW9uYWxCeXRlcyIsICJPcHRpb25hbE5lc3RlZE1lc3NhZ2UiLCAiT3B0aW9uYWxGb3JlaWduTWVzc2FnZSIsICJPcHRpb25hbEltcG9ydE1lc3NhZ2UiLCAiT3B0aW9uYWxOZXN0ZWRFbnVtIiwgIk9wdGlvbmFsRm9yZWlnbkVudW0iLCAiT3B0aW9uYWxTdHJpbmdQaWVjZSIsICJPcHRpb25hbENvcmQiLCAiT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlIiwgIk9wdGlvbmFsTGF6eU1lc3NhZ2UiLCAiUmVwZWF0ZWRJbnQzMiIsICJSZXBlYXRlZEludDY0IiwgIlJlcGVhdGVkVWludDMyIiwgIlJlcGVhdGVkVWludDY0IiwgIlJlcGVhdGVkU2ludDMyIiwgIlJlcGVhdGVkU2ludDY0IiwgIlJlcGVhdGVkRml4ZWQzMiIsICJSZXBlYXRlZEZpeGVkNjQiLCAiUmVwZWF0ZWRTZml4ZWQzMiIsICJSZXBlYXRlZFNmaXhlZDY0IiwgIlJlcGVhdGVkRmxvYXQiLCAiUmVwZWF0ZWREb3VibGUiLCAiUmVwZWF0ZWRCb29sIiwgIlJlcGVhdGVkU3RyaW5nIiwgIlJlcGVhdGVkQnl0ZXMiLCAiUmVwZWF0ZWROZXN0ZWRNZXNzYWdlIiwgIlJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UiLCAiUmVwZWF0ZWRJbXBvcnRNZXNzYWdlIiwgIlJlcGVhdGVkTmVzdGVkRW51bSIsICJSZXBlYXRlZEZvcmVpZ25FbnVtIiwgIlJlcGVhdGVkU3RyaW5nUGllY2UiLCAiUmVwZWF0ZWRDb3JkIiwgIlJlcGVhdGVkTGF6eU1lc3NhZ2UiLCAiT25lb2ZVaW50MzIiLCAiT25lb2ZOZXN0ZWRNZXNzYWdlIiwgIk9uZW9mU3RyaW5nIiwgIk9uZW9mQnl0ZXMiLCAiT25lb2ZGaWVsZCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkJiIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlBhY2tlZEludDMyIiwgIlBhY2tlZEludDY0IiwgIlBhY2tlZFVpbnQzMiIsICJQYWNrZWRVaW50NjQiLCAiUGFja2VkU2ludDMyIiwgIlBhY2tlZFNpbnQ2NCIsICJQYWNrZWRGaXhlZDMyIiwgIlBhY2tlZEZpeGVkNjQiLCAiUGFja2VkU2ZpeGVkMzIiLCAiUGFja2VkU2ZpeGVkNjQiLCAiUGFja2VkRmxvYXQiLCAiUGFja2VkRG91YmxlIiwgIlBhY2tlZEJvb2wiLCAiUGFja2VkRW51bSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJSZXBlYXRlZEludDMyIiwgIlJlcGVhdGVkSW50NjQiLCAiUmVwZWF0ZWRVaW50MzIiLCAiUmVwZWF0ZWRVaW50NjQiLCAiUmVwZWF0ZWRTaW50MzIiLCAiUmVwZWF0ZWRTaW50NjQiLCAiUmVwZWF0ZWRGaXhlZDMyIiwgIlJlcGVhdGVkRml4ZWQ2NCIsICJSZXBlYXRlZFNmaXhlZDMyIiwgIlJlcGVhdGVkU2ZpeGVkNjQiLCAiUmVwZWF0ZWRGbG9hdCIsICJSZXBlYXRlZERvdWJsZSIsICJSZXBlYXRlZEJvb2wiLCAiUmVwZWF0ZWROZXN0ZWRFbnVtIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9OZXN0ZWRUZXN0QWxsVHlwZXNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkNoaWxkIiwgIlBheWxvYWQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM19saXRlX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX2xpdGVfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfbGl0ZV91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LmdldERlc2NyaXB0b3IoKTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhALMLKNU/igsAP4oLACMAAABwcm90bzNfdW5pdHRlc3QvVW5pdHRlc3RQcm90bzMuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X3Byb3RvMy5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG8zX3VuaXR0ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIFVuaXR0ZXN0UHJvdG8zIHsKICBwcml2YXRlIFVuaXR0ZXN0UHJvdG8zKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW19CiAgICovCiAgcHVibGljIGVudW0gRm9yZWlnbkVudW0KICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgLyoqCiAgICAgKiA8Y29kZT5GT1JFSUdOX1pFUk8gPSAwOzwvY29kZT4KICAgICAqLwogICAgRk9SRUlHTl9aRVJPKDApLAogICAgLyoqCiAgICAgKiA8Y29kZT5GT1JFSUdOX0ZPTyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBGT1JFSUdOX0ZPTyg0KSwKICAgIC8qKgogICAgICogPGNvZGU+Rk9SRUlHTl9CQVIgPSA1OzwvY29kZT4KICAgICAqLwogICAgRk9SRUlHTl9CQVIoNSksCiAgICAvKioKICAgICAqIDxjb2RlPkZPUkVJR05fQkFaID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEZPUkVJR05fQkFaKDYpLAogICAgVU5SRUNPR05JWkVEKC0xKSwKICAgIDsKCiAgICAvKioKICAgICAqIDxjb2RlPkZPUkVJR05fWkVSTyA9IDA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT1JFSUdOX1pFUk9fVkFMVUUgPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5GT1JFSUdOX0ZPTyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT1JFSUdOX0ZPT19WQUxVRSA9IDQ7CiAgICAvKioKICAgICAqIDxjb2RlPkZPUkVJR05fQkFSID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPUkVJR05fQkFSX1ZBTFVFID0gNTsKICAgIC8qKgogICAgICogPGNvZGU+Rk9SRUlHTl9CQVogPSA2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9SRUlHTl9CQVpfVkFMVUUgPSA2OwoKCiAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJDYW4ndCBnZXQgdGhlIG51bWJlciBvZiBhbiB1bmtub3duIGVudW0gdmFsdWUuIik7CiAgICAgIH0KICAgICAgcmV0dXJuIHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgc3RhdGljIEZvcmVpZ25FbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgRm9yZWlnbkVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgY2FzZSAwOiByZXR1cm4gRk9SRUlHTl9aRVJPOwogICAgICAgIGNhc2UgNDogcmV0dXJuIEZPUkVJR05fRk9POwogICAgICAgIGNhc2UgNTogcmV0dXJuIEZPUkVJR05fQkFSOwogICAgICAgIGNhc2UgNjogcmV0dXJuIEZPUkVJR05fQkFaOwogICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPEZvcmVpZ25FbnVtPgogICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICBGb3JlaWduRW51bT4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxGb3JlaWduRW51bT4oKSB7CiAgICAgICAgICAgIHB1YmxpYyBGb3JlaWduRW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIEZvcmVpZ25FbnVtLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwoKICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbFN0YXRlRXhjZXB0aW9uKAogICAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBkZXNjcmlwdG9yIG9mIGFuIHVucmVjb2duaXplZCBlbnVtIHZhbHVlLiIpOwogICAgICB9CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICB9CiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZvcmVpZ25FbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgcHVibGljIHN0YXRpYyBGb3JlaWduRW51bSB2YWx1ZU9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICB9CiAgICAgIGlmIChkZXNjLmdldEluZGV4KCkgPT0gLTEpIHsKICAgICAgICByZXR1cm4gVU5SRUNPR05JWkVEOwogICAgICB9CiAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICBwcml2YXRlIEZvcmVpZ25FbnVtKGludCB2YWx1ZSkgewogICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtKQogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBTaW5ndWxhcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+aW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBvcHRpb25hbF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbEludDY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsVWludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT51aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbFVpbnQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbFNpbnQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTaW50NjQuCiAgICAgKi8KICAgIGxvbmcgZ2V0T3B0aW9uYWxTaW50NjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxGaXhlZDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5maXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbEZpeGVkNjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxTZml4ZWQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNmaXhlZDY0LgogICAgICovCiAgICBsb25nIGdldE9wdGlvbmFsU2ZpeGVkNjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGbG9hdC4KICAgICAqLwogICAgZmxvYXQgZ2V0T3B0aW9uYWxGbG9hdCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+ZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRG91YmxlLgogICAgICovCiAgICBkb3VibGUgZ2V0T3B0aW9uYWxEb3VibGUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQm9vbC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRPcHRpb25hbEJvb2woKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFN0cmluZ0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvcHRpb25hbF9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQnl0ZXMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEZvcmVpZ25NZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGb3JlaWduTWVzc2FnZS4KICAgICAqLwogICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbE5lc3RlZEVudW1WYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRFbnVtLgogICAgICovCiAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxGb3JlaWduRW51bS4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsRm9yZWlnbkVudW1WYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bSBnZXRPcHRpb25hbEZvcmVpZ25FbnVtKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZ1BpZWNlLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nUGllY2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsU3RyaW5nUGllY2VCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbENvcmQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxDb3JkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsQ29yZC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxDb3JkQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbExhenlNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbExhenlNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9pbXBvcnRfbWVzc2FnZSA9IDExNSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9pbXBvcnRfbWVzc2FnZSA9IDExNSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2xhenlfaW1wb3J0X21lc3NhZ2UgPSAxMTUgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBSZXBlYXRlZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZEludDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50NjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkSW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkVWludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFVpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkVWludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDY0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UmVwZWF0ZWRVaW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkU2ludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU2ludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDY0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UmVwZWF0ZWRTaW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkNjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRSZXBlYXRlZEZpeGVkNjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNmaXhlZDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkU2ZpeGVkNjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGbG9hdC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PiBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmxvYXQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEZsb2F0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBmbG9hdCBnZXRSZXBlYXRlZEZsb2F0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWREb3VibGUuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+IGdldFJlcGVhdGVkRG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWREb3VibGUuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZERvdWJsZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZG91YmxlIGdldFJlcGVhdGVkRG91YmxlKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2wuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPiBnZXRSZXBlYXRlZEJvb2xMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQm9vbENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2woaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCeXRlcy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEJ5dGVzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQnl0ZXMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiAKICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZT4gCiAgICAgICAgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2U+IAogICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbkVudW0+IGdldFJlcGVhdGVkRm9yZWlnbkVudW1MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGb3JlaWduRW51bS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRm9yZWlnbkVudW1Db3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGb3JlaWduRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bSBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWRGb3JlaWduRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkRm9yZWlnbkVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGb3JlaWduRW51bVZhbHVlKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQ29yZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZENvcmRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRDb3JkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRDb3JkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQ29yZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRDb3JkKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkQ29yZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkQ29yZEJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IAogICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRSZXBlYXRlZExhenlNZXNzYWdlKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZExhenlNZXNzYWdlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlVpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZVaW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDExMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZlVpbnQzMi4KICAgICAqLwogICAgaW50IGdldE9uZW9mVWludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPbmVvZk5lc3RlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZk5lc3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPbmVvZk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZlN0cmluZy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRPbmVvZlN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvbmVvZlN0cmluZy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T25lb2ZTdHJpbmdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZkJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPbmVvZkJ5dGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mQnl0ZXMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPbmVvZkJ5dGVzKCk7CgogICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5PbmVvZkZpZWxkQ2FzZSBnZXRPbmVvZkZpZWxkQ2FzZSgpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRoaXMgcHJvdG8gaW5jbHVkZXMgZXZlcnkgdHlwZSBvZiBmaWVsZCBpbiBib3RoIHNpbmd1bGFyIGFuZCByZXBlYXRlZAogICAqIGZvcm1zLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RBbGxUeXBlcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzKQogICAgICBUZXN0QWxsVHlwZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0QWxsVHlwZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0QWxsVHlwZXMoKSB7CiAgICAgIG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgICBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gMDsKICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSAiIjsKICAgICAgb3B0aW9uYWxDb3JkXyA9ICIiOwogICAgICByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcmVwZWF0ZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRCeXRlc18gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkQ29yZF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0QWxsVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLmNsYXNzLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtfQogICAgICovCiAgICBwdWJsaWMgZW51bSBOZXN0ZWRFbnVtCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgICAvKioKICAgICAgICogPGNvZGU+WkVSTyA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgWkVSTygwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgRk9PKDEpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QkFSID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVIoMiksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVogPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEJBWigzKSwKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEludGVudGlvbmFsbHkgbmVnYXRpdmUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5ORUcgPSAtMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBORUcoLTEpLAogICAgICBVTlJFQ09HTklaRUQoLTEpLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+WkVSTyA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgWkVST19WQUxVRSA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19WQUxVRSA9IDE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9WQUxVRSA9IDI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVogPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBWl9WQUxVRSA9IDM7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBJbnRlbnRpb25hbGx5IG5lZ2F0aXZlLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+TkVHID0gLTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkVHX1ZBTFVFID0gLTE7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBudW1iZXIgb2YgYW4gdW5rbm93biBlbnVtIHZhbHVlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIFpFUk87CiAgICAgICAgICBjYXNlIDE6IHJldHVybiBGT087CiAgICAgICAgICBjYXNlIDI6IHJldHVybiBCQVI7CiAgICAgICAgICBjYXNlIDM6IHJldHVybiBCQVo7CiAgICAgICAgICBjYXNlIC0xOiByZXR1cm4gTkVHOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIE5lc3RlZEVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxOZXN0ZWRFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgTmVzdGVkRW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gTmVzdGVkRW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IHRoZSBkZXNjcmlwdG9yIG9mIGFuIHVucmVjb2duaXplZCBlbnVtIHZhbHVlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgICB9CiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBOZXN0ZWRFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICBpZiAoZGVzYy5nZXRJbmRleCgpID09IC0xKSB7CiAgICAgICAgICByZXR1cm4gVU5SRUNPR05JWkVEOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBOZXN0ZWRFbnVtKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtKQogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAqIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCiAgICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+aW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYmIuCiAgICAgICAqLwogICAgICBpbnQgZ2V0QmIoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZE1lc3NhZ2UgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkKICAgICAgICBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBOZXN0ZWRNZXNzYWdlKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQl9GSUVMRF9OVU1CRVIgPSAxOwogICAgICBwcml2YXRlIGludCBiYl8gPSAwOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICogVGhpcyBmaWxlIG5lZWRzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIHRvIHRlc3QgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5pbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBiYi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRCYigpIHsKICAgICAgICByZXR1cm4gYmJfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChiYl8gIT0gMCkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgYmJfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKGJiXyAhPSAwKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgYmJfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICAgIGlmIChnZXRCYigpCiAgICAgICAgICAgICE9IG90aGVyLmdldEJiKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEJiKCk7CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKQogICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmNsYXNzLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgYmJfID0gMDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQuYmJfID0gYmJfOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSlvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmdldEJiKCkgIT0gMCkgewogICAgICAgICAgICBzZXRCYihvdGhlci5nZXRCYigpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgICBiYl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCBiYl8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqCiAgICAgICAgICogPGNvZGU+aW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBiYi4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRCYigpIHsKICAgICAgICAgIHJldHVybiBiYl87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqCiAgICAgICAgICogPGNvZGU+aW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJiIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmIoaW50IHZhbHVlKSB7CgogICAgICAgICAgYmJfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIDxjb2RlPmludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQmIoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBiYl8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE5lc3RlZE1lc3NhZ2U+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTmVzdGVkTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwcml2YXRlIGludCBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb25lb2ZGaWVsZF87CiAgICBwdWJsaWMgZW51bSBPbmVvZkZpZWxkQ2FzZQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2UuSW50ZXJuYWxPbmVPZkVudW0gewogICAgICBPTkVPRl9VSU5UMzIoMTExKSwKICAgICAgT05FT0ZfTkVTVEVEX01FU1NBR0UoMTEyKSwKICAgICAgT05FT0ZfU1RSSU5HKDExMyksCiAgICAgIE9ORU9GX0JZVEVTKDExNCksCiAgICAgIE9ORU9GRklFTERfTk9UX1NFVCgwKTsKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CiAgICAgIHByaXZhdGUgT25lb2ZGaWVsZENhc2UoaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWJlciBvZiB0aGUgZW51bSB0byBsb29rIGZvci4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWJlci4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBPbmVvZkZpZWxkQ2FzZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIE9uZW9mRmllbGRDYXNlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDExMTogcmV0dXJuIE9ORU9GX1VJTlQzMjsKICAgICAgICAgIGNhc2UgMTEyOiByZXR1cm4gT05FT0ZfTkVTVEVEX01FU1NBR0U7CiAgICAgICAgICBjYXNlIDExMzogcmV0dXJuIE9ORU9GX1NUUklORzsKICAgICAgICAgIGNhc2UgMTE0OiByZXR1cm4gT05FT0ZfQllURVM7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBPTkVPRkZJRUxEX05PVF9TRVQ7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIE9uZW9mRmllbGRDYXNlCiAgICBnZXRPbmVvZkZpZWxkQ2FzZSgpIHsKICAgICAgcmV0dXJuIE9uZW9mRmllbGRDYXNlLmZvck51bWJlcigKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UMzJfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzJfID0gMDsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFNpbmd1bGFyCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5pbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UNjRfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbEludDY0XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBvcHRpb25hbF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxJbnQ2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50NjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VJTlQzMl9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIG9wdGlvbmFsX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfVUlOVDY0X0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxVaW50NjRfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbFVpbnQ2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TSU5UMzJfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsU2ludDMyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnNpbnQzMiBvcHRpb25hbF9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsU2ludDMyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxTaW50MzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NJTlQ2NF9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsU2ludDY0XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5zaW50NjQgb3B0aW9uYWxfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxTaW50NjQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFNpbnQ2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxGaXhlZDMyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPmZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsRml4ZWQzMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsRml4ZWQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSA4OwogICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsRml4ZWQ2NF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+Zml4ZWQ2NCBvcHRpb25hbF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZpeGVkNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsRml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsRml4ZWQ2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0ZJWEVEMzJfRklFTERfTlVNQkVSID0gOTsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsU2ZpeGVkMzJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+c2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ZpeGVkMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxTZml4ZWQzMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsU2ZpeGVkMzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NGSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDEwOwogICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsU2ZpeGVkNjRfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPnNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsU2ZpeGVkNjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0ZMT0FUX0ZJRUxEX05VTUJFUiA9IDExOwogICAgcHJpdmF0ZSBmbG9hdCBvcHRpb25hbEZsb2F0XyA9IDBGOwogICAgLyoqCiAgICAgKiA8Y29kZT5mbG9hdCBvcHRpb25hbF9mbG9hdCA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRPcHRpb25hbEZsb2F0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGbG9hdF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRE9VQkxFX0ZJRUxEX05VTUJFUiA9IDEyOwogICAgcHJpdmF0ZSBkb3VibGUgb3B0aW9uYWxEb3VibGVfID0gMEQ7CiAgICAvKioKICAgICAqIDxjb2RlPmRvdWJsZSBvcHRpb25hbF9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbERvdWJsZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRPcHRpb25hbERvdWJsZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsRG91YmxlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9CT09MX0ZJRUxEX05VTUJFUiA9IDEzOwogICAgcHJpdmF0ZSBib29sZWFuIG9wdGlvbmFsQm9vbF8gPSBmYWxzZTsKICAgIC8qKgogICAgICogPGNvZGU+Ym9vbCBvcHRpb25hbF9ib29sID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCb29sLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRPcHRpb25hbEJvb2woKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEJvb2xfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NUUklOR19GSUVMRF9OVU1CRVIgPSAxNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHM7CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsU3RyaW5nQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9CWVRFU19GSUVMRF9OVU1CRVIgPSAxNTsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIG9wdGlvbmFsQnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvcHRpb25hbF9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQnl0ZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T3B0aW9uYWxCeXRlcygpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsQnl0ZXNfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDE4OwogICAgcHJpdmF0ZSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0ZPUkVJR05fTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAxOTsKICAgIHByaXZhdGUgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGb3JlaWduTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25NZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyA9PSBudWxsID8gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxGb3JlaWduTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyA9PSBudWxsID8gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxGb3JlaWduTWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU1QT1JUX01FU1NBR0VfRklFTERfTlVNQkVSID0gMjA7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxJbXBvcnRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEltcG9ydE1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUiA9IDIxOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRFbnVtXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlc3VsdCA9IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5mb3JOdW1iZXIob3B0aW9uYWxOZXN0ZWRFbnVtXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRk9SRUlHTl9FTlVNX0ZJRUxEX05VTUJFUiA9IDIyOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxGb3JlaWduRW51bV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxGb3JlaWduRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldE9wdGlvbmFsRm9yZWlnbkVudW1WYWx1ZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbkVudW1fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bSBnZXRPcHRpb25hbEZvcmVpZ25FbnVtKCkgewogICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtLmZvck51bWJlcihvcHRpb25hbEZvcmVpZ25FbnVtXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU1RSSU5HX1BJRUNFX0ZJRUxEX05VTUJFUiA9IDI0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmdQaWVjZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ1BpZWNlXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gczsKICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmdQaWVjZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsU3RyaW5nUGllY2VCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ1BpZWNlXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9DT1JEX0ZJRUxEX05VTUJFUiA9IDI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxDb3JkXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQ29yZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxDb3JkKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsQ29yZF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBvcHRpb25hbENvcmRfID0gczsKICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbENvcmQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbENvcmRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbENvcmRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBvcHRpb25hbENvcmRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfUFVCTElDX0lNUE9SVF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDI2OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9MQVpZX01FU1NBR0VfRklFTERfTlVNQkVSID0gMjc7CiAgICBwcml2YXRlIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxMYXp5TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID09IG51bGwgPyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbExhenlNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VOVkVSSUZJRURfTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDI4OwogICAgcHJpdmF0ZSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfID09IG51bGwgPyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfID09IG51bGwgPyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfTEFaWV9JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAxMTU7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9pbXBvcnRfbWVzc2FnZSA9IDExNSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2xhenlfaW1wb3J0X21lc3NhZ2UgPSAxMTUgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9pbXBvcnRfbWVzc2FnZSA9IDExNSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAzMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRJbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUmVwZWF0ZWQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkSW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBSZXBlYXRlZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDMyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRJbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+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+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdldFJlcGVhdGVkQm9vbChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDQ0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZ18gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZy4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZ0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQllURVNfRklFTERfTlVNQkVSID0gNDU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiByZXBlYXRlZEJ5dGVzXyA9CiAgICAgICAgZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCeXRlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCeXRlc0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCeXRlcyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gNDg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9GT1JFSUdOX01FU1NBR0VfRklFTERfTlVNQkVSID0gNDk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlPiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2U+IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfSU1QT1JUX01FU1NBR0VfRklFTERfTlVNQkVSID0gNTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2U+IHJlcGVhdGVkSW1wb3J0TWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlPiBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUiA9IDUxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZE5lc3RlZEVudW1fOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlc3VsdCA9IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocmVwZWF0ZWROZXN0ZWRFbnVtXywgcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCkpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCByZXBlYXRlZE5lc3RlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0ZPUkVJR05fRU5VTV9GSUVMRF9OVU1CRVIgPSA1MjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWRGb3JlaWduRW51bV87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtPiByZXBlYXRlZEZvcmVpZ25FbnVtX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtIHJlc3VsdCA9IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbkVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtPiBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bT4ocmVwZWF0ZWRGb3JlaWduRW51bV8sIHJlcGVhdGVkRm9yZWlnbkVudW1fY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGb3JlaWduRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25FbnVtXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bSBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRGb3JlaWduRW51bV8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWRGb3JlaWduRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UmVwZWF0ZWRGb3JlaWduRW51bVZhbHVlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbkVudW1fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZEZvcmVpZ25FbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25FbnVtXy5nZXQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcmVwZWF0ZWRGb3JlaWduRW51bU1lbW9pemVkU2VyaWFsaXplZFNpemU7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HX1BJRUNFX0ZJRUxEX05VTUJFUiA9IDU0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZ1BpZWNlXyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZ1BpZWNlLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nUGllY2VDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0NPUkRfRklFTERfTlVNQkVSID0gNTU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkQ29yZF8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZENvcmQuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkQ29yZExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZENvcmRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQ29yZC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZENvcmRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRDb3JkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRDb3JkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZENvcmQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRDb3JkQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZENvcmRfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0xBWllfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSA1NzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IHJlcGVhdGVkTGF6eU1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiBnZXRSZXBlYXRlZExhenlNZXNzYWdlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZExhenlNZXNzYWdlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FT0ZfVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDExMTsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDExMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mVWludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZVaW50MzIoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTExOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mVWludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9uZW9mVWludDMyKCkgewogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMSkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDExMjsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTI7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9uZW9mTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICAgcmV0dXJuIChwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9uZW9mTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICAgcmV0dXJuIChwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FT0ZfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDExMzsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZTdHJpbmcoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mU3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPbmVvZlN0cmluZygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICByZWYgPSBvbmVvZkZpZWxkXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPbmVvZlN0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9CWVRFU19GSUVMRF9OVU1CRVIgPSAxMTQ7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mQnl0ZXMoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDExNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZkJ5dGVzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9uZW9mQnl0ZXMoKSB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0KSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBpZiAob3B0aW9uYWxJbnQzMl8gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIG9wdGlvbmFsSW50MzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxJbnQ2NF8gIT0gMEwpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgyLCBvcHRpb25hbEludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsVWludDMyXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKDMsIG9wdGlvbmFsVWludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsVWludDY0XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCg0LCBvcHRpb25hbFVpbnQ2NF8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbFNpbnQzMl8gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQzMig1LCBvcHRpb25hbFNpbnQzMl8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbFNpbnQ2NF8gIT0gMEwpIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50NjQoNiwgb3B0aW9uYWxTaW50NjRfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxGaXhlZDMyXyAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMig3LCBvcHRpb25hbEZpeGVkMzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxGaXhlZDY0XyAhPSAwTCkgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjQoOCwgb3B0aW9uYWxGaXhlZDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ZpeGVkMzJfICE9IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQzMig5LCBvcHRpb25hbFNmaXhlZDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ZpeGVkNjRfICE9IDBMKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjQoMTAsIG9wdGlvbmFsU2ZpeGVkNjRfKTsKICAgICAgfQogICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKG9wdGlvbmFsRmxvYXRfKSAhPSAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMTEsIG9wdGlvbmFsRmxvYXRfKTsKICAgICAgfQogICAgICBpZiAoamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb1Jhd0xvbmdCaXRzKG9wdGlvbmFsRG91YmxlXykgIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgxMiwgb3B0aW9uYWxEb3VibGVfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxCb29sXyAhPSBmYWxzZSkgewogICAgICAgIG91dHB1dC53cml0ZUJvb2woMTMsIG9wdGlvbmFsQm9vbF8pOwogICAgICB9CiAgICAgIGlmICghY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuaXNTdHJpbmdFbXB0eShvcHRpb25hbFN0cmluZ18pKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxNCwgb3B0aW9uYWxTdHJpbmdfKTsKICAgICAgfQogICAgICBpZiAoIW9wdGlvbmFsQnl0ZXNfLmlzRW1wdHkoKSkgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDE1LCBvcHRpb25hbEJ5dGVzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxOCwgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTksIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyMCwgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbE5lc3RlZEVudW1fICE9IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5aRVJPLmdldE51bWJlcigpKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgyMSwgb3B0aW9uYWxOZXN0ZWRFbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbkVudW1fICE9IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bS5GT1JFSUdOX1pFUk8uZ2V0TnVtYmVyKCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDIyLCBvcHRpb25hbEZvcmVpZ25FbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KG9wdGlvbmFsU3RyaW5nUGllY2VfKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjQsIG9wdGlvbmFsU3RyaW5nUGllY2VfKTsKICAgICAgfQogICAgICBpZiAoIWNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmlzU3RyaW5nRW1wdHkob3B0aW9uYWxDb3JkXykpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDI1LCBvcHRpb25hbENvcmRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDI2LCBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyNywgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDI4LCBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjUwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyTm9UYWcocmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjU4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDY0Tm9UYWcocmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkVWludDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyNjYpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkVWludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI3NCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRVaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NE5vVGFnKHJlcGVhdGVkVWludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI4Mik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRTaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQzMk5vVGFnKHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjkwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZFNpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0Tm9UYWcocmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI5OCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWRGaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZpeGVkMzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMk5vVGFnKHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMDYpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkRml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjROb1RhZyhyZXBlYXRlZEZpeGVkNjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMTQpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkU2ZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ZpeGVkMzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzJOb1RhZyhyZXBlYXRlZFNmaXhlZDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygzMjIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHJlcGVhdGVkU2ZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ZpeGVkNjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjROb1RhZyhyZXBlYXRlZFNmaXhlZDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzMwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEZsb2F0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZsb2F0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0Tm9UYWcocmVwZWF0ZWRGbG9hdF8uZ2V0RmxvYXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzM4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZERvdWJsZU1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWREb3VibGVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlTm9UYWcocmVwZWF0ZWREb3VibGVfLmdldERvdWJsZShpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQm9vbExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMzQ2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQm9vbF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sTm9UYWcocmVwZWF0ZWRCb29sXy5nZXRCb29sZWFuKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNDQsIHJlcGVhdGVkU3RyaW5nXy5nZXRSYXcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcyg0NSwgcmVwZWF0ZWRCeXRlc18uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDQ4LCByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNDksIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg1MCwgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDQxMCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocmVwZWF0ZWROZXN0ZWRFbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bU5vVGFnKHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNDE4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhyZXBlYXRlZEZvcmVpZ25FbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZvcmVpZ25FbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW1Ob1RhZyhyZXBlYXRlZEZvcmVpZ25FbnVtXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDU0LCByZXBlYXRlZFN0cmluZ1BpZWNlXy5nZXRSYXcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRDb3JkXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNTUsIHJlcGVhdGVkQ29yZF8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTGF6eU1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg1NywgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigKICAgICAgICAgICAgMTExLCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfKSk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDExMiwgKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMTMsIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNCkgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKAogICAgICAgICAgICAxMTQsIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDExNSwgZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKG9wdGlvbmFsSW50MzJfICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIG9wdGlvbmFsSW50MzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxJbnQ2NF8gIT0gMEwpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplKDIsIG9wdGlvbmFsSW50NjRfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxVaW50MzJfICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSgzLCBvcHRpb25hbFVpbnQzMl8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbFVpbnQ2NF8gIT0gMEwpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDY0U2l6ZSg0LCBvcHRpb25hbFVpbnQ2NF8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbFNpbnQzMl8gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTSW50MzJTaXplKDUsIG9wdGlvbmFsU2ludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsU2ludDY0XyAhPSAwTCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTSW50NjRTaXplKDYsIG9wdGlvbmFsU2ludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsRml4ZWQzMl8gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGaXhlZDMyU2l6ZSg3LCBvcHRpb25hbEZpeGVkMzJfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxGaXhlZDY0XyAhPSAwTCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGaXhlZDY0U2l6ZSg4LCBvcHRpb25hbEZpeGVkNjRfKTsKICAgICAgfQogICAgICBpZiAob3B0aW9uYWxTZml4ZWQzMl8gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTRml4ZWQzMlNpemUoOSwgb3B0aW9uYWxTZml4ZWQzMl8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbFNmaXhlZDY0XyAhPSAwTCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTRml4ZWQ2NFNpemUoMTAsIG9wdGlvbmFsU2ZpeGVkNjRfKTsKICAgICAgfQogICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9SYXdJbnRCaXRzKG9wdGlvbmFsRmxvYXRfKSAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZsb2F0U2l6ZSgxMSwgb3B0aW9uYWxGbG9hdF8pOwogICAgICB9CiAgICAgIGlmIChqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvUmF3TG9uZ0JpdHMob3B0aW9uYWxEb3VibGVfKSAhPSAwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZURvdWJsZVNpemUoMTIsIG9wdGlvbmFsRG91YmxlXyk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsQm9vbF8gIT0gZmFsc2UpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQm9vbFNpemUoMTMsIG9wdGlvbmFsQm9vbF8pOwogICAgICB9CiAgICAgIGlmICghY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuaXNTdHJpbmdFbXB0eShvcHRpb25hbFN0cmluZ18pKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxNCwgb3B0aW9uYWxTdHJpbmdfKTsKICAgICAgfQogICAgICBpZiAoIW9wdGlvbmFsQnl0ZXNfLmlzRW1wdHkoKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemUoMTUsIG9wdGlvbmFsQnl0ZXNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTgsIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTksIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwLCBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkRW51bV8gIT0gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlpFUk8uZ2V0TnVtYmVyKCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMjEsIG9wdGlvbmFsTmVzdGVkRW51bV8pOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25FbnVtXyAhPSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbkVudW0uRk9SRUlHTl9aRVJPLmdldE51bWJlcigpKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDIyLCBvcHRpb25hbEZvcmVpZ25FbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KG9wdGlvbmFsU3RyaW5nUGllY2VfKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMjQsIG9wdGlvbmFsU3RyaW5nUGllY2VfKTsKICAgICAgfQogICAgICBpZiAoIWNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmlzU3RyaW5nRW1wdHkob3B0aW9uYWxDb3JkXykpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDI1LCBvcHRpb25hbENvcmRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjYsIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjcsIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDI4LCBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcocmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkSW50MzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplTm9UYWcocmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkSW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcocmVwZWF0ZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZFVpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZFVpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemVOb1RhZyhyZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkU2ludDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkU2ludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZU5vVGFnKHJlcGVhdGVkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkU2ludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkU2ludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZEZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkRml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZFNmaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkRmxvYXRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRGbG9hdE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkRG91YmxlTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHJlcGVhdGVkRG91YmxlTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gMSAqIGdldFJlcGVhdGVkQm9vbExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkQm9vbExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZ18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmdfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRTdHJpbmdMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemVOb1RhZyhyZXBlYXRlZEJ5dGVzXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkQnl0ZXNMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0OCwgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDksIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUwLCByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkuaXNFbXB0eSgpKSB7ICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH1yZXBlYXRlZE5lc3RlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZvcmVpZ25FbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocmVwZWF0ZWRGb3JlaWduRW51bV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFJlcGVhdGVkRm9yZWlnbkVudW1MaXN0KCkuaXNFbXB0eSgpKSB7ICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH1yZXBlYXRlZEZvcmVpZ25FbnVtTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmdQaWVjZV8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQ29yZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRDb3JkXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkQ29yZExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZExhenlNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1NywgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKAogICAgICAgICAgICAgIDExMSwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSBvbmVvZkZpZWxkXykpOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExMiwgKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxMTMsIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemUoCiAgICAgICAgICAgICAgMTE0LCAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExNSwgZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIG90aGVyID0gKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMpIG9iajsKCiAgICAgIGlmIChnZXRPcHRpb25hbEludDMyKCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQ2NCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsVWludDMyKCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsVWludDY0KCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsU2ludDMyKCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsU2ludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsU2ludDY0KCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsU2ludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsRml4ZWQzMigpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEZpeGVkMzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0T3B0aW9uYWxGaXhlZDY0KCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsRml4ZWQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChnZXRPcHRpb25hbFNmaXhlZDMyKCkKICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsU2ZpeGVkMzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFNmaXhlZDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhnZXRPcHRpb25hbEZsb2F0KCkpCiAgICAgICAgICAhPSBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgb3RoZXIuZ2V0T3B0aW9uYWxGbG9hdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldE9wdGlvbmFsRG91YmxlKCkpCiAgICAgICAgICAhPSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoCiAgICAgICAgICAgICAgb3RoZXIuZ2V0T3B0aW9uYWxEb3VibGUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGdldE9wdGlvbmFsQm9vbCgpCiAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEJvb2woKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldE9wdGlvbmFsU3RyaW5nKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxTdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRPcHRpb25hbEJ5dGVzKCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxCeXRlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChvcHRpb25hbE5lc3RlZEVudW1fICE9IG90aGVyLm9wdGlvbmFsTmVzdGVkRW51bV8pIHJldHVybiBmYWxzZTsKICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbkVudW1fICE9IG90aGVyLm9wdGlvbmFsRm9yZWlnbkVudW1fKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZSgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsU3RyaW5nUGllY2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRPcHRpb25hbENvcmQoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbENvcmQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbExhenlNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbExhenlNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoKSAhPSBvdGhlci5oYXNPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkSW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZsb2F0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRmxvYXRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRCb29sTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQm9vbExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZ0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQnl0ZXNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFyZXBlYXRlZE5lc3RlZEVudW1fLmVxdWFscyhvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXJlcGVhdGVkRm9yZWlnbkVudW1fLmVxdWFscyhvdGhlci5yZXBlYXRlZEZvcmVpZ25FbnVtXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nUGllY2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQ29yZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZExhenlNZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkTGF6eU1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0T25lb2ZGaWVsZENhc2UoKS5lcXVhbHMob3RoZXIuZ2V0T25lb2ZGaWVsZENhc2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgc3dpdGNoIChvbmVvZkZpZWxkQ2FzZV8pIHsKICAgICAgICBjYXNlIDExMToKICAgICAgICAgIGlmIChnZXRPbmVvZlVpbnQzMigpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T25lb2ZVaW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMTI6CiAgICAgICAgICBpZiAoIWdldE9uZW9mTmVzdGVkTWVzc2FnZSgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTEzOgogICAgICAgICAgaWYgKCFnZXRPbmVvZlN0cmluZygpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPbmVvZlN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMTQ6CiAgICAgICAgICBpZiAoIWdldE9uZW9mQnl0ZXMoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T25lb2ZCeXRlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzIoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0T3B0aW9uYWxJbnQ2NCgpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxVaW50MzIoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgIGdldE9wdGlvbmFsVWludDY0KCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TSU5UMzJfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFNpbnQzMigpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TSU5UNjRfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgZ2V0T3B0aW9uYWxTaW50NjQoKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEZpeGVkMzIoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBnZXRPcHRpb25hbEZpeGVkNjQoKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1NGSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxTZml4ZWQzMigpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBnZXRPcHRpb25hbFNmaXhlZDY0KCkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9GTE9BVF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgIGdldE9wdGlvbmFsRmxvYXQoKSk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0T3B0aW9uYWxEb3VibGUoKSkpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9CT09MX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgIGdldE9wdGlvbmFsQm9vbCgpKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9CWVRFU19GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRk9SRUlHTl9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIG9wdGlvbmFsTmVzdGVkRW51bV87CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0ZPUkVJR05fRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIG9wdGlvbmFsRm9yZWlnbkVudW1fOwogICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TVFJJTkdfUElFQ0VfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFN0cmluZ1BpZWNlKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfQ09SRF9GSUVMRF9OVU1CRVI7CiAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsQ29yZCgpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1BVQkxJQ19JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1VOVkVSSUZJRURfTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0xBWllfSU1QT1JUX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9JTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9JTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFVpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFVpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfVUlOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZpeGVkNjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNmaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TRklYRUQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNmaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZsb2F0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GTE9BVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZERvdWJsZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRE9VQkxFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEJvb2xDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0JPT0xfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkQm9vbExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFN0cmluZ0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEJ5dGVzQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9CWVRFU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRCeXRlc0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRk9SRUlHTl9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU1QT1JUX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZE5lc3RlZEVudW1Db3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXBlYXRlZE5lc3RlZEVudW1fLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRm9yZWlnbkVudW1Db3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZPUkVJR05fRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcmVwZWF0ZWRGb3JlaWduRW51bV8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HX1BJRUNFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQ29yZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQ09SRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0xBWllfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIHN3aXRjaCAob25lb2ZGaWVsZENhc2VfKSB7CiAgICAgICAgY2FzZSAxMTE6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPTkVPRl9VSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZVaW50MzIoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTEyOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTEzOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mU3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTE0OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfQllURVNfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZCeXRlcygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGlzIHByb3RvIGluY2x1ZGVzIGV2ZXJ5IHR5cGUgb2YgZmllbGQgaW4gYm90aCBzaW5ndWxhciBhbmQgcmVwZWF0ZWQKICAgICAqIGZvcm1zLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMpCiAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuY2xhc3MsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgYml0RmllbGQxXyA9IDA7CiAgICAgICAgb3B0aW9uYWxJbnQzMl8gPSAwOwogICAgICAgIG9wdGlvbmFsSW50NjRfID0gMEw7CiAgICAgICAgb3B0aW9uYWxVaW50MzJfID0gMDsKICAgICAgICBvcHRpb25hbFVpbnQ2NF8gPSAwTDsKICAgICAgICBvcHRpb25hbFNpbnQzMl8gPSAwOwogICAgICAgIG9wdGlvbmFsU2ludDY0XyA9IDBMOwogICAgICAgIG9wdGlvbmFsRml4ZWQzMl8gPSAwOwogICAgICAgIG9wdGlvbmFsRml4ZWQ2NF8gPSAwTDsKICAgICAgICBvcHRpb25hbFNmaXhlZDMyXyA9IDA7CiAgICAgICAgb3B0aW9uYWxTZml4ZWQ2NF8gPSAwTDsKICAgICAgICBvcHRpb25hbEZsb2F0XyA9IDBGOwogICAgICAgIG9wdGlvbmFsRG91YmxlXyA9IDBEOwogICAgICAgIG9wdGlvbmFsQm9vbF8gPSBmYWxzZTsKICAgICAgICBvcHRpb25hbFN0cmluZ18gPSAiIjsKICAgICAgICBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDA7CiAgICAgICAgb3B0aW9uYWxGb3JlaWduRW51bV8gPSAwOwogICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gIiI7CiAgICAgICAgb3B0aW9uYWxDb3JkXyA9ICIiOwogICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ18gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRCeXRlc18gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDIwMDApOwogICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIHJlcGVhdGVkQ29yZF8gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMgcmVzdWx0ID0gbmV3IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXModGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDFfICE9IDApIHsgYnVpbGRQYXJ0aWFsMShyZXN1bHQpOyB9CiAgICAgICAgYnVpbGRQYXJ0aWFsT25lb2ZzKHJlc3VsdCk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIHJlc3VsdCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkTmVzdGVkRW51bV8gPSByZXBlYXRlZE5lc3RlZEVudW1fOwogICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEZvcmVpZ25FbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5yZXBlYXRlZEZvcmVpZ25FbnVtXyA9IHJlcGVhdGVkRm9yZWlnbkVudW1fOwogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRMYXp5TWVzc2FnZV8pOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSByZXBlYXRlZExhenlNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMl8gPSBvcHRpb25hbEludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDY0XyA9IG9wdGlvbmFsSW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVWludDMyXyA9IG9wdGlvbmFsVWludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQ2NF8gPSBvcHRpb25hbFVpbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTaW50MzJfID0gb3B0aW9uYWxTaW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsU2ludDY0XyA9IG9wdGlvbmFsU2ludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEZpeGVkMzJfID0gb3B0aW9uYWxGaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEZpeGVkNjRfID0gb3B0aW9uYWxGaXhlZDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFNmaXhlZDMyXyA9IG9wdGlvbmFsU2ZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsU2ZpeGVkNjRfID0gb3B0aW9uYWxTZml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxGbG9hdF8gPSBvcHRpb25hbEZsb2F0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbERvdWJsZV8gPSBvcHRpb25hbERvdWJsZV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxCb29sXyA9IG9wdGlvbmFsQm9vbF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTdHJpbmdfID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsQnl0ZXNfID0gb3B0aW9uYWxCeXRlc187CiAgICAgICAgfQogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEltcG9ydE1lc3NhZ2VfID0gb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxJbXBvcnRNZXNzYWdlXwogICAgICAgICAgICAgIDogb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbE5lc3RlZEVudW1fID0gb3B0aW9uYWxOZXN0ZWRFbnVtXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEZvcmVpZ25FbnVtXyA9IG9wdGlvbmFsRm9yZWlnbkVudW1fOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsU3RyaW5nUGllY2VfID0gb3B0aW9uYWxTdHJpbmdQaWVjZV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxDb3JkXyA9IG9wdGlvbmFsQ29yZF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxMYXp5TWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyA9IG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV8gPSBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW50MzJfID0gcmVwZWF0ZWRJbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbnQ2NF8gPSByZXBlYXRlZEludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRVaW50MzJfID0gcmVwZWF0ZWRVaW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFVpbnQ2NF8gPSByZXBlYXRlZFVpbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2ludDMyXyA9IHJlcGVhdGVkU2ludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTaW50NjRfID0gcmVwZWF0ZWRTaW50NjRfOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMV8gPSBiaXRGaWVsZDFfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZpeGVkMzJfID0gcmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRml4ZWQ2NF8gPSByZXBlYXRlZEZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2ZpeGVkMzJfID0gcmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTZml4ZWQ2NF8gPSByZXBlYXRlZFNmaXhlZDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZsb2F0XyA9IHJlcGVhdGVkRmxvYXRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZERvdWJsZV8gPSByZXBlYXRlZERvdWJsZV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEJvb2xfID0gcmVwZWF0ZWRCb29sXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmdfID0gcmVwZWF0ZWRTdHJpbmdfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRCeXRlc18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQnl0ZXNfID0gcmVwZWF0ZWRCeXRlc187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmdQaWVjZV8gPSByZXBlYXRlZFN0cmluZ1BpZWNlXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQ29yZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQ29yZF8gPSByZXBlYXRlZENvcmRfOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbE9uZW9mcyhwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIHJlc3VsdCkgewogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkQ2FzZV8gPSBvbmVvZkZpZWxkQ2FzZV87CiAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRfID0gdGhpcy5vbmVvZkZpZWxkXzsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMiAmJgogICAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMigpICE9IDApIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzIob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsSW50NjQoKSAhPSAwTCkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQ2NChvdGhlci5nZXRPcHRpb25hbEludDY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxVaW50MzIoKSAhPSAwKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFVpbnQzMihvdGhlci5nZXRPcHRpb25hbFVpbnQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsVWludDY0KCkgIT0gMEwpIHsKICAgICAgICAgIHNldE9wdGlvbmFsVWludDY0KG90aGVyLmdldE9wdGlvbmFsVWludDY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxTaW50MzIoKSAhPSAwKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFNpbnQzMihvdGhlci5nZXRPcHRpb25hbFNpbnQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsU2ludDY0KCkgIT0gMEwpIHsKICAgICAgICAgIHNldE9wdGlvbmFsU2ludDY0KG90aGVyLmdldE9wdGlvbmFsU2ludDY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxGaXhlZDMyKCkgIT0gMCkgewogICAgICAgICAgc2V0T3B0aW9uYWxGaXhlZDMyKG90aGVyLmdldE9wdGlvbmFsRml4ZWQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsRml4ZWQ2NCgpICE9IDBMKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEZpeGVkNjQob3RoZXIuZ2V0T3B0aW9uYWxGaXhlZDY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxTZml4ZWQzMigpICE9IDApIHsKICAgICAgICAgIHNldE9wdGlvbmFsU2ZpeGVkMzIob3RoZXIuZ2V0T3B0aW9uYWxTZml4ZWQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsU2ZpeGVkNjQoKSAhPSAwTCkgewogICAgICAgICAgc2V0T3B0aW9uYWxTZml4ZWQ2NChvdGhlci5nZXRPcHRpb25hbFNmaXhlZDY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuZ2V0T3B0aW9uYWxGbG9hdCgpICE9IDBGKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEZsb2F0KG90aGVyLmdldE9wdGlvbmFsRmxvYXQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5nZXRPcHRpb25hbERvdWJsZSgpICE9IDBEKSB7CiAgICAgICAgICBzZXRPcHRpb25hbERvdWJsZShvdGhlci5nZXRPcHRpb25hbERvdWJsZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsQm9vbCgpICE9IGZhbHNlKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEJvb2wob3RoZXIuZ2V0T3B0aW9uYWxCb29sKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmdldE9wdGlvbmFsU3RyaW5nKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBvdGhlci5vcHRpb25hbFN0cmluZ187CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmdldE9wdGlvbmFsQnl0ZXMoKSAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsQnl0ZXMob3RoZXIuZ2V0T3B0aW9uYWxCeXRlcygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsTmVzdGVkTWVzc2FnZShvdGhlci5nZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxGb3JlaWduTWVzc2FnZShvdGhlci5nZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxJbXBvcnRNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLm9wdGlvbmFsTmVzdGVkRW51bV8gIT0gMCkgewogICAgICAgICAgc2V0T3B0aW9uYWxOZXN0ZWRFbnVtVmFsdWUob3RoZXIuZ2V0T3B0aW9uYWxOZXN0ZWRFbnVtVmFsdWUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5vcHRpb25hbEZvcmVpZ25FbnVtXyAhPSAwKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEZvcmVpZ25FbnVtVmFsdWUob3RoZXIuZ2V0T3B0aW9uYWxGb3JlaWduRW51bVZhbHVlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmdldE9wdGlvbmFsU3RyaW5nUGllY2UoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gb3RoZXIub3B0aW9uYWxTdHJpbmdQaWVjZV87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5nZXRPcHRpb25hbENvcmQoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIG9wdGlvbmFsQ29yZF8gPSBvdGhlci5vcHRpb25hbENvcmRfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsTGF6eU1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZShvdGhlci5nZXRPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEludDMyXyA9IG90aGVyLnJlcGVhdGVkSW50MzJfOwogICAgICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkSW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEludDY0XyA9IG90aGVyLnJlcGVhdGVkSW50NjRfOwogICAgICAgICAgICByZXBlYXRlZEludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkVWludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFVpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXyA9IG90aGVyLnJlcGVhdGVkVWludDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZFVpbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRVaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkVWludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gb3RoZXIucmVwZWF0ZWRVaW50NjRfOwogICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkVWludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8gPSBvdGhlci5yZXBlYXRlZFNpbnQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTaW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2ludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IG90aGVyLnJlcGVhdGVkU2ludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNpbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gb3RoZXIucmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZEZpeGVkMzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IG90aGVyLnJlcGVhdGVkRml4ZWQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGaXhlZDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNmaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNmaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBvdGhlci5yZXBlYXRlZFNmaXhlZDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNmaXhlZDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNmaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNmaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBvdGhlci5yZXBlYXRlZFNmaXhlZDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNmaXhlZDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZsb2F0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEZsb2F0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBvdGhlci5yZXBlYXRlZEZsb2F0XzsKICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEZsb2F0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZERvdWJsZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWREb3VibGVfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBvdGhlci5yZXBlYXRlZERvdWJsZV87CiAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWREb3VibGVfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQm9vbF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRCb29sXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRCb29sXyA9IG90aGVyLnJlcGVhdGVkQm9vbF87CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRCb29sXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRCb29sXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZ18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmdfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFN0cmluZ18gPSBvdGhlci5yZXBlYXRlZFN0cmluZ187CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmdfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQnl0ZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkQnl0ZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEJ5dGVzXyA9IG90aGVyLnJlcGVhdGVkQnl0ZXNfOwogICAgICAgICAgICByZXBlYXRlZEJ5dGVzXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRCeXRlc18uYWRkQWxsKG90aGVyLnJlcGVhdGVkQnl0ZXNfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAyMDApOwogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRJbXBvcnRNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkSW1wb3J0TWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA4MDApOwogICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZEltcG9ydE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IG90aGVyLnJlcGVhdGVkTmVzdGVkRW51bV87CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZEFsbChvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRm9yZWlnbkVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbkVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXyA9IG90aGVyLnJlcGVhdGVkRm9yZWlnbkVudW1fOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLmFkZEFsbChvdGhlci5yZXBlYXRlZEZvcmVpZ25FbnVtXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZ1BpZWNlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFN0cmluZ1BpZWNlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8gPSBvdGhlci5yZXBlYXRlZFN0cmluZ1BpZWNlXzsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdQaWVjZUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmdQaWVjZV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRDb3JkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZENvcmRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZENvcmRfID0gb3RoZXIucmVwZWF0ZWRDb3JkXzsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRDb3JkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkQ29yZF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkQ29yZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZExhenlNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRMYXp5TWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMTAwMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRMYXp5TWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTGF6eU1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkTGF6eU1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIucmVwZWF0ZWRMYXp5TWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHN3aXRjaCAob3RoZXIuZ2V0T25lb2ZGaWVsZENhc2UoKSkgewogICAgICAgICAgY2FzZSBPTkVPRl9VSU5UMzI6IHsKICAgICAgICAgICAgc2V0T25lb2ZVaW50MzIob3RoZXIuZ2V0T25lb2ZVaW50MzIoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBPTkVPRl9ORVNURURfTUVTU0FHRTogewogICAgICAgICAgICBtZXJnZU9uZW9mTmVzdGVkTWVzc2FnZShvdGhlci5nZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBPTkVPRl9TVFJJTkc6IHsKICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTEzOwogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IG90aGVyLm9uZW9mRmllbGRfOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GX0JZVEVTOiB7CiAgICAgICAgICAgIHNldE9uZW9mQnl0ZXMob3RoZXIuZ2V0T25lb2ZCeXRlcygpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GRklFTERfTk9UX1NFVDogewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDY0XyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxVaW50MzJfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgICAgY2FzZSAzMjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxVaW50NjRfID0gaW5wdXQucmVhZFVJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyCiAgICAgICAgICAgICAgY2FzZSA0MDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxTaW50MzJfID0gaW5wdXQucmVhZFNJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQwCiAgICAgICAgICAgICAgY2FzZSA0ODogewogICAgICAgICAgICAgICAgb3B0aW9uYWxTaW50NjRfID0gaW5wdXQucmVhZFNJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ4CiAgICAgICAgICAgICAgY2FzZSA2MTogewogICAgICAgICAgICAgICAgb3B0aW9uYWxGaXhlZDMyXyA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjEKICAgICAgICAgICAgICBjYXNlIDY1OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEZpeGVkNjRfID0gaW5wdXQucmVhZEZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NQogICAgICAgICAgICAgIGNhc2UgNzc6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsU2ZpeGVkMzJfID0gaW5wdXQucmVhZFNGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzcKICAgICAgICAgICAgICBjYXNlIDgxOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFNmaXhlZDY0XyA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxCiAgICAgICAgICAgICAgY2FzZSA5MzogewogICAgICAgICAgICAgICAgb3B0aW9uYWxGbG9hdF8gPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MwogICAgICAgICAgICAgIGNhc2UgOTc6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsRG91YmxlXyA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NwogICAgICAgICAgICAgIGNhc2UgMTA0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEJvb2xfID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDQKICAgICAgICAgICAgICBjYXNlIDExNDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE0CiAgICAgICAgICAgICAgY2FzZSAxMjI6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsQnl0ZXNfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIyCiAgICAgICAgICAgICAgY2FzZSAxNDY6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ2CiAgICAgICAgICAgICAgY2FzZSAxNTQ6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1NAogICAgICAgICAgICAgIGNhc2UgMTYyOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MgogICAgICAgICAgICAgIGNhc2UgMTY4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjgKICAgICAgICAgICAgICBjYXNlIDE3NjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxGb3JlaWduRW51bV8gPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE3NgogICAgICAgICAgICAgIGNhc2UgMTk0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE5NAogICAgICAgICAgICAgIGNhc2UgMjAyOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbENvcmRfID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjAyCiAgICAgICAgICAgICAgY2FzZSAyMTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjEwCiAgICAgICAgICAgICAgY2FzZSAyMTg6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxOAogICAgICAgICAgICAgIGNhc2UgMjI2OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjI2CiAgICAgICAgICAgICAgY2FzZSAyNDg6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQ4CiAgICAgICAgICAgICAgY2FzZSAyNTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQoaW5wdXQucmVhZEludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1MAogICAgICAgICAgICAgIGNhc2UgMjU2OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjU2CiAgICAgICAgICAgICAgY2FzZSAyNTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKGlucHV0LnJlYWRJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTgKICAgICAgICAgICAgICBjYXNlIDI2NDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNjQKICAgICAgICAgICAgICBjYXNlIDI2NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8uYWRkSW50KGlucHV0LnJlYWRVSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjY2CiAgICAgICAgICAgICAgY2FzZSAyNzI6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRVSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNzIKICAgICAgICAgICAgICBjYXNlIDI3NDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkVUludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI3NAogICAgICAgICAgICAgIGNhc2UgMjgwOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI4MAogICAgICAgICAgICAgIGNhc2UgMjgyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5hZGRJbnQoaW5wdXQucmVhZFNJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODIKICAgICAgICAgICAgICBjYXNlIDI4ODogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI4OAogICAgICAgICAgICAgIGNhc2UgMjkwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRMb25nKGlucHV0LnJlYWRTSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjkwCiAgICAgICAgICAgICAgY2FzZSAzMDE6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzAxCiAgICAgICAgICAgICAgY2FzZSAyOTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRJbnQoaW5wdXQucmVhZEZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjk4CiAgICAgICAgICAgICAgY2FzZSAzMDU6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMDUKICAgICAgICAgICAgICBjYXNlIDMwNjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZExvbmcoaW5wdXQucmVhZEZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzA2CiAgICAgICAgICAgICAgY2FzZSAzMTc6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFNGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzE3CiAgICAgICAgICAgICAgY2FzZSAzMTQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLmFkZEludChpbnB1dC5yZWFkU0ZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzE0CiAgICAgICAgICAgICAgY2FzZSAzMjE6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMjEKICAgICAgICAgICAgICBjYXNlIDMyMjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIyCiAgICAgICAgICAgICAgY2FzZSAzMzM6IHsKICAgICAgICAgICAgICAgIGZsb2F0IHYgPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLmFkZEZsb2F0KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzMwogICAgICAgICAgICAgIGNhc2UgMzMwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdChpbnB1dC5yZWFkRmxvYXQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzMwCiAgICAgICAgICAgICAgY2FzZSAzMzc6IHsKICAgICAgICAgICAgICAgIGRvdWJsZSB2ID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5hZGREb3VibGUodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzM3CiAgICAgICAgICAgICAgY2FzZSAzMzg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkRG91YmxlKGlucHV0LnJlYWREb3VibGUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzM4CiAgICAgICAgICAgICAgY2FzZSAzNDQ6IHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdiA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8uYWRkQm9vbGVhbih2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNDQKICAgICAgICAgICAgICBjYXNlIDM0NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEJvb2xlYW4oaW5wdXQucmVhZEJvb2woKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQ2CiAgICAgICAgICAgICAgY2FzZSAzNTQ6IHsKICAgICAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGlucHV0LnJlYWRTdHJpbmdSZXF1aXJlVXRmOCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nXy5hZGQocyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzU0CiAgICAgICAgICAgICAgY2FzZSAzNjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2ID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJ5dGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEJ5dGVzXy5hZGQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzYyCiAgICAgICAgICAgICAgY2FzZSAzODY6IHsKICAgICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLnBhcnNlcigpLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM4NgogICAgICAgICAgICAgIGNhc2UgMzk0OiB7CiAgICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZS5wYXJzZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzk0CiAgICAgICAgICAgICAgY2FzZSA0MDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAyCiAgICAgICAgICAgICAgY2FzZSA0MDg6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQwOAogICAgICAgICAgICAgIGNhc2UgNDEwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDEwCiAgICAgICAgICAgICAgY2FzZSA0MTY6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDE2CiAgICAgICAgICAgICAgY2FzZSA0MTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQxOAogICAgICAgICAgICAgIGNhc2UgNDM0OiB7CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfLmFkZChzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MzQKICAgICAgICAgICAgICBjYXNlIDQ0MjogewogICAgICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZENvcmRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkQ29yZF8uYWRkKHMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ0MgogICAgICAgICAgICAgIGNhc2UgNDU4OiB7CiAgICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5wYXJzZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDU4CiAgICAgICAgICAgICAgY2FzZSA4ODg6IHsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTExOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDg4OAogICAgICAgICAgICAgIGNhc2UgODk4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPbmVvZk5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTEyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDg5OAogICAgICAgICAgICAgIGNhc2UgOTA2OiB7CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBpbnB1dC5yZWFkU3RyaW5nUmVxdWlyZVV0ZjgoKTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMzsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRfID0gczsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MDYKICAgICAgICAgICAgICBjYXNlIDkxNDogewogICAgICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MTQKICAgICAgICAgICAgICBjYXNlIDkyMjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTIyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9uZW9mRmllbGRfOwogICAgICBwdWJsaWMgT25lb2ZGaWVsZENhc2UKICAgICAgICAgIGdldE9uZW9mRmllbGRDYXNlKCkgewogICAgICAgIHJldHVybiBPbmVvZkZpZWxkQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZGaWVsZCgpIHsKICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQxXzsKCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFNpbmd1bGFyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5pbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBTaW5ndWxhcgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+aW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFNpbmd1bGFyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5pbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9wdGlvbmFsSW50MzJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsSW50NjRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQ2NCBvcHRpb25hbF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb3B0aW9uYWxJbnQ2NF8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBvcHRpb25hbF91aW50MzIgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9wdGlvbmFsX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsVWludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsVWludDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9wdGlvbmFsX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsVWludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvcHRpb25hbFVpbnQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxVaW50NjRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50NjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsVWludDY0KCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFVpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVWludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxVaW50NjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9wdGlvbmFsVWludDY0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFNpbnQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFNpbnQzMigpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxTaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFNpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxTaW50MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTaW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9wdGlvbmFsU2ludDMyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFNpbnQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxTaW50NjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsU2ludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU2ludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbFNpbnQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNpbnQ2NCBvcHRpb25hbF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFNpbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb3B0aW9uYWxTaW50NjRfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsRml4ZWQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEZpeGVkMzIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsRml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxGaXhlZDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxGaXhlZDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvcHRpb25hbEZpeGVkMzJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsRml4ZWQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+Zml4ZWQ2NCBvcHRpb25hbF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxGaXhlZDY0KCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEZpeGVkNjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5maXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9wdGlvbmFsRml4ZWQ2NF8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZml4ZWQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZml4ZWQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFNmaXhlZDMyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFNmaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFNmaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTZml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxTZml4ZWQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTZml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb3B0aW9uYWxTZml4ZWQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxTZml4ZWQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+c2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsU2ZpeGVkNjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsU2ZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFNmaXhlZDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTZml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsU2ZpeGVkNjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFNmaXhlZDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvcHRpb25hbFNmaXhlZDY0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IG9wdGlvbmFsRmxvYXRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZsb2F0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0T3B0aW9uYWxGbG9hdCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxGbG9hdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEZsb2F0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsRmxvYXRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5mbG9hdCBvcHRpb25hbF9mbG9hdCA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEZsb2F0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvcHRpb25hbEZsb2F0XyA9IDBGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGRvdWJsZSBvcHRpb25hbERvdWJsZV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxEb3VibGUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0T3B0aW9uYWxEb3VibGUoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsRG91YmxlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+ZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbERvdWJsZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRG91YmxlKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbERvdWJsZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmRvdWJsZSBvcHRpb25hbF9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxEb3VibGUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9wdGlvbmFsRG91YmxlXyA9IDBEOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gb3B0aW9uYWxCb29sXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQm9vbC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0T3B0aW9uYWxCb29sKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEJvb2xfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxCb29sIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxCb29sKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxCb29sXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ym9vbCBvcHRpb25hbF9ib29sID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsQm9vbCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb3B0aW9uYWxCb29sXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gczsKICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9wdGlvbmFsU3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFN0cmluZygpIHsKICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbFN0cmluZygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgb3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvcHRpb25hbF9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlcy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEJ5dGVzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxCeXRlcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQnl0ZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbEJ5dGVzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxCeXRlcygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb3B0aW9uYWxCeXRlc18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbEJ5dGVzKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTmVzdGVkTWVzc2FnZShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfICE9IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxGb3JlaWduTWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGb3JlaWduTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbEZvcmVpZ25NZXNzYWdlKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gIT0gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxJbXBvcnRNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyPiBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEltcG9ydE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEltcG9ydE1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEltcG9ydE1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxJbXBvcnRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxJbXBvcnRNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxOZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgaW50IGdldE9wdGlvbmFsTmVzdGVkRW51bVZhbHVlKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZEVudW1fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxOZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRFbnVtVmFsdWUoaW50IHZhbHVlKSB7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVzdWx0ID0gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmZvck51bWJlcihvcHRpb25hbE5lc3RlZEVudW1fKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkRW51bShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxOZXN0ZWRFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxGb3JlaWduRW51bV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3Igb3B0aW9uYWxGb3JlaWduRW51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGludCBnZXRPcHRpb25hbEZvcmVpZ25FbnVtVmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbkVudW1fOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIG9wdGlvbmFsRm9yZWlnbkVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEZvcmVpZ25FbnVtVmFsdWUoaW50IHZhbHVlKSB7CiAgICAgICAgb3B0aW9uYWxGb3JlaWduRW51bV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtIGdldE9wdGlvbmFsRm9yZWlnbkVudW0oKSB7CiAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtIHJlc3VsdCA9IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bS5mb3JOdW1iZXIob3B0aW9uYWxGb3JlaWduRW51bV8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRm9yZWlnbkVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEZvcmVpZ25FbnVtKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRm9yZWlnbkVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsU3RyaW5nUGllY2VfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nUGllY2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZ1BpZWNlKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdQaWVjZV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IHM7CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZ1BpZWNlLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdQaWVjZV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZ1BpZWNlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFN0cmluZ1BpZWNlKCkgewogICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZSgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMTAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZ1BpZWNlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTdHJpbmdQaWVjZUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxDb3JkXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQ29yZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsQ29yZCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsQ29yZF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBvcHRpb25hbENvcmRfID0gczsKICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxDb3JkLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0T3B0aW9uYWxDb3JkQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbENvcmRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBvcHRpb25hbENvcmRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxDb3JkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxDb3JkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxDb3JkXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxDb3JkKCkgewogICAgICAgIG9wdGlvbmFsQ29yZF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbENvcmQoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvcHRpb25hbENvcmQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbENvcmRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBvcHRpb25hbENvcmRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbExhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbExhenlNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID09IG51bGwgPyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxMYXp5TWVzc2FnZShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbExhenlNZXNzYWdlKAogICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxMYXp5TWVzc2FnZShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfICE9IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxMYXp5TWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF91bnZlcmlmaWVkX2xhenlfbWVzc2FnZSA9IDI4IFt1bnZlcmlmaWVkX2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF91bnZlcmlmaWVkX2xhenlfbWVzc2FnZSA9IDI4IFt1bnZlcmlmaWVkX2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoCiAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyAhPSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2xhenlfaW1wb3J0X21lc3NhZ2UgPSAxMTUgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2xhenlfaW1wb3J0X21lc3NhZ2UgPSAxMTUgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9pbXBvcnRfbWVzc2FnZSA9IDExNSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9sYXp5X2ltcG9ydF9tZXNzYWdlID0gMTE1IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2xhenlfaW1wb3J0X21lc3NhZ2UgPSAxMTUgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAyMDAwMDAwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VfICE9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9pbXBvcnRfbWVzc2FnZSA9IDExNSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9pbXBvcnRfbWVzc2FnZSA9IDExNSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2xhenlfaW1wb3J0X21lc3NhZ2UgPSAxMTUgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5SW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9sYXp5X2ltcG9ydF9tZXNzYWdlID0gMTE1IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbExhenlJbXBvcnRNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbExhenlJbXBvcnRNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRJbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50MzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkSW50MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBSZXBlYXRlZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZEludDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBSZXBlYXRlZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBSZXBlYXRlZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBSZXBlYXRlZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRJbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRJbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUmVwZWF0ZWQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkSW50MzIoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRJbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRJbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkSW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEludDY0KCkgewogICAgICAgIHJlcGVhdGVkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkVWludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkVWludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFVpbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkVWludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRVaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFVpbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkVWludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkVWludDMyKCkgewogICAgICAgIHJlcGVhdGVkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDEwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRVaW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRVaW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkVWludDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRVaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRVaW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVWludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRVaW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkVWludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFVpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkVWludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRVaW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRVaW50NjQoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFNpbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNpbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2ludDMyKCkgewogICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTaW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTaW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkU2ludDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRTaW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTaW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU2ludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTaW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTaW50NjQoKSB7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkMzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRml4ZWQzMl8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpeGVkMzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZpeGVkMzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRGaXhlZDMyXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRGaXhlZDMyKCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkNjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRml4ZWQ2NF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRml4ZWQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRml4ZWQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZpeGVkNjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRGaXhlZDY0Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRGaXhlZDY0KCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU2ZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNmaXhlZDMyXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFNmaXhlZDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2ZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNmaXhlZDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFNmaXhlZDMyXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNmaXhlZDMyKCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTZml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ZpeGVkNjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRTZml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ZpeGVkNjRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFNmaXhlZDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNmaXhlZDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTZml4ZWQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU2ZpeGVkNjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ZpeGVkNjRfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2ZpeGVkNjQoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZsb2F0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGbG9hdF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZsb2F0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGbG9hdF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGbG9hdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGbG9hdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGbG9hdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZmxvYXQgZ2V0UmVwZWF0ZWRGbG9hdChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uZ2V0RmxvYXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZsb2F0KAogICAgICAgICAgaW50IGluZGV4LCBmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8uc2V0RmxvYXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZsb2F0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGbG9hdCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRmxvYXQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEZsb2F0Xyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZsb2F0KCkgewogICAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZERvdWJsZV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZERvdWJsZV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWREb3VibGVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWREb3VibGVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWREb3VibGUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpIHsKICAgICAgICByZXBlYXRlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRG91YmxlLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZERvdWJsZUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGRvdWJsZSBnZXRSZXBlYXRlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLmdldERvdWJsZShpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZERvdWJsZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRG91YmxlKAogICAgICAgICAgaW50IGluZGV4LCBkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZERvdWJsZV8uc2V0RG91YmxlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRG91YmxlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWREb3VibGUoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWREb3VibGVfLmFkZERvdWJsZSh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZERvdWJsZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRG91YmxlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZERvdWJsZV8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZERvdWJsZSgpIHsKICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRCb29sXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEJvb2xfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEJvb2xfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkQm9vbF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQm9vbC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldFJlcGVhdGVkQm9vbExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCb29sLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJvb2xDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2woaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQm9vbCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQm9vbCgKICAgICAgICAgIGludCBpbmRleCwgYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJvb2xfLnNldEJvb2xlYW4oaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJvb2wgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEJvb2woYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEJvb2wgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEJvb2woCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRCb29sXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRCb29sKCkgewogICAgICAgIHJlcGVhdGVkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZ18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZ18uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmdfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcoCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ18uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU3RyaW5nIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTdHJpbmdfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmcoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDA4MCk7OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ18uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiByZXBlYXRlZEJ5dGVzXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQnl0ZXNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEJ5dGVzXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEJ5dGVzXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQnl0ZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRCeXRlc0xpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRCeXRlc18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEJ5dGVzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQnl0ZXNDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQnl0ZXMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXBlYXRlZEJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEJ5dGVzXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQnl0ZXMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEJ5dGVzKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJ5dGVzXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQnl0ZXMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEJ5dGVzKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQnl0ZXNfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRCeXRlcyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkQnl0ZXMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEJ5dGVzXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEJ5dGVzKCkgewogICAgICAgIHJlcGVhdGVkQnl0ZXNfID0gZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUNvdW50KCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkTmVzdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQxXyAmIDB4MDAwMDAyMDApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2U+IHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlPihyZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2U+IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMV8gJiAweDAwMDAwNDAwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4ocmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2U+IHZhbHVlcykgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQxXyAmIDB4MDAwMDA4MDApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWROZXN0ZWRFbnVtXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4ocmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocmVwZWF0ZWROZXN0ZWRFbnVtXywgcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWRFbnVtKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRFbnVtKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE5lc3RlZEVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWROZXN0ZWRFbnVtKCkgewogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlTGlzdCgpIHsKICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IHZhbHVlKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChpbnQgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkRm9yZWlnbkVudW1fID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHJlcGVhdGVkRm9yZWlnbkVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bT4gZ2V0UmVwZWF0ZWRGb3JlaWduRW51bUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtPihyZXBlYXRlZEZvcmVpZ25FbnVtXywgcmVwZWF0ZWRGb3JlaWduRW51bV9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRm9yZWlnbkVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRm9yZWlnbkVudW1Db3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRm9yZWlnbkVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bSBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25FbnVtX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZEZvcmVpZ25FbnVtXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGb3JlaWduRW51bSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRm9yZWlnbkVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZvcmVpZ25FbnVtKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGb3JlaWduRW51bSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbkVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZvcmVpZ25FbnVtKCkgewogICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkRm9yZWlnbkVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFJlcGVhdGVkRm9yZWlnbkVudW1WYWx1ZUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkRm9yZWlnbkVudW1fKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIG9mIHJlcGVhdGVkRm9yZWlnbkVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbkVudW1fLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZEZvcmVpZ25FbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGb3JlaWduRW51bVZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWRGb3JlaWduRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbkVudW1WYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkRm9yZWlnbkVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZvcmVpZ25FbnVtVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbkVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKGludCB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nUGllY2VfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZ1BpZWNlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KHJlcGVhdGVkU3RyaW5nUGllY2VfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nUGllY2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmdQaWVjZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nUGllY2UgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFN0cmluZ1BpZWNlKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nUGllY2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nUGllY2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdQaWVjZUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZ1BpZWNlXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmdQaWVjZSgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDQwMDApOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmdQaWVjZUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjaGVja0J5dGVTdHJpbmdJc1V0ZjgodmFsdWUpOwogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRDb3JkXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZENvcmRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZENvcmRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZENvcmRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZENvcmRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRDb3JkLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZENvcmRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkQ29yZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZENvcmRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRDb3JkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZENvcmRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRDb3JkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkQ29yZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRDb3JkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkQ29yZEJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZENvcmRfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQ29yZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQ29yZCgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRDb3JkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRDb3JkXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQ29yZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQ29yZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQ29yZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQ29yZF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZENvcmQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZENvcmQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRDb3JkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkQ29yZF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRDb3JkKCkgewogICAgICAgIHJlcGVhdGVkQ29yZF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDA4MDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZENvcmQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZENvcmRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY2hlY2tCeXRlU3RyaW5nSXNVdGY4KHZhbHVlKTsKICAgICAgICBlbnN1cmVSZXBlYXRlZENvcmRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZENvcmRfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMV8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+KHJlcGVhdGVkTGF6eU1lc3NhZ2VfKTsKICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiBnZXRSZXBlYXRlZExhenlNZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZExhenlNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZExhenlNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRMYXp5TWVzc2FnZShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRMYXp5TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRMYXp5TWVzc2FnZSgKICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRMYXp5TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkTGF6eU1lc3NhZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZExhenlNZXNzYWdlKCkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRMYXp5TWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQxXyAmIDB4MDAwMTAwMDApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDExMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZVaW50MzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZVaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTE7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZlVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0T25lb2ZVaW50MzIoKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTEpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDExMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb25lb2ZVaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZlVpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTExOwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mVWludDMyKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTExKSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb25lb2ZOZXN0ZWRNZXNzYWdlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9uZW9mTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICAgICAgcmV0dXJuIChwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICAgICAgcmV0dXJuIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mTmVzdGVkTWVzc2FnZShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZOZXN0ZWRNZXNzYWdlKAogICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9uZW9mTmVzdGVkTWVzc2FnZShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIgJiYKICAgICAgICAgICAgICBvbmVvZkZpZWxkXyAhPSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXykKICAgICAgICAgICAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldE9uZW9mTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmICgob25lb2ZGaWVsZENhc2VfID09IDExMikgJiYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgICByZXR1cm4gb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICAgICByZXR1cm4gKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF87CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIShvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSkgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF8sCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mU3RyaW5nKCkgewogICAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb25lb2ZTdHJpbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9uZW9mU3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9uZW9mU3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGI7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9uZW9mU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTM7CiAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZTdHJpbmcoKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvbmVvZlN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mU3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTEzOwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDExNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZkJ5dGVzKCkgewogICAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDExNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9uZW9mQnl0ZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9uZW9mQnl0ZXMoKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTQpIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9uZW9mQnl0ZXMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZkJ5dGVzKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTE0OwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZkJ5dGVzKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0KSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0QWxsVHlwZXM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEFsbFR5cGVzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdEFsbFR5cGVzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEFsbFR5cGVzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RBbGxUeXBlcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RQYWNrZWRUeXBlc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzNfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkSW50MzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQzMi4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkSW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZEludDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50NjQuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRJbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRQYWNrZWRJbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkVWludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkVWludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRVaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRVaW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRVaW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFVpbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZFVpbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDY0LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkVWludDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRVaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFBhY2tlZFVpbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkU2ludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRTaW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRTaW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNpbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZFNpbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ludDY0LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2ludDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFBhY2tlZFNpbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGaXhlZDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkRml4ZWQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkRml4ZWQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRGaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEZpeGVkMzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRml4ZWQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZEZpeGVkNjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRml4ZWQ2NC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UGFja2VkRml4ZWQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNmaXhlZDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldFBhY2tlZFNmaXhlZDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2ZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2ZpeGVkMzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZml4ZWQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFBhY2tlZFNmaXhlZDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ZpeGVkNjQuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRTZml4ZWQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNmaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRQYWNrZWRTZml4ZWQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGbG9hdC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PiBnZXRQYWNrZWRGbG9hdExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGbG9hdC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEZsb2F0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgZmxvYXQgZ2V0UGFja2VkRmxvYXQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWREb3VibGUuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+IGdldFBhY2tlZERvdWJsZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZERvdWJsZS4KICAgICAqLwogICAgaW50IGdldFBhY2tlZERvdWJsZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZERvdWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGRvdWJsZSBnZXRQYWNrZWREb3VibGUoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEJvb2wuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPiBnZXRQYWNrZWRCb29sTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRCb29sLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkQm9vbENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0UGFja2VkQm9vbChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtPiBnZXRQYWNrZWRFbnVtTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRFbnVtLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bSBnZXRQYWNrZWRFbnVtKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHBhY2tlZEVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UGFja2VkRW51bVZhbHVlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcGFja2VkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRFbnVtVmFsdWUoaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RQYWNrZWRUeXBlcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90bzNfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzKQogICAgICBUZXN0UGFja2VkVHlwZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RQYWNrZWRUeXBlcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0UGFja2VkVHlwZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0UGFja2VkVHlwZXMoKSB7CiAgICAgIHBhY2tlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHBhY2tlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcGFja2VkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcGFja2VkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwYWNrZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcGFja2VkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHBhY2tlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcGFja2VkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcGFja2VkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBwYWNrZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcGFja2VkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFBhY2tlZFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcy5jbGFzcywgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfSU5UMzJfRklFTERfTlVNQkVSID0gOTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZEludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFBhY2tlZEludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9JTlQ2NF9GSUVMRF9OVU1CRVIgPSA5MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZEludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRQYWNrZWRJbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkSW50NjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRJbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9VSU5UMzJfRklFTERfTlVNQkVSID0gOTI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZFVpbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRVaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRQYWNrZWRVaW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkVWludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFVpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkVWludDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRVaW50MzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRVaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1VJTlQ2NF9GSUVMRF9OVU1CRVIgPSA5MzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFVpbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkVWludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UGFja2VkVWludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFVpbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZFVpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRVaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1NJTlQzMl9GSUVMRF9OVU1CRVIgPSA5NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkU2ludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFBhY2tlZFNpbnQzMkxpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTaW50MzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZFNpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfU0lOVDY0X0ZJRUxEX05VTUJFUiA9IDk1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkU2ludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRQYWNrZWRTaW50NjRMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkU2ludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ludDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkU2ludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UGFja2VkU2ludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkU2ludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZFNpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA5NjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkRml4ZWQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEZpeGVkMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRQYWNrZWRGaXhlZDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEZpeGVkMzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkRml4ZWQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRGaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDk3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkRml4ZWQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGaXhlZDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UGFja2VkRml4ZWQ2NExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRGaXhlZDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkNjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRGaXhlZDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkRml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRGaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9TRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA5ODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkU2ZpeGVkMzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNmaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkU2ZpeGVkMzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ZpeGVkMzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkU2ZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1NGSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDk5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkU2ZpeGVkNjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFBhY2tlZFNmaXhlZDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNmaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNmaXhlZDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZFNmaXhlZDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkU2ZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkU2ZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0ZMT0FUX0ZJRUxEX05VTUJFUiA9IDEwMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCBwYWNrZWRGbG9hdF8gPQogICAgICAgIGVtcHR5RmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZ2V0UGFja2VkRmxvYXRMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkRmxvYXRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEZsb2F0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZsb2F0Q291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRGbG9hdF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZmxvYXQgZ2V0UGFja2VkRmxvYXQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRGbG9hdF8uZ2V0RmxvYXQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkRmxvYXRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0RPVUJMRV9GSUVMRF9OVU1CRVIgPSAxMDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHBhY2tlZERvdWJsZV8gPQogICAgICAgIGVtcHR5RG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRG91YmxlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBnZXRQYWNrZWREb3VibGVMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkRG91YmxlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZERvdWJsZS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWREb3VibGVDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZERvdWJsZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZG91YmxlIGdldFBhY2tlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZERvdWJsZV8uZ2V0RG91YmxlKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZERvdWJsZU1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfQk9PTF9GSUVMRF9OVU1CRVIgPSAxMDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCBwYWNrZWRCb29sXyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRCb29sLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZ2V0UGFja2VkQm9vbExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRCb29sXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkQm9vbC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRCb29sQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRCb29sXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdldFBhY2tlZEJvb2woaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRCb29sXy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0VOVU1fRklFTERfTlVNQkVSID0gMTAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrZWRFbnVtXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbkVudW0+IHBhY2tlZEVudW1fY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbkVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbkVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bS5VTlJFQ09HTklaRUQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtPiBnZXRQYWNrZWRFbnVtTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bT4ocGFja2VkRW51bV8sIHBhY2tlZEVudW1fY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRW51bUNvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkRW51bV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtIGdldFBhY2tlZEVudW0oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRFbnVtX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcGFja2VkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UGFja2VkRW51bVZhbHVlTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEVudW1fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcGFja2VkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRW51bVZhbHVlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkRW51bV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgaWYgKGdldFBhY2tlZEludDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3MjIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMk5vVGFnKHBhY2tlZEludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRJbnQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzMwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRJbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkSW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjROb1RhZyhwYWNrZWRJbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFVpbnQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzM4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRVaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFVpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFVpbnQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzQ2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRVaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50NjROb1RhZyhwYWNrZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTaW50MzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDc1NCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2ludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyTm9UYWcocGFja2VkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTaW50NjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDc2Mik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2ludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRTaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0Tm9UYWcocGFja2VkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkRml4ZWQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzcwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRGaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRGaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzJOb1RhZyhwYWNrZWRGaXhlZDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRGaXhlZDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3NzgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEZpeGVkNjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NE5vVGFnKHBhY2tlZEZpeGVkNjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTZml4ZWQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzg2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRTZml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2ZpeGVkMzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzJOb1RhZyhwYWNrZWRTZml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2ZpeGVkNjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDc5NCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2ZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNmaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0Tm9UYWcocGFja2VkU2ZpeGVkNjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRGbG9hdExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoODAyKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRGbG9hdE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkRmxvYXRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXROb1RhZyhwYWNrZWRGbG9hdF8uZ2V0RmxvYXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWREb3VibGVMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDgxMCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkRG91YmxlTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWREb3VibGVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlTm9UYWcocGFja2VkRG91YmxlXy5nZXREb3VibGUoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRCb29sTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MTgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEJvb2xfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbE5vVGFnKHBhY2tlZEJvb2xfLmdldEJvb2xlYW4oaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRFbnVtTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MjYpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bU5vVGFnKHBhY2tlZEVudW1fLmdldChpKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkSW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcocGFja2VkSW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRJbnQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZU5vVGFnKHBhY2tlZEludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkVWludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhwYWNrZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRVaW50MzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkVWludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhwYWNrZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkVWludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZFVpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50MzJTaXplTm9UYWcocGFja2VkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkU2ludDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZFNpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50NjRTaXplTm9UYWcocGFja2VkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZFNpbnQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRTaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UGFja2VkRml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEZpeGVkMzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkRml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRQYWNrZWRGaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkRml4ZWQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRGaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFBhY2tlZFNmaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkU2ZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UGFja2VkU2ZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRTZml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRQYWNrZWRGbG9hdExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEZsb2F0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEZsb2F0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFBhY2tlZERvdWJsZUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZERvdWJsZUxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWREb3VibGVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSAxICogZ2V0UGFja2VkQm9vbExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEJvb2xMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkQm9vbE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhwYWNrZWRFbnVtXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkRW51bUxpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfXBhY2tlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcyBvdGhlciA9IChwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzKSBvYmo7CgogICAgICBpZiAoIWdldFBhY2tlZEludDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEludDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEludDY0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZFVpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRVaW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkVWludDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZFVpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRTaW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkU2ludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZFNpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRTaW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkRml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRGaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkRml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRTZml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRTZml4ZWQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRTZml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRGbG9hdExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRGbG9hdExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWREb3VibGVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkRG91YmxlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEJvb2xMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkQm9vbExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFwYWNrZWRFbnVtXy5lcXVhbHMob3RoZXIucGFja2VkRW51bV8pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGdldFBhY2tlZEludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFVpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkVWludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFVpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkVWludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkU2ludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkU2ludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEZpeGVkMzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9GSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRGaXhlZDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEZpeGVkNjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRGaXhlZDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNmaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfU0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZFNmaXhlZDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNmaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfU0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZFNmaXhlZDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEZsb2F0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEZsb2F0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZERvdWJsZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkRG91YmxlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEJvb2xDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9CT09MX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRCb29sTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEVudW1Db3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBwYWNrZWRFbnVtXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvM191bml0dGVzdC5UZXN0UGFja2VkVHlwZXMpCiAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMuY2xhc3MsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBwYWNrZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBwYWNrZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcGFja2VkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHBhY2tlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcGFja2VkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHBhY2tlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcGFja2VkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBwYWNrZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBwYWNrZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBwYWNrZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcGFja2VkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBwYWNrZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgcGFja2VkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgcGFja2VkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzIGJ1aWxkKCkgewogICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzIHJlc3VsdCA9IG5ldyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHBhY2tlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnBhY2tlZEVudW1fID0gcGFja2VkRW51bV87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkSW50MzJfID0gcGFja2VkSW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRJbnQ2NF8gPSBwYWNrZWRJbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRVaW50MzJfID0gcGFja2VkVWludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZFVpbnQ2NF8gPSBwYWNrZWRVaW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkU2ludDMyXyA9IHBhY2tlZFNpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRTaW50NjRfID0gcGFja2VkU2ludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRGaXhlZDMyXyA9IHBhY2tlZEZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZEZpeGVkNjRfID0gcGFja2VkRml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZFNmaXhlZDMyXyA9IHBhY2tlZFNmaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkU2ZpeGVkNjRfID0gcGFja2VkU2ZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRGbG9hdF8gPSBwYWNrZWRGbG9hdF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWREb3VibGVfID0gcGFja2VkRG91YmxlXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRCb29sXyA9IHBhY2tlZEJvb2xfOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRJbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEludDMyXyA9IG90aGVyLnBhY2tlZEludDMyXzsKICAgICAgICAgICAgcGFja2VkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkSW50MzJfLmFkZEFsbChvdGhlci5wYWNrZWRJbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkSW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkSW50NjRfID0gb3RoZXIucGFja2VkSW50NjRfOwogICAgICAgICAgICBwYWNrZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRJbnQ2NF8uYWRkQWxsKG90aGVyLnBhY2tlZEludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRVaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFVpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZFVpbnQzMl8gPSBvdGhlci5wYWNrZWRVaW50MzJfOwogICAgICAgICAgICBwYWNrZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFVpbnQzMl8uYWRkQWxsKG90aGVyLnBhY2tlZFVpbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkVWludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRVaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRVaW50NjRfID0gb3RoZXIucGFja2VkVWludDY0XzsKICAgICAgICAgICAgcGFja2VkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRVaW50NjRfLmFkZEFsbChvdGhlci5wYWNrZWRVaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZFNpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkU2ludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkU2ludDMyXyA9IG90aGVyLnBhY2tlZFNpbnQzMl87CiAgICAgICAgICAgIHBhY2tlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkU2ludDMyXy5hZGRBbGwob3RoZXIucGFja2VkU2ludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRTaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFNpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZFNpbnQ2NF8gPSBvdGhlci5wYWNrZWRTaW50NjRfOwogICAgICAgICAgICBwYWNrZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFNpbnQ2NF8uYWRkQWxsKG90aGVyLnBhY2tlZFNpbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEZpeGVkMzJfID0gb3RoZXIucGFja2VkRml4ZWQzMl87CiAgICAgICAgICAgIHBhY2tlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRGaXhlZDMyXy5hZGRBbGwob3RoZXIucGFja2VkRml4ZWQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEZpeGVkNjRfID0gb3RoZXIucGFja2VkRml4ZWQ2NF87CiAgICAgICAgICAgIHBhY2tlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRGaXhlZDY0Xy5hZGRBbGwob3RoZXIucGFja2VkRml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkU2ZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFNmaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkU2ZpeGVkMzJfID0gb3RoZXIucGFja2VkU2ZpeGVkMzJfOwogICAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8uYWRkQWxsKG90aGVyLnBhY2tlZFNmaXhlZDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkU2ZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRTZml4ZWQ2NF8gPSBvdGhlci5wYWNrZWRTZml4ZWQ2NF87CiAgICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5hZGRBbGwob3RoZXIucGFja2VkU2ZpeGVkNjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEZsb2F0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEZsb2F0XyA9IG90aGVyLnBhY2tlZEZsb2F0XzsKICAgICAgICAgICAgcGFja2VkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkRmxvYXRfLmFkZEFsbChvdGhlci5wYWNrZWRGbG9hdF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkRG91YmxlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWREb3VibGVfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWREb3VibGVfID0gb3RoZXIucGFja2VkRG91YmxlXzsKICAgICAgICAgICAgcGFja2VkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWREb3VibGVfLmFkZEFsbChvdGhlci5wYWNrZWREb3VibGVfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRCb29sXyA9IG90aGVyLnBhY2tlZEJvb2xfOwogICAgICAgICAgICBwYWNrZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkQm9vbF8uYWRkQWxsKG90aGVyLnBhY2tlZEJvb2xfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRFbnVtXyA9IG90aGVyLnBhY2tlZEVudW1fOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEVudW1fLmFkZEFsbChvdGhlci5wYWNrZWRFbnVtXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA3MjA6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkSW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MjAKICAgICAgICAgICAgICBjYXNlIDcyMjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRJbnQzMl8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MjIKICAgICAgICAgICAgICBjYXNlIDcyODogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkSW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzI4CiAgICAgICAgICAgICAgY2FzZSA3MzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkSW50NjRfLmFkZExvbmcoaW5wdXQucmVhZEludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDczMAogICAgICAgICAgICAgIGNhc2UgNzM2OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkVWludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzM2CiAgICAgICAgICAgICAgY2FzZSA3Mzg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZFVpbnQzMl8uYWRkSW50KGlucHV0LnJlYWRVSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzM4CiAgICAgICAgICAgICAgY2FzZSA3NDQ6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRVSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkVWludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0NAogICAgICAgICAgICAgIGNhc2UgNzQ2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRVaW50NjRfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NDYKICAgICAgICAgICAgICBjYXNlIDc1MjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZFNpbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc1MgogICAgICAgICAgICAgIGNhc2UgNzU0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRTaW50MzJfLmFkZEludChpbnB1dC5yZWFkU0ludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc1NAogICAgICAgICAgICAgIGNhc2UgNzYwOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZFNpbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NjAKICAgICAgICAgICAgICBjYXNlIDc2MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkU2ludDY0Xy5hZGRMb25nKGlucHV0LnJlYWRTSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzYyCiAgICAgICAgICAgICAgY2FzZSA3NzM6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZEZpeGVkMzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzMKICAgICAgICAgICAgICBjYXNlIDc3MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkMzJJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkRml4ZWQzMl8uYWRkSW50KGlucHV0LnJlYWRGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc3MAogICAgICAgICAgICAgIGNhc2UgNzc3OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkRml4ZWQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzcKICAgICAgICAgICAgICBjYXNlIDc3ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkRml4ZWQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzgKICAgICAgICAgICAgICBjYXNlIDc4OTogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc4OQogICAgICAgICAgICAgIGNhc2UgNzg2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkMzJJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkU2ZpeGVkMzJfLmFkZEludChpbnB1dC5yZWFkU0ZpeGVkMzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzg2CiAgICAgICAgICAgICAgY2FzZSA3OTM6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc5MwogICAgICAgICAgICAgIGNhc2UgNzk0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkU2ZpeGVkNjRfLmFkZExvbmcoaW5wdXQucmVhZFNGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc5NAogICAgICAgICAgICAgIGNhc2UgODA1OiB7CiAgICAgICAgICAgICAgICBmbG9hdCB2ID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkRmxvYXRfLmFkZEZsb2F0KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwNQogICAgICAgICAgICAgIGNhc2UgODAyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkRmxvYXRfLmFkZEZsb2F0KGlucHV0LnJlYWRGbG9hdCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDIKICAgICAgICAgICAgICBjYXNlIDgwOTogewogICAgICAgICAgICAgICAgZG91YmxlIHYgPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZERvdWJsZV8uYWRkRG91YmxlKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwOQogICAgICAgICAgICAgIGNhc2UgODEwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZERvdWJsZV8uYWRkRG91YmxlKGlucHV0LnJlYWREb3VibGUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODEwCiAgICAgICAgICAgICAgY2FzZSA4MTY6IHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdiA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRCb29sXy5hZGRCb29sZWFuKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxNgogICAgICAgICAgICAgIGNhc2UgODE4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkQm9vbElzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRCb29sXy5hZGRCb29sZWFuKGlucHV0LnJlYWRCb29sKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxOAogICAgICAgICAgICAgIGNhc2UgODI0OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgyNAogICAgICAgICAgICAgIGNhc2UgODI2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBwYWNrZWRFbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MjYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkSW50MzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRQYWNrZWRJbnQzMkxpc3QoKSB7CiAgICAgICAgcGFja2VkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkSW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkSW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRJbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkSW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRJbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEludDMyKCkgewogICAgICAgIHBhY2tlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkSW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRJbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkSW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFBhY2tlZEludDY0TGlzdCgpIHsKICAgICAgICBwYWNrZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRJbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UGFja2VkSW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkSW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRJbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRJbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRJbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRJbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkSW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkSW50NjQoKSB7CiAgICAgICAgcGFja2VkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkVWludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkVWludDMyXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRVaW50MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFBhY2tlZFVpbnQzMkxpc3QoKSB7CiAgICAgICAgcGFja2VkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZFVpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkVWludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFVpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkVWludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRVaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRVaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRVaW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFVpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFVpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkVWludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRVaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRVaW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkVWludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkVWludDMyKCkgewogICAgICAgIHBhY2tlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBwYWNrZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkVWludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkVWludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkVWludDY0XyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRVaW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFBhY2tlZFVpbnQ2NExpc3QoKSB7CiAgICAgICAgcGFja2VkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkVWludDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRVaW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFVpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZFVpbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRVaW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRVaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRVaW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRVaW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkVWludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkVWludDY0KCkgewogICAgICAgIHBhY2tlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRTaW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTaW50MzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFNpbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UGFja2VkU2ludDMyTGlzdCgpIHsKICAgICAgICBwYWNrZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkU2ludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZFNpbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNpbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkU2ludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTaW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZFNpbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRTaW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRTaW50MzIoKSB7CiAgICAgICAgcGFja2VkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRTaW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRTaW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFNpbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UGFja2VkU2ludDY0TGlzdCgpIHsKICAgICAgICBwYWNrZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkU2ludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRTaW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZFNpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkU2ludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNpbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNpbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZFNpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRTaW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRTaW50NjQoKSB7CiAgICAgICAgcGFja2VkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEZpeGVkMzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRQYWNrZWRGaXhlZDMyTGlzdCgpIHsKICAgICAgICBwYWNrZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRml4ZWQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRGaXhlZDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEZpeGVkMzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRml4ZWQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRGaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkRml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEZpeGVkMzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkRml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEZpeGVkMzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEZpeGVkMzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEZpeGVkMzIoKSB7CiAgICAgICAgcGFja2VkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBwYWNrZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRml4ZWQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRml4ZWQ2NF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFBhY2tlZEZpeGVkNjRMaXN0KCkgewogICAgICAgIHBhY2tlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkRml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRGaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkNjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZEZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRGaXhlZDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRGaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkRml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRGaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkRml4ZWQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkRml4ZWQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkRml4ZWQ2NCgpIHsKICAgICAgICBwYWNrZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkU2ZpeGVkMzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRTZml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZFNmaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRTZml4ZWQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkU2ZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkU2ZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRQYWNrZWRTZml4ZWQzMkxpc3QoKSB7CiAgICAgICAgcGFja2VkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkU2ZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ZpeGVkMzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRTZml4ZWQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2ZpeGVkMzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRTZml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNmaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNmaXhlZDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkU2ZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRTZml4ZWQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZFNmaXhlZDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZFNmaXhlZDMyKCkgewogICAgICAgIHBhY2tlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTZml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkU2ZpeGVkNjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXBhY2tlZFNmaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkU2ZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFNmaXhlZDY0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNmaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UGFja2VkU2ZpeGVkNjRMaXN0KCkgewogICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNmaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRTZml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRTZml4ZWQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNmaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkU2ZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNmaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkU2ZpeGVkNjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRTZml4ZWQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRTZml4ZWQ2NCgpIHsKICAgICAgICBwYWNrZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IHBhY2tlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEZsb2F0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRmxvYXRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEZsb2F0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEZsb2F0XyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRGbG9hdF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0UGFja2VkRmxvYXRMaXN0KCkgewogICAgICAgIHBhY2tlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZsb2F0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEZsb2F0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRGbG9hdENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRGbG9hdF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRQYWNrZWRGbG9hdChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRmxvYXRfLmdldEZsb2F0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRGbG9hdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEZsb2F0KAogICAgICAgICAgaW50IGluZGV4LCBmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEZsb2F0Xy5zZXRGbG9hdChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEZsb2F0Xy5hZGRGbG9hdCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRGbG9hdCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRGbG9hdF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkRmxvYXQoKSB7CiAgICAgICAgcGFja2VkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHBhY2tlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZERvdWJsZV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZERvdWJsZV8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRG91YmxlXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkRG91YmxlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRG91YmxlXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWREb3VibGVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRG91YmxlLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRQYWNrZWREb3VibGVMaXN0KCkgewogICAgICAgIHBhY2tlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWREb3VibGVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWREb3VibGUuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZERvdWJsZUNvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWREb3VibGVfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZERvdWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZG91YmxlIGdldFBhY2tlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRG91YmxlXy5nZXREb3VibGUoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRG91YmxlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkRG91YmxlKAogICAgICAgICAgaW50IGluZGV4LCBkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRG91YmxlXy5zZXREb3VibGUoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRG91YmxlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkRG91YmxlKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICBwYWNrZWREb3VibGVfLmFkZERvdWJsZSh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWREb3VibGUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWREb3VibGUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWREb3VibGVfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkRG91YmxlKCkgewogICAgICAgIHBhY2tlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCBwYWNrZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkQm9vbF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkQm9vbF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkQm9vbF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkQm9vbF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEJvb2wuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRQYWNrZWRCb29sTGlzdCgpIHsKICAgICAgICBwYWNrZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEJvb2xfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEJvb2wuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEJvb2xDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkQm9vbF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGdldFBhY2tlZEJvb2woaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEJvb2xfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRCb29sIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkQm9vbCgKICAgICAgICAgIGludCBpbmRleCwgYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkQm9vbF8uc2V0Qm9vbGVhbihpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEJvb2wgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRCb29sKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkQm9vbElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEJvb2xfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRCb29sIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkQm9vbCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkQm9vbF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEJvb2woKSB7CiAgICAgICAgcGFja2VkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrZWRFbnVtXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRFbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihwYWNrZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtPiBnZXRQYWNrZWRFbnVtTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbkVudW0+KHBhY2tlZEVudW1fLCBwYWNrZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEVudW1Db3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRW51bV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbkVudW0gZ2V0UGFja2VkRW51bShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocGFja2VkRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRFbnVtKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbkVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBwYWNrZWRFbnVtXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRFbnVtKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduRW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25FbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICBwYWNrZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEVudW0oKSB7CiAgICAgICAgcGFja2VkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHBhY2tlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldFBhY2tlZEVudW1WYWx1ZUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHBhY2tlZEVudW1fKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRW51bVZhbHVlKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRFbnVtXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHBhY2tlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRFbnVtVmFsdWUoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewogICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBwYWNrZWRFbnVtXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgcGFja2VkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEVudW1WYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVQYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRW51bV8uYWRkKHZhbHVlKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciBwYWNrZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkRW51bVZhbHVlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChpbnQgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHBhY2tlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvM191bml0dGVzdC5UZXN0UGFja2VkVHlwZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM191bml0dGVzdC5UZXN0UGFja2VkVHlwZXMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFBhY2tlZFR5cGVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0UGFja2VkVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UGFja2VkVHlwZXM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFBhY2tlZFR5cGVzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdFBhY2tlZFR5cGVzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFBhY2tlZFR5cGVzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQYWNrZWRUeXBlcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RQYWNrZWRUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RVbnBhY2tlZFR5cGVzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvM191bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRSZXBlYXRlZEludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+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+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJvb2wuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEJvb2xDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2woaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBlbnVtIG51bWVyaWMgdmFsdWVzIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBFeHBsaWNpdGx5IHNldCBwYWNrZWQgdG8gZmFsc2UKICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM191bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RVbnBhY2tlZFR5cGVzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvM191bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgICAgVGVzdFVucGFja2VkVHlwZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RVbnBhY2tlZFR5cGVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RVbnBhY2tlZFR5cGVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFVucGFja2VkVHlwZXMoKSB7CiAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgIHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RVbnBhY2tlZFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdFVucGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0VW5wYWNrZWRUeXBlcy5jbGFzcywgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RVbnBhY2tlZFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkSW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkSW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkSW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9VSU5UMzJfRklFTERfTlVNQkVSID0gMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRVaW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkVWludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVpbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1VJTlQ2NF9GSUVMRF9OVU1CRVIgPSA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRVaW50NjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkVWludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NJTlQzMl9GSUVMRF9OVU1CRVIgPSA1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFNpbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRTaW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0lOVDY0X0ZJRUxEX05VTUJFUiA9IDY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNpbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkU2ludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRTaW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEZpeGVkMzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0ZJWEVENjRfRklFTERfTlVNQkVSID0gODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkRml4ZWQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkRml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0ZJWEVEMzJfRklFTERfTlVNQkVSID0gOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRTZml4ZWQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0ZJWEVENjRfRklFTERfTlVNQkVSID0gMTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNmaXhlZDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9GTE9BVF9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCByZXBlYXRlZEZsb2F0XyA9CiAgICAgICAgZW1wdHlGbG9hdExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmxvYXQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGZsb2F0IGdldFJlcGVhdGVkRmxvYXQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0Xy5nZXRGbG9hdChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRE9VQkxFX0ZJRUxEX05VTUJFUiA9IDEyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCByZXBlYXRlZERvdWJsZV8gPQogICAgICAgIGVtcHR5RG91YmxlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZERvdWJsZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZERvdWJsZS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZERvdWJsZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDEyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZERvdWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBkb3VibGUgZ2V0UmVwZWF0ZWREb3VibGUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV8uZ2V0RG91YmxlKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9CT09MX0ZJRUxEX05VTUJFUiA9IDEzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgcmVwZWF0ZWRCb29sXyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGdldFJlcGVhdGVkQm9vbExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJvb2xDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZ2V0UmVwZWF0ZWRCb29sKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVIgPSAxNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocmVwZWF0ZWROZXN0ZWRFbnVtXywgcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgb2YgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCByZXBlYXRlZEludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgyLCByZXBlYXRlZEludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigzLCByZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCg0LCByZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzIoNSwgcmVwZWF0ZWRTaW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50NjQoNiwgcmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzIoNywgcmVwZWF0ZWRGaXhlZDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjQoOCwgcmVwZWF0ZWRGaXhlZDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ZpeGVkMzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzIoOSwgcmVwZWF0ZWRTZml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ZpeGVkNjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjQoMTAsIHJlcGVhdGVkU2ZpeGVkNjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdCgxMSwgcmVwZWF0ZWRGbG9hdF8uZ2V0RmxvYXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWREb3VibGVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKDEyLCByZXBlYXRlZERvdWJsZV8uZ2V0RG91YmxlKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQm9vbF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDEzLCByZXBlYXRlZEJvb2xfLmdldEJvb2xlYW4oaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTQsIHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKHJlcGVhdGVkSW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZU5vVGFnKHJlcGVhdGVkSW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkSW50NjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKHJlcGVhdGVkVWludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkVWludDMyTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZU5vVGFnKHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU2ludDMyTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDEgKiBnZXRSZXBlYXRlZEJvb2xMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRCb29sTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0VW5wYWNrZWRUeXBlcyBvdGhlciA9IChwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMpIG9iajsKCiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkSW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZsb2F0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRmxvYXRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRCb29sTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQm9vbExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFyZXBlYXRlZE5lc3RlZEVudW1fLmVxdWFscyhvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChnZXRSZXBlYXRlZEludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9JTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9JTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFVpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFVpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfVUlOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZpeGVkNjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNmaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TRklYRUQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNmaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZsb2F0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GTE9BVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZERvdWJsZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRE9VQkxFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEJvb2xDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0JPT0xfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkQm9vbExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZE5lc3RlZEVudW1Db3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXBlYXRlZE5lc3RlZEVudW1fLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RVbnBhY2tlZFR5cGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBFeHBsaWNpdGx5IHNldCBwYWNrZWQgdG8gZmFsc2UKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM191bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvM191bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdFVucGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdFVucGFja2VkVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RVbnBhY2tlZFR5cGVzLmNsYXNzLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RVbnBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RVbnBhY2tlZFR5cGVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RVbnBhY2tlZFR5cGVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMgcmVzdWx0ID0gbmV3IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0VW5wYWNrZWRUeXBlcyh0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5yZXBlYXRlZE5lc3RlZEVudW1fID0gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RVbnBhY2tlZFR5cGVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbnQzMl8gPSByZXBlYXRlZEludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEludDY0XyA9IHJlcGVhdGVkSW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFVpbnQzMl8gPSByZXBlYXRlZFVpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkVWludDY0XyA9IHJlcGVhdGVkVWludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTaW50MzJfID0gcmVwZWF0ZWRTaW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNpbnQ2NF8gPSByZXBlYXRlZFNpbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZpeGVkMzJfID0gcmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRml4ZWQ2NF8gPSByZXBlYXRlZEZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2ZpeGVkMzJfID0gcmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTZml4ZWQ2NF8gPSByZXBlYXRlZFNmaXhlZDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZsb2F0XyA9IHJlcGVhdGVkRmxvYXRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZERvdWJsZV8gPSByZXBlYXRlZERvdWJsZV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEJvb2xfID0gcmVwZWF0ZWRCb29sXzsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0VW5wYWNrZWRUeXBlcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RVbnBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEludDMyXyA9IG90aGVyLnJlcGVhdGVkSW50MzJfOwogICAgICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkSW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEludDY0XyA9IG90aGVyLnJlcGVhdGVkSW50NjRfOwogICAgICAgICAgICByZXBlYXRlZEludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkVWludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFVpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXyA9IG90aGVyLnJlcGVhdGVkVWludDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZFVpbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRVaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkVWludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gb3RoZXIucmVwZWF0ZWRVaW50NjRfOwogICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkVWludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8gPSBvdGhlci5yZXBlYXRlZFNpbnQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTaW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2ludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IG90aGVyLnJlcGVhdGVkU2ludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNpbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gb3RoZXIucmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZEZpeGVkMzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IG90aGVyLnJlcGVhdGVkRml4ZWQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGaXhlZDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNmaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNmaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBvdGhlci5yZXBlYXRlZFNmaXhlZDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNmaXhlZDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNmaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNmaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBvdGhlci5yZXBlYXRlZFNmaXhlZDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNmaXhlZDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZsb2F0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEZsb2F0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBvdGhlci5yZXBlYXRlZEZsb2F0XzsKICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEZsb2F0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZERvdWJsZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWREb3VibGVfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBvdGhlci5yZXBlYXRlZERvdWJsZV87CiAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWREb3VibGVfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQm9vbF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRCb29sXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRCb29sXyA9IG90aGVyLnJlcGVhdGVkQm9vbF87CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRCb29sXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRCb29sXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGRBbGwob3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKGlucHV0LnJlYWRJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjQ6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRJbnQoaW5wdXQucmVhZFVJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzI6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRVSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGNhc2UgNDA6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFNJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAKICAgICAgICAgICAgICBjYXNlIDQyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5hZGRJbnQoaW5wdXQucmVhZFNJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MgogICAgICAgICAgICAgIGNhc2UgNDg6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OAogICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLmFkZExvbmcoaW5wdXQucmVhZFNJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MAogICAgICAgICAgICAgIGNhc2UgNjE6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjEKICAgICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KGlucHV0LnJlYWRGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU4CiAgICAgICAgICAgICAgY2FzZSA2NTogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY1CiAgICAgICAgICAgICAgY2FzZSA2NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZExvbmcoaW5wdXQucmVhZEZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjYKICAgICAgICAgICAgICBjYXNlIDc3OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc3CiAgICAgICAgICAgICAgY2FzZSA3NDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkMzJJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uYWRkSW50KGlucHV0LnJlYWRTRml4ZWQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NAogICAgICAgICAgICAgIGNhc2UgODE6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MQogICAgICAgICAgICAgIGNhc2UgODI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcoaW5wdXQucmVhZFNGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgyCiAgICAgICAgICAgICAgY2FzZSA5MzogewogICAgICAgICAgICAgICAgZmxvYXQgdiA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkRmxvYXQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTMKICAgICAgICAgICAgICBjYXNlIDkwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdChpbnB1dC5yZWFkRmxvYXQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTAKICAgICAgICAgICAgICBjYXNlIDk3OiB7CiAgICAgICAgICAgICAgICBkb3VibGUgdiA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkRG91YmxlKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk3CiAgICAgICAgICAgICAgY2FzZSA5ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRG91YmxlXy5hZGREb3VibGUoaW5wdXQucmVhZERvdWJsZSgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5OAogICAgICAgICAgICAgIGNhc2UgMTA0OiB7CiAgICAgICAgICAgICAgICBib29sZWFuIHYgPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEJvb2xlYW4odik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA0CiAgICAgICAgICAgICAgY2FzZSAxMDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoYWxsb2MgLyAxKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRCb29sXy5hZGRCb29sZWFuKGlucHV0LnJlYWRCb29sKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNgogICAgICAgICAgICAgIGNhc2UgMTEyOiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTIKICAgICAgICAgICAgICBjYXNlIDExNDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExNAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkSW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEludDMyKCkgewogICAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRJbnQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkSW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZEludDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZEludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkSW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRJbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRJbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRJbnQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkSW50NjQoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRVaW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRVaW50MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRVaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFVpbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFVpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFVpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkVWludDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRVaW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkVWludDMyKCkgewogICAgICAgIHJlcGVhdGVkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRVaW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRVaW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRVaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRVaW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkVWludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVWludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRVaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVWludDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFVpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkVWludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRVaW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSA0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkVWludDY0KCkgewogICAgICAgIHJlcGVhdGVkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNpbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNpbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkU2ludDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSA1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNpbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gNSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2ludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2ludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTaW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFNpbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTaW50MzIoKSB7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNpbnQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNpbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSA2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkU2ludDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSA2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFNpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gNiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTaW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2ludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTaW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFNpbnQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTaW50NjQoKSB7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkMzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRml4ZWQzMl8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gNyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaXhlZDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZpeGVkMzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRGaXhlZDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSA3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRml4ZWQzMigpIHsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkNjRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRGaXhlZDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSA4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGaXhlZDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaXhlZDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGaXhlZDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRml4ZWQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gOCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZpeGVkNjQoKSB7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTZml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ZpeGVkMzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRTZml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFNmaXhlZDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSA5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNmaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTZml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU2ZpeGVkMzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ZpeGVkMzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gOSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNmaXhlZDMyKCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTZml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ZpeGVkNjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRTZml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ZpeGVkNjRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFNmaXhlZDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFNmaXhlZDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDEwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNmaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSAxMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTZml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU2ZpeGVkNjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ZpeGVkNjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gMTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTZml4ZWQ2NCgpIHsKICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5GbG9hdExpc3QgcmVwZWF0ZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRmxvYXRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZsb2F0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZsb2F0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRmxvYXRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZsb2F0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZsb2F0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAxMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGbG9hdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRSZXBlYXRlZEZsb2F0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0Xy5nZXRGbG9hdChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZsb2F0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGbG9hdCgKICAgICAgICAgIGludCBpbmRleCwgZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfLnNldEZsb2F0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZsb2F0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDExIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEZsb2F0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGbG9hdCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRmxvYXRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRGbG9hdCgpIHsKICAgICAgICByZXBlYXRlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWREb3VibGVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWREb3VibGVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRG91YmxlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRG91YmxlXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAxMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWREb3VibGUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpIHsKICAgICAgICByZXBlYXRlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAxMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWREb3VibGUuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRG91YmxlQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAxMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0UmVwZWF0ZWREb3VibGUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXy5nZXREb3VibGUoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZERvdWJsZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRG91YmxlKAogICAgICAgICAgaW50IGluZGV4LCBkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZERvdWJsZV8uc2V0RG91YmxlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gMTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWREb3VibGUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZERvdWJsZShkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkRG91YmxlKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAxMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWREb3VibGUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZERvdWJsZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWREb3VibGVfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSAxMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZERvdWJsZSgpIHsKICAgICAgICByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCByZXBlYXRlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRCb29sXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEJvb2xfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEJvb2xfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkQm9vbF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCb29sLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0UmVwZWF0ZWRCb29sTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCb29sQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2woaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRCb29sIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRCb29sKAogICAgICAgICAgaW50IGluZGV4LCBib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQm9vbF8uc2V0Qm9vbGVhbihpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gMTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRCb29sIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRCb29sKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCb29sXy5hZGRCb29sZWFuKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDEzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEJvb2wgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEJvb2woCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRCb29sXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSAxMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEJvb2woKSB7CiAgICAgICAgcmVwZWF0ZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkTmVzdGVkRW51bV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4ocmVwZWF0ZWROZXN0ZWRFbnVtXywgcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRSZXBlYXRlZE5lc3RlZEVudW0oaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWRFbnVtKAogICAgICAgICAgaW50IGluZGV4LCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZEVudW0ocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRFbnVtKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWROZXN0ZWRFbnVtKCkgewogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGVudW0gbnVtZXJpYyB2YWx1ZXMgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWVMaXN0KCkgewogICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE5lc3RlZEVudW1fKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDE0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBvZiByZXBlYXRlZE5lc3RlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBlbnVtIG51bWVyaWMgdmFsdWUgb24gdGhlIHdpcmUgZm9yIHJlcGVhdGVkTmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkRW51bVZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gMTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZEVudW1WYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSAxNCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZW51bSBudW1lcmljIHZhbHVlcyBvbiB0aGUgd2lyZSBmb3IgcmVwZWF0ZWROZXN0ZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRFbnVtVmFsdWUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAoaW50IHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvM191bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8zX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZFR5cGVzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RVbnBhY2tlZFR5cGVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0VW5wYWNrZWRUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RVbnBhY2tlZFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFVucGFja2VkVHlwZXM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFVucGFja2VkVHlwZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0VW5wYWNrZWRUeXBlcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbnBhY2tlZFR5cGVzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbnBhY2tlZFR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdFVucGFja2VkVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBOZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8zX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNoaWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNDaGlsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY2hpbGQuCiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgZ2V0Q2hpbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRDaGlsZE9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXlsb2FkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNQYXlsb2FkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHBheWxvYWQuCiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMgZ2V0UGF5bG9hZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UGF5bG9hZE9yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRoaXMgcHJvdG8gaW5jbHVkZXMgYSByZWN1cnNpdmVseSBuZXN0ZWQgbWVzc2FnZS4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM191bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBOZXN0ZWRUZXN0QWxsVHlwZXMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8zX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcykKICAgICAgTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBOZXN0ZWRUZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgTmVzdGVkVGVzdEFsbFR5cGVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgTmVzdGVkVGVzdEFsbFR5cGVzKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE5lc3RlZFRlc3RBbGxUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMuY2xhc3MsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENISUxEX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGRfOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0NoaWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgZ2V0Q2hpbGQoKSB7CiAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldENoaWxkT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gY2hpbGRfID09IG51bGwgPyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogY2hpbGRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBWUxPQURfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcyBwYXlsb2FkXzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXlsb2FkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUGF5bG9hZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBwYXlsb2FkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcyBnZXRQYXlsb2FkKCkgewogICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBwYXlsb2FkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRQYXlsb2FkT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBwYXlsb2FkXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgZ2V0Q2hpbGQoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyLCBnZXRQYXlsb2FkKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0Q2hpbGQoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIsIGdldFBheWxvYWQoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcyBvdGhlciA9IChwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzKSBvYmo7CgogICAgICBpZiAoaGFzQ2hpbGQoKSAhPSBvdGhlci5oYXNDaGlsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNDaGlsZCgpKSB7CiAgICAgICAgaWYgKCFnZXRDaGlsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Q2hpbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUGF5bG9hZCgpICE9IG90aGVyLmhhc1BheWxvYWQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUGF5bG9hZCgpKSB7CiAgICAgICAgaWYgKCFnZXRQYXlsb2FkKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYXlsb2FkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzQ2hpbGQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIENISUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRDaGlsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1BheWxvYWQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBWUxPQURfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBheWxvYWQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoaXMgcHJvdG8gaW5jbHVkZXMgYSByZWN1cnNpdmVseSBuZXN0ZWQgbWVzc2FnZS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM191bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzNfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzKQogICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzLmNsYXNzLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRDaGlsZEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgY2hpbGRfID0gbnVsbDsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBwYXlsb2FkXyA9IG51bGw7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVzdWx0ID0gbmV3IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXModGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5jaGlsZF8gPSBjaGlsZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGNoaWxkXwogICAgICAgICAgICAgIDogY2hpbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnBheWxvYWRfID0gcGF5bG9hZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IHBheWxvYWRfCiAgICAgICAgICAgICAgOiBwYXlsb2FkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzQ2hpbGQoKSkgewogICAgICAgICAgbWVyZ2VDaGlsZChvdGhlci5nZXRDaGlsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1BheWxvYWQoKSkgewogICAgICAgICAgbWVyZ2VQYXlsb2FkKG90aGVyLmdldFBheWxvYWQoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldENoaWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldFBheWxvYWRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlcj4gY2hpbGRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2hpbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzQ2hpbGQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzIGdldENoaWxkKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDaGlsZChwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBjaGlsZF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Q2hpbGQoCiAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgY2hpbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlQ2hpbGQocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBjaGlsZF8gIT0gbnVsbCAmJgogICAgICAgICAgICBjaGlsZF8gIT0gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRDaGlsZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY2hpbGRfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGNoaWxkXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNoaWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBjaGlsZF8gPSBudWxsOwogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgY2hpbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRDaGlsZEJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRDaGlsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldENoaWxkT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogY2hpbGRfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRDaGlsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcywgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0Q2hpbGQoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGNoaWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMgcGF5bG9hZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gcGF5bG9hZEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBheWxvYWQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzUGF5bG9hZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcGF5bG9hZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzIGdldFBheWxvYWQoKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBwYXlsb2FkXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHBheWxvYWRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYXlsb2FkKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgcGF5bG9hZF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBheWxvYWQoCiAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBwYXlsb2FkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VQYXlsb2FkKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSAmJgogICAgICAgICAgICBwYXlsb2FkXyAhPSBudWxsICYmCiAgICAgICAgICAgIHBheWxvYWRfICE9IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0UGF5bG9hZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGF5bG9hZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChwYXlsb2FkXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGF5bG9hZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgcGF5bG9hZF8gPSBudWxsOwogICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHBheWxvYWRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldFBheWxvYWRCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UGF5bG9hZE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBwYXlsb2FkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBheWxvYWRfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcywgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFBheWxvYWRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRQYXlsb2FkKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBwYXlsb2FkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwYXlsb2FkQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG8zX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8zX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5OZXN0ZWRUZXN0QWxsVHlwZXMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLk5lc3RlZFRlc3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZFRlc3RBbGxUeXBlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxOZXN0ZWRUZXN0QWxsVHlwZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBOZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRUZXN0QWxsVHlwZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkVGVzdEFsbFR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuTmVzdGVkVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgYyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYy4KICAgICAqLwogICAgaW50IGdldEMoKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBEZWZpbmUgdGhlc2UgYWZ0ZXIgVGVzdEFsbFR5cGVzIHRvIG1ha2Ugc3VyZSB0aGUgY29tcGlsZXIgY2FuIGhhbmRsZQogICAqIHRoYXQuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGb3JlaWduTWVzc2FnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UpCiAgICAgIEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBGb3JlaWduTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBGb3JlaWduTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEZvcmVpZ25NZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEZvcmVpZ25NZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZS5jbGFzcywgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IGNfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgYyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRDKCkgewogICAgICByZXR1cm4gY187CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoY18gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGNfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKGNfICE9IDApIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIGNfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSBvdGhlciA9IChwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UpIG9iajsKCiAgICAgIGlmIChnZXRDKCkKICAgICAgICAgICE9IG90aGVyLmdldEMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIENfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRDKCk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogRGVmaW5lIHRoZXNlIGFmdGVyIFRlc3RBbGxUeXBlcyB0byBtYWtlIHN1cmUgdGhlIGNvbXBpbGVyIGNhbiBoYW5kbGUKICAgICAqIHRoYXQuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UpCiAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZS5jbGFzcywgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBjXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNfID0gY187CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmdldEMoKSAhPSAwKSB7CiAgICAgICAgICBzZXRDKG90aGVyLmdldEMoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgY18gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGMgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDKCkgewogICAgICAgIHJldHVybiBjXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgYyA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDKGludCB2YWx1ZSkgewoKICAgICAgICBjXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgYyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuRm9yZWlnbk1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5Gb3JlaWduTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvcmVpZ25NZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZvcmVpZ25NZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgRm9yZWlnbk1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb3JlaWduTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb3JlaWduTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLkZvcmVpZ25NZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEVtcHR5TWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzNfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUZXN0RW1wdHlNZXNzYWdlIGlzIHVzZWQgdG8gdGVzdCBiZWhhdmlvciBvZiB1bmtub3duIGZpZWxkcy4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM191bml0dGVzdC5UZXN0RW1wdHlNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEVtcHR5TWVzc2FnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90bzNfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZSkKICAgICAgVGVzdEVtcHR5TWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdEVtcHR5TWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0RW1wdHlNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdEVtcHR5TWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0RW1wdHlNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEVtcHR5TWVzc2FnZS5jbGFzcywgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RFbXB0eU1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RFbXB0eU1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlIG90aGVyID0gKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlKSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0RW1wdHlNZXNzYWdlIGlzIHVzZWQgdG8gdGVzdCBiZWhhdmlvciBvZiB1bmtub3duIGZpZWxkcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM191bml0dGVzdC5UZXN0RW1wdHlNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8zX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2UpCiAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RFbXB0eU1lc3NhZ2VPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlLmNsYXNzLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEVtcHR5TWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEVtcHR5TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEVtcHR5TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RFbXB0eU1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RFbXB0eU1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEVtcHR5TWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RFbXB0eU1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RFbXB0eU1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0RW1wdHlNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG8zX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEVtcHR5TWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEVtcHR5TWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RFbXB0eU1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RW1wdHlNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RFbXB0eU1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0RW1wdHlNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEVtcHR5TWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RW1wdHlNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdEVtcHR5TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RNZXNzYWdlV2l0aER1bW15T3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvM191bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhEdW1teSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGlzIGZpZWxkIGlzIG9ubHkgaGVyZSBmb3IgdHJpZ2dlcmluZyBjb3B5LW9uLXdyaXRlOyBpdCdzIG5vdCBpbnRlbmRlZCB0bwogICAgICogYmUgc2VyaWFsaXplZC4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPmJvb2wgZHVtbXkgPSA1MzY4NzA5MTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RHVtbXkoKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUZXN0TWVzc2FnZVdpdGhEdW1teSBpcyBhbHNvIHVzZWQgdG8gdGVzdCBiZWhhdmlvciBvZiB1bmtub3duIGZpZWxkcy4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvM191bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhEdW1teX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RNZXNzYWdlV2l0aER1bW15IGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvM191bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhEdW1teSkKICAgICAgVGVzdE1lc3NhZ2VXaXRoRHVtbXlPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RNZXNzYWdlV2l0aER1bW15Lm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNZXNzYWdlV2l0aER1bW15KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE1lc3NhZ2VXaXRoRHVtbXkoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdE1lc3NhZ2VXaXRoRHVtbXkoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhEdW1teV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aER1bW15X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RNZXNzYWdlV2l0aER1bW15LmNsYXNzLCBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE1lc3NhZ2VXaXRoRHVtbXkuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVNTVlfRklFTERfTlVNQkVSID0gNTM2ODcwOTExOwogICAgcHJpdmF0ZSBib29sZWFuIGR1bW15XyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhpcyBmaWVsZCBpcyBvbmx5IGhlcmUgZm9yIHRyaWdnZXJpbmcgY29weS1vbi13cml0ZTsgaXQncyBub3QgaW50ZW5kZWQgdG8KICAgICAqIGJlIHNlcmlhbGl6ZWQuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5ib29sIGR1bW15ID0gNTM2ODcwOTExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXREdW1teSgpIHsKICAgICAgcmV0dXJuIGR1bW15XzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmIChkdW1teV8gIT0gZmFsc2UpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDUzNjg3MDkxMSwgZHVtbXlfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKGR1bW15XyAhPSBmYWxzZSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSg1MzY4NzA5MTEsIGR1bW15Xyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RNZXNzYWdlV2l0aER1bW15KSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE1lc3NhZ2VXaXRoRHVtbXkgb3RoZXIgPSAocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RNZXNzYWdlV2l0aER1bW15KSBvYmo7CgogICAgICBpZiAoZ2V0RHVtbXkoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0RHVtbXkoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERVTU1ZX0ZJRUxEX05VTUJFUjsKICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoQm9vbGVhbigKICAgICAgICAgIGdldER1bW15KCkpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RNZXNzYWdlV2l0aER1bW15IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RNZXNzYWdlV2l0aER1bW15IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RNZXNzYWdlV2l0aER1bW15IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE1lc3NhZ2VXaXRoRHVtbXkgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RNZXNzYWdlV2l0aER1bW15IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RNZXNzYWdlV2l0aER1bW15IHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE1lc3NhZ2VXaXRoRHVtbXkgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE1lc3NhZ2VXaXRoRHVtbXkgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRlc3RNZXNzYWdlV2l0aER1bW15IGlzIGFsc28gdXNlZCB0byB0ZXN0IGJlaGF2aW9yIG9mIHVua25vd24gZmllbGRzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG8zX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aER1bW15fQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG8zX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aER1bW15KQogICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhEdW1teV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhEdW1teV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE1lc3NhZ2VXaXRoRHVtbXkuY2xhc3MsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgZHVtbXlfID0gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aER1bW15X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE1lc3NhZ2VXaXRoRHVtbXkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teSBidWlsZCgpIHsKICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE1lc3NhZ2VXaXRoRHVtbXkgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE1lc3NhZ2VXaXRoRHVtbXkgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teSByZXN1bHQgPSBuZXcgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RNZXNzYWdlV2l0aER1bW15KHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmR1bW15XyA9IGR1bW15XzsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE1lc3NhZ2VXaXRoRHVtbXkpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE1lc3NhZ2VXaXRoRHVtbXkgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RNZXNzYWdlV2l0aER1bW15LmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuZ2V0RHVtbXkoKSAhPSBmYWxzZSkgewogICAgICAgICAgc2V0RHVtbXkob3RoZXIuZ2V0RHVtbXkoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgLTg6IHsKICAgICAgICAgICAgICAgIGR1bW15XyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgLTgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBib29sZWFuIGR1bW15XyA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGlzIGZpZWxkIGlzIG9ubHkgaGVyZSBmb3IgdHJpZ2dlcmluZyBjb3B5LW9uLXdyaXRlOyBpdCdzIG5vdCBpbnRlbmRlZCB0bwogICAgICAgKiBiZSBzZXJpYWxpemVkLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+Ym9vbCBkdW1teSA9IDUzNjg3MDkxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXREdW1teSgpIHsKICAgICAgICByZXR1cm4gZHVtbXlfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGlzIGZpZWxkIGlzIG9ubHkgaGVyZSBmb3IgdHJpZ2dlcmluZyBjb3B5LW9uLXdyaXRlOyBpdCdzIG5vdCBpbnRlbmRlZCB0bwogICAgICAgKiBiZSBzZXJpYWxpemVkLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+Ym9vbCBkdW1teSA9IDUzNjg3MDkxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREdW1teShib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGR1bW15XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhpcyBmaWVsZCBpcyBvbmx5IGhlcmUgZm9yIHRyaWdnZXJpbmcgY29weS1vbi13cml0ZTsgaXQncyBub3QgaW50ZW5kZWQgdG8KICAgICAgICogYmUgc2VyaWFsaXplZC4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPmJvb2wgZHVtbXkgPSA1MzY4NzA5MTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBkdW1teV8gPSBmYWxzZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90bzNfdW5pdHRlc3QuVGVzdE1lc3NhZ2VXaXRoRHVtbXkpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvM191bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhEdW1teSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE1lc3NhZ2VXaXRoRHVtbXkoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0TWVzc2FnZVdpdGhEdW1teSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlV2l0aER1bW15PgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RNZXNzYWdlV2l0aER1bW15PigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE1lc3NhZ2VXaXRoRHVtbXkgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZVdpdGhEdW1teT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZVdpdGhEdW1teT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RNZXNzYWdlV2l0aER1bW15IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE9uZW9mMk9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90bzNfdW5pdHRlc3QuVGVzdE9uZW9mMikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90bzNfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIGZvb19lbnVtID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb0VudW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0Zvb0VudW0oKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZEVudW0gZm9vX2VudW0gPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgZm9vRW51bS4KICAgICAqLwogICAgaW50IGdldEZvb0VudW1WYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bSBmb29fZW51bSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vRW51bS4KICAgICAqLwogICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIuTmVzdGVkRW51bSBnZXRGb29FbnVtKCk7CgogICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIuRm9vQ2FzZSBnZXRGb29DYXNlKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogU2FtZSBsYXlvdXQgYXMgVGVzdE9uZW9mMiBpbiB1bml0dGVzdC5wcm90byB0byB0ZXN0IHVua25vd24gZW51bSB2YWx1ZQogICAqIHBhcnNpbmcgYmVoYXZpb3IgaW4gb25lb2YuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfdW5pdHRlc3QuVGVzdE9uZW9mMn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RPbmVvZjIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG8zX3VuaXR0ZXN0LlRlc3RPbmVvZjIpCiAgICAgIFRlc3RPbmVvZjJPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RPbmVvZjIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdE9uZW9mMihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RPbmVvZjIoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdE9uZW9mMigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RPbmVvZjJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0T25lb2YyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIuY2xhc3MsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG8zX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bX0KICAgICAqLwogICAgcHVibGljIGVudW0gTmVzdGVkRW51bQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlVOS05PV04gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIFVOS05PV04oMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEZPTygxKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQkFSKDIpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QkFaID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVooMyksCiAgICAgIFVOUkVDT0dOSVpFRCgtMSksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5VTktOT1dOID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX1ZBTFVFID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSX1ZBTFVFID0gMjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBWiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFaX1ZBTFVFID0gMzsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICJDYW4ndCBnZXQgdGhlIG51bWJlciBvZiBhbiB1bmtub3duIGVudW0gdmFsdWUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAwOiByZXR1cm4gVU5LTk9XTjsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIEZPTzsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIEJBUjsKICAgICAgICAgIGNhc2UgMzogcmV0dXJuIEJBWjsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE5lc3RlZEVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBOZXN0ZWRFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIE5lc3RlZEVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIE5lc3RlZEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgZGVzY3JpcHRvciBvZiBhbiB1bnJlY29nbml6ZWQgZW51bSB2YWx1ZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE5lc3RlZEVudW1bXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSB2YWx1ZU9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgICAgfQogICAgICAgIGlmIChkZXNjLmdldEluZGV4KCkgPT0gLTEpIHsKICAgICAgICAgIHJldHVybiBVTlJFQ09HTklaRUQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgICBwcml2YXRlIE5lc3RlZEVudW0oaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90bzNfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtKQogICAgfQoKICAgIHByaXZhdGUgaW50IGZvb0Nhc2VfID0gMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGZvb187CiAgICBwdWJsaWMgZW51bSBGb29DYXNlCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZS5JbnRlcm5hbE9uZU9mRW51bSB7CiAgICAgIEZPT19FTlVNKDYpLAogICAgICBGT09fTk9UX1NFVCgwKTsKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CiAgICAgIHByaXZhdGUgRm9vQ2FzZShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtYmVyIG9mIHRoZSBlbnVtIHRvIGxvb2sgZm9yLgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtYmVyLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIEZvb0Nhc2UgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBGb29DYXNlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDY6IHJldHVybiBGT09fRU5VTTsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIEZPT19OT1RfU0VUOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB0aGlzLnZhbHVlOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBGb29DYXNlCiAgICBnZXRGb29DYXNlKCkgewogICAgICByZXR1cm4gRm9vQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICBmb29DYXNlXyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX0VOVU1fRklFTERfTlVNQkVSID0gNjsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZEVudW0gZm9vX2VudW0gPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vRW51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb0VudW0oKSB7CiAgICAgIHJldHVybiBmb29DYXNlXyA9PSA2OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bSBmb29fZW51bSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBmb29FbnVtLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZvb0VudW1WYWx1ZSgpIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDYpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSBmb29fOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bSBmb29fZW51bSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vRW51bS4KICAgICAqLwogICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyLk5lc3RlZEVudW0gZ2V0Rm9vRW51bSgpIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDYpIHsKICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIHJlc3VsdCA9IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyLk5lc3RlZEVudW0uZm9yTnVtYmVyKAogICAgICAgICAgICAoamF2YS5sYW5nLkludGVnZXIpIGZvb18pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyLk5lc3RlZEVudW0uVU5SRUNPR05JWkVEIDogcmVzdWx0OwogICAgICB9CiAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtLlVOS05PV047CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoZm9vQ2FzZV8gPT0gNikgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oNiwgKChqYXZhLmxhbmcuSW50ZWdlcikgZm9vXykpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoZm9vQ2FzZV8gPT0gNikgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSg2LCAoKGphdmEubGFuZy5JbnRlZ2VyKSBmb29fKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyIG90aGVyID0gKHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyKSBvYmo7CgogICAgICBpZiAoIWdldEZvb0Nhc2UoKS5lcXVhbHMob3RoZXIuZ2V0Rm9vQ2FzZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBzd2l0Y2ggKGZvb0Nhc2VfKSB7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgaWYgKGdldEZvb0VudW1WYWx1ZSgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0Rm9vRW51bVZhbHVlKCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgc3dpdGNoIChmb29DYXNlXykgewogICAgICAgIGNhc2UgNjoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZPT19FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZvb0VudW1WYWx1ZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFNhbWUgbGF5b3V0IGFzIFRlc3RPbmVvZjIgaW4gdW5pdHRlc3QucHJvdG8gdG8gdGVzdCB1bmtub3duIGVudW0gdmFsdWUKICAgICAqIHBhcnNpbmcgYmVoYXZpb3IgaW4gb25lb2YuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90bzNfdW5pdHRlc3QuVGVzdE9uZW9mMn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvM191bml0dGVzdC5UZXN0T25lb2YyKQogICAgICAgIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5pbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RPbmVvZjJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLmludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdE9uZW9mMl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMi5jbGFzcywgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMi5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgZm9vQ2FzZV8gPSAwOwogICAgICAgIGZvb18gPSBudWxsOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0T25lb2YyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMiBidWlsZCgpIHsKICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMiByZXN1bHQgPSBuZXcgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBidWlsZFBhcnRpYWxPbmVvZnMocmVzdWx0KTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxPbmVvZnMocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIgcmVzdWx0KSB7CiAgICAgICAgcmVzdWx0LmZvb0Nhc2VfID0gZm9vQ2FzZV87CiAgICAgICAgcmVzdWx0LmZvb18gPSB0aGlzLmZvb187CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHN3aXRjaCAob3RoZXIuZ2V0Rm9vQ2FzZSgpKSB7CiAgICAgICAgICBjYXNlIEZPT19FTlVNOiB7CiAgICAgICAgICAgIHNldEZvb0VudW1WYWx1ZShvdGhlci5nZXRGb29FbnVtVmFsdWUoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGT09fTk9UX1NFVDogewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA0ODogewogICAgICAgICAgICAgICAgaW50IHJhd1ZhbHVlID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIGZvb0Nhc2VfID0gNjsKICAgICAgICAgICAgICAgIGZvb18gPSByYXdWYWx1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGZvb0Nhc2VfID0gMDsKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGZvb187CiAgICAgIHB1YmxpYyBGb29DYXNlCiAgICAgICAgICBnZXRGb29DYXNlKCkgewogICAgICAgIHJldHVybiBGb29DYXNlLmZvck51bWJlcigKICAgICAgICAgICAgZm9vQ2FzZV8pOwogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZvbygpIHsKICAgICAgICBmb29DYXNlXyA9IDA7CiAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZEVudW0gZm9vX2VudW0gPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29FbnVtIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vRW51bSgpIHsKICAgICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gNjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZEVudW0gZm9vX2VudW0gPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBudW1lcmljIHZhbHVlIG9uIHRoZSB3aXJlIGZvciBmb29FbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZvb0VudW1WYWx1ZSgpIHsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gNikgewogICAgICAgICAgcmV0dXJuICgoamF2YS5sYW5nLkludGVnZXIpIGZvb18pLmludFZhbHVlKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bSBmb29fZW51bSA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW0gbnVtZXJpYyB2YWx1ZSBvbiB0aGUgd2lyZSBmb3IgZm9vRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvb0VudW1WYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgICBmb29DYXNlXyA9IDY7CiAgICAgICAgZm9vXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bSBmb29fZW51bSA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmb29FbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG8zX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8zLlRlc3RPbmVvZjIuTmVzdGVkRW51bSBnZXRGb29FbnVtKCkgewogICAgICAgIGlmIChmb29DYXNlXyA9PSA2KSB7CiAgICAgICAgICBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIHJlc3VsdCA9IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyLk5lc3RlZEVudW0uZm9yTnVtYmVyKAogICAgICAgICAgICAgIChqYXZhLmxhbmcuSW50ZWdlcikgZm9vXyk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtLlVOUkVDT0dOSVpFRCA6IHJlc3VsdDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyLk5lc3RlZEVudW0uVU5LTk9XTjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvM191bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZEVudW0gZm9vX2VudW0gPSA2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb29FbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vRW51bShwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDY7CiAgICAgICAgZm9vXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG8zX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bSBmb29fZW51bSA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZvb0VudW0oKSB7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDYpIHsKICAgICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvM191bml0dGVzdC5UZXN0T25lb2YyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90bzNfdW5pdHRlc3QuVGVzdE9uZW9mMikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90bzNfdW5pdHRlc3QuVW5pdHRlc3RQcm90bzMuVGVzdE9uZW9mMiBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RPbmVvZjI+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdE9uZW9mMj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RPbmVvZjIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0T25lb2YyPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RPbmVvZjI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvM191bml0dGVzdC5Vbml0dGVzdFByb3RvMy5UZXN0T25lb2YyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdFVucGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9OZXN0ZWRUZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoRHVtbXlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aER1bW15X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdE9uZW9mMl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdE9uZW9mMl9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuJWdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9wcm90bzMucHJvdG9cMDIyIiArCiAgICAgICJcMDE3cHJvdG8zX3VuaXR0ZXN0XDAzMiVnb29nbGUvcHJvdG9idWYvdW5pdHRlIiArCiAgICAgICJzdF9pbXBvcnQucHJvdG9cIlwyMDNcMDIyXG5cMDE0VGVzdEFsbFR5cGVzXDAyMlwwMjZcblwwMTZvcHRpIiArCiAgICAgICJvbmFsX2ludDMyXDAzMFwwMDEgXDAwMShcMDA1XDAyMlwwMjZcblwwMTZvcHRpb25hbF9pbnQ2NFwwMzBcMDAyIFwwMDEoXDAwMyIgKwogICAgICAiXDAyMlwwMjdcblwwMTdvcHRpb25hbF91aW50MzJcMDMwXDAwMyBcMDAxKFxyXDAyMlwwMjdcblwwMTdvcHRpb25hbF91aSIgKwogICAgICAibnQ2NFwwMzBcMDA0IFwwMDEoXDAwNFwwMjJcMDI3XG5cMDE3b3B0aW9uYWxfc2ludDMyXDAzMFwwMDUgXDAwMShcMDIxXDAyMlwwMjdcblwwMTdvIiArCiAgICAgICJwdGlvbmFsX3NpbnQ2NFwwMzBcMDA2IFwwMDEoXDAyMlwwMjJcMDMwXG5cMDIwb3B0aW9uYWxfZml4ZWQzMiIgKwogICAgICAiXDAzMFwwMDcgXDAwMShcMDA3XDAyMlwwMzBcblwwMjBvcHRpb25hbF9maXhlZDY0XDAzMFwwMTAgXDAwMShcMDA2XDAyMlwwMzFcblwwMjFvcHRpIiArCiAgICAgICJvbmFsX3NmaXhlZDMyXDAzMFx0IFwwMDEoXDAxN1wwMjJcMDMxXG5cMDIxb3B0aW9uYWxfc2ZpeGVkNjQiICsKICAgICAgIlwwMzBcbiBcMDAxKFwwMjBcMDIyXDAyNlxuXDAxNm9wdGlvbmFsX2Zsb2F0XDAzMFwwMTMgXDAwMShcMDAyXDAyMlwwMjdcblwwMTdvcHRpb24iICsKICAgICAgImFsX2RvdWJsZVwwMzBcMDE0IFwwMDEoXDAwMVwwMjJcMDI1XG5ccm9wdGlvbmFsX2Jvb2xcMDMwXHIgXDAwMShcMDEwXDAyMlwwMjciICsKICAgICAgIlxuXDAxN29wdGlvbmFsX3N0cmluZ1wwMzBcMDE2IFwwMDEoXHRcMDIyXDAyNlxuXDAxNm9wdGlvbmFsX2J5dGUiICsKICAgICAgInNcMDMwXDAxNyBcMDAxKFwwMTRcMDIyUVxuXDAyN29wdGlvbmFsX25lc3RlZF9tZXNzYWdlXDAzMFwwMjIgXDAwMShcMDEzIiArCiAgICAgICIyKy5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lIiArCiAgICAgICJzc2FnZUhcMDAxXDIxMFwwMDFcMDAxXDAyMkFcblwwMzBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VcMDMwXDAyMyIgKwogICAgICAiIFwwMDEoXDAxMzJcMDM3LnByb3RvM191bml0dGVzdC5Gb3JlaWduTWVzc2FnZVwwMjJIXG4iICsKICAgICAgIlwwMjdvcHRpb25hbF9pbXBvcnRfbWVzc2FnZVwwMzBcMDI0IFwwMDEoXDAxMzJcJy5wcm90b2J1IiArCiAgICAgICJmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlXDAyMkZcblwwMjRvcHRpbyIgKwogICAgICAibmFsX25lc3RlZF9lbnVtXDAzMFwwMjUgXDAwMShcMDE2MigucHJvdG8zX3VuaXR0ZXN0LiIgKwogICAgICAiVGVzdEFsbFR5cGVzLk5lc3RlZEVudW1cMDIyO1xuXDAyNW9wdGlvbmFsX2ZvcmUiICsKICAgICAgImlnbl9lbnVtXDAzMFwwMjYgXDAwMShcMDE2MlwwMzQucHJvdG8zX3VuaXR0ZXN0LkZvcmVpZ24iICsKICAgICAgIkVudW1cMDIyIVxuXDAyNW9wdGlvbmFsX3N0cmluZ19waWVjZVwwMzBcMDMwIFwwMDEoXHRCXDAwMlwwMTBcMDAyXDAyMiIgKwogICAgICAiXDAzMVxuXHJvcHRpb25hbF9jb3JkXDAzMFwwMzEgXDAwMShcdEJcMDAyXDAxMFwwMDFcMDIyVVxuXDAzNm9wdGlvbmFsX3AiICsKICAgICAgInVibGljX2ltcG9ydF9tZXNzYWdlXDAzMFwwMzIgXDAwMShcMDEzMi0ucHJvdG9idWZfdW4iICsKICAgICAgIml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZVwwMjJOXG5cMDI1b3B0IiArCiAgICAgICJpb25hbF9sYXp5X21lc3NhZ2VcMDMwXDAzMyBcMDAxKFwwMTMyKy5wcm90bzNfdW5pdHRlIiArCiAgICAgICJzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZUJcMDAyKFwwMDFcMDIyWVxuIG9wdCIgKwogICAgICAiaW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2VcMDMwXDAzNCBcMDAxKFwwMTMyKy5wciIgKwogICAgICAib3RvM191bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSIgKwogICAgICAiQlwwMDJ4XDAwMVwwMjJRXG5cMDM0b3B0aW9uYWxfbGF6eV9pbXBvcnRfbWVzc2FnZVwwMzBzIFwwMDEiICsKICAgICAgIihcMDEzMlwnLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzIiArCiAgICAgICJhZ2VCXDAwMihcMDAxXDAyMlwwMjZcblwwMTZyZXBlYXRlZF9pbnQzMlwwMzBcMDM3IFwwMDMoXDAwNVwwMjJcMDI2XG5cMDE2cmVwZWEiICsKICAgICAgInRlZF9pbnQ2NFwwMzAgIFwwMDMoXDAwM1wwMjJcMDI3XG5cMDE3cmVwZWF0ZWRfdWludDMyXDAzMCEgXDAwMyhcciIgKwogICAgICAiXDAyMlwwMjdcblwwMTdyZXBlYXRlZF91aW50NjRcMDMwXCIgXDAwMyhcMDA0XDAyMlwwMjdcblwwMTdyZXBlYXRlZF9zaSIgKwogICAgICAibnQzMlwwMzAjIFwwMDMoXDAyMVwwMjJcMDI3XG5cMDE3cmVwZWF0ZWRfc2ludDY0XDAzMCQgXDAwMyhcMDIyXDAyMlwwMzBcblwwMjByIiArCiAgICAgICJlcGVhdGVkX2ZpeGVkMzJcMDMwJSBcMDAzKFwwMDdcMDIyXDAzMFxuXDAyMHJlcGVhdGVkX2ZpeGVkNiIgKwogICAgICAiNFwwMzAmIFwwMDMoXDAwNlwwMjJcMDMxXG5cMDIxcmVwZWF0ZWRfc2ZpeGVkMzJcMDMwXCcgXDAwMyhcMDE3XDAyMlwwMzFcblwwMjFyZSIgKwogICAgICAicGVhdGVkX3NmaXhlZDY0XDAzMCggXDAwMyhcMDIwXDAyMlwwMjZcblwwMTZyZXBlYXRlZF9mbG9hdFwwMzAiICsKICAgICAgIikgXDAwMyhcMDAyXDAyMlwwMjdcblwwMTdyZXBlYXRlZF9kb3VibGVcMDMwKiBcMDAzKFwwMDFcMDIyXDAyNVxuXHJyZXBlYXQiICsKICAgICAgImVkX2Jvb2xcMDMwKyBcMDAzKFwwMTBcMDIyXDAyN1xuXDAxN3JlcGVhdGVkX3N0cmluZ1wwMzAsIFwwMDMoXHRcMDIyXDAyNiIgKwogICAgICAiXG5cMDE2cmVwZWF0ZWRfYnl0ZXNcMDMwLSBcMDAzKFwwMTRcMDIyTFxuXDAyN3JlcGVhdGVkX25lc3RlIiArCiAgICAgICJkX21lc3NhZ2VcMDMwMCBcMDAzKFwwMTMyKy5wcm90bzNfdW5pdHRlc3QuVGVzdEFsIiArCiAgICAgICJsVHlwZXMuTmVzdGVkTWVzc2FnZVwwMjJBXG5cMDMwcmVwZWF0ZWRfZm9yZWlnbiIgKwogICAgICAiX21lc3NhZ2VcMDMwMSBcMDAzKFwwMTMyXDAzNy5wcm90bzNfdW5pdHRlc3QuRm9yZWlnbiIgKwogICAgICAiTWVzc2FnZVwwMjJIXG5cMDI3cmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2VcMDMwMiBcMDAzKFwwMTMiICsKICAgICAgIjJcJy5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnIiArCiAgICAgICJlXDAyMkZcblwwMjRyZXBlYXRlZF9uZXN0ZWRfZW51bVwwMzAzIFwwMDMoXDAxNjIoLnByb3RvMyIgKwogICAgICAiX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtXDAyMjtcblwwMjVyZXAiICsKICAgICAgImVhdGVkX2ZvcmVpZ25fZW51bVwwMzA0IFwwMDMoXDAxNjJcMDM0LnByb3RvM191bml0dGUiICsKICAgICAgInN0LkZvcmVpZ25FbnVtXDAyMiFcblwwMjVyZXBlYXRlZF9zdHJpbmdfcGllY2VcMDMwIiArCiAgICAgICI2IFwwMDMoXHRCXDAwMlwwMTBcMDAyXDAyMlwwMzFcblxycmVwZWF0ZWRfY29yZFwwMzA3IFwwMDMoXHRCXDAwMlwwMTBcMDAxXDAyMk5cblwwMjUiICsKICAgICAgInJlcGVhdGVkX2xhenlfbWVzc2FnZVwwMzA5IFwwMDMoXDAxMzIrLnByb3RvM191bmkiICsKICAgICAgInR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlQlwwMDIoXDAwMVwwMjJcMDI2XG5cMDE0IiArCiAgICAgICJvbmVvZl91aW50MzJcMDMwbyBcMDAxKFxySFwwMDBcMDIyS1xuXDAyNG9uZW9mX25lc3RlZF9tZXMiICsKICAgICAgInNhZ2VcMDMwcCBcMDAxKFwwMTMyKy5wcm90bzNfdW5pdHRlc3QuVGVzdEFsbFR5cGUiICsKICAgICAgInMuTmVzdGVkTWVzc2FnZUhcMDAwXDAyMlwwMjZcblwwMTRvbmVvZl9zdHJpbmdcMDMwcSBcMDAxKFx0SCIgKwogICAgICAiXDAwMFwwMjJcMDI1XG5cMDEzb25lb2ZfYnl0ZXNcMDMwciBcMDAxKFwwMTRIXDAwMFwwMzJcMDMzXG5cck5lc3RlZE1lc3NhZyIgKwogICAgICAiZVwwMjJcblxuXDAwMmJiXDAzMFwwMDEgXDAwMShcMDA1XCJDXG5cbk5lc3RlZEVudW1cMDIyXDAxMFxuXDAwNFpFUk9cMDIwXDAwMFwwMjJcMDA3XG4iICsKICAgICAgIlwwMDNGT09cMDIwXDAwMVwwMjJcMDA3XG5cMDAzQkFSXDAyMFwwMDJcMDIyXDAwN1xuXDAwM0JBWlwwMjBcMDAzXDAyMlwwMjBcblwwMDNORUdcMDIwXDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzciICsKICAgICAgIlwzNzdcMDAxQlxyXG5cMDEzb25lb2ZfZmllbGRCXDAzMlxuXDAzMF9vcHRpb25hbF9uZXN0ZWRfbWUiICsKICAgICAgInNzYWdlXCJcMjUwXDAwM1xuXDAxN1Rlc3RQYWNrZWRUeXBlc1wwMjJcMDMwXG5cMDE0cGFja2VkX2ludDMiICsKICAgICAgIjJcMDMwWiBcMDAzKFwwMDVCXDAwMlwwMjBcMDAxXDAyMlwwMzBcblwwMTRwYWNrZWRfaW50NjRcMDMwWyBcMDAzKFwwMDNCXDAwMlwwMjBcMDAxXDAyMlwwMzFcbiIgKwogICAgICAiXHJwYWNrZWRfdWludDMyXDAzMFxcIFwwMDMoXHJCXDAwMlwwMjBcMDAxXDAyMlwwMzFcblxycGFja2VkX3VpbnQ2IiArCiAgICAgICI0XDAzMF0gXDAwMyhcMDA0QlwwMDJcMDIwXDAwMVwwMjJcMDMxXG5ccnBhY2tlZF9zaW50MzJcMDMwXiBcMDAzKFwwMjFCXDAwMlwwMjBcMDAxXDAyMlwwMzEiICsKICAgICAgIlxuXHJwYWNrZWRfc2ludDY0XDAzMF8gXDAwMyhcMDIyQlwwMDJcMDIwXDAwMVwwMjJcMDMyXG5cMDE2cGFja2VkX2ZpeGUiICsKICAgICAgImQzMlwwMzBgIFwwMDMoXDAwN0JcMDAyXDAyMFwwMDFcMDIyXDAzMlxuXDAxNnBhY2tlZF9maXhlZDY0XDAzMGEgXDAwMyhcMDA2QlwwMDJcMDIwIiArCiAgICAgICJcMDAxXDAyMlwwMzNcblwwMTdwYWNrZWRfc2ZpeGVkMzJcMDMwYiBcMDAzKFwwMTdCXDAwMlwwMjBcMDAxXDAyMlwwMzNcblwwMTdwYWNrZWQiICsKICAgICAgIl9zZml4ZWQ2NFwwMzBjIFwwMDMoXDAyMEJcMDAyXDAyMFwwMDFcMDIyXDAzMFxuXDAxNHBhY2tlZF9mbG9hdFwwMzBkIFwwMDMoIiArCiAgICAgICJcMDAyQlwwMDJcMDIwXDAwMVwwMjJcMDMxXG5ccnBhY2tlZF9kb3VibGVcMDMwZSBcMDAzKFwwMDFCXDAwMlwwMjBcMDAxXDAyMlwwMjdcblwwMTNwYWNrIiArCiAgICAgICJlZF9ib29sXDAzMGYgXDAwMyhcMDEwQlwwMDJcMDIwXDAwMVwwMjI1XG5cMDEzcGFja2VkX2VudW1cMDMwZyBcMDAzKFwwMTYyXDAzNCIgKwogICAgICAiLnByb3RvM191bml0dGVzdC5Gb3JlaWduRW51bUJcMDAyXDAyMFwwMDFcIlwzMzFcMDAzXG5cMDIxVGVzIiArCiAgICAgICJ0VW5wYWNrZWRUeXBlc1wwMjJcMDMyXG5cMDE2cmVwZWF0ZWRfaW50MzJcMDMwXDAwMSBcMDAzKFwwMDVCXDAwMiIgKwogICAgICAiXDAyMFwwMDBcMDIyXDAzMlxuXDAxNnJlcGVhdGVkX2ludDY0XDAzMFwwMDIgXDAwMyhcMDAzQlwwMDJcMDIwXDAwMFwwMjJcMDMzXG5cMDE3cmVwZWF0IiArCiAgICAgICJlZF91aW50MzJcMDMwXDAwMyBcMDAzKFxyQlwwMDJcMDIwXDAwMFwwMjJcMDMzXG5cMDE3cmVwZWF0ZWRfdWludDY0XDAzMFwwMDQiICsKICAgICAgIiBcMDAzKFwwMDRCXDAwMlwwMjBcMDAwXDAyMlwwMzNcblwwMTdyZXBlYXRlZF9zaW50MzJcMDMwXDAwNSBcMDAzKFwwMjFCXDAwMlwwMjBcMDAwXDAyMlwwMzNcbiIgKwogICAgICAiXDAxN3JlcGVhdGVkX3NpbnQ2NFwwMzBcMDA2IFwwMDMoXDAyMkJcMDAyXDAyMFwwMDBcMDIyXDAzNFxuXDAyMHJlcGVhdGVkX2YiICsKICAgICAgIml4ZWQzMlwwMzBcMDA3IFwwMDMoXDAwN0JcMDAyXDAyMFwwMDBcMDIyXDAzNFxuXDAyMHJlcGVhdGVkX2ZpeGVkNjRcMDMwXDAxMCBcMDAzIiArCiAgICAgICIoXDAwNkJcMDAyXDAyMFwwMDBcMDIyXDAzNVxuXDAyMXJlcGVhdGVkX3NmaXhlZDMyXDAzMFx0IFwwMDMoXDAxN0JcMDAyXDAyMFwwMDBcMDIyXDAzNVxuIiArCiAgICAgICJcMDIxcmVwZWF0ZWRfc2ZpeGVkNjRcMDMwXG4gXDAwMyhcMDIwQlwwMDJcMDIwXDAwMFwwMjJcMDMyXG5cMDE2cmVwZWF0ZWQiICsKICAgICAgIl9mbG9hdFwwMzBcMDEzIFwwMDMoXDAwMkJcMDAyXDAyMFwwMDBcMDIyXDAzM1xuXDAxN3JlcGVhdGVkX2RvdWJsZVwwMzBcMDE0IFwwMDMoIiArCiAgICAgICJcMDAxQlwwMDJcMDIwXDAwMFwwMjJcMDMxXG5ccnJlcGVhdGVkX2Jvb2xcMDMwXHIgXDAwMyhcMDEwQlwwMDJcMDIwXDAwMFwwMjJKXG5cMDI0cmVwZSIgKwogICAgICAiYXRlZF9uZXN0ZWRfZW51bVwwMzBcMDE2IFwwMDMoXDAxNjIoLnByb3RvM191bml0dGVzdCIgKwogICAgICAiLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtQlwwMDJcMDIwXDAwMFwieFxuXDAyMk5lc3RlZFRlIiArCiAgICAgICJzdEFsbFR5cGVzXDAyMjJcblwwMDVjaGlsZFwwMzBcMDAxIFwwMDEoXDAxMzIjLnByb3RvM191bml0dCIgKwogICAgICAiZXN0Lk5lc3RlZFRlc3RBbGxUeXBlc1wwMjIuXG5cMDA3cGF5bG9hZFwwMzBcMDAyIFwwMDEoXDAxMzIiICsKICAgICAgIlwwMzUucHJvdG8zX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wiXDAzM1xuXDAxNkZvcmVpZyIgKwogICAgICAibk1lc3NhZ2VcMDIyXHRcblwwMDFjXDAzMFwwMDEgXDAwMShcMDA1XCJcMDIyXG5cMDIwVGVzdEVtcHR5TWVzc2FnZVwiIiArCiAgICAgICIpXG5cMDI0VGVzdE1lc3NhZ2VXaXRoRHVtbXlcMDIyXDAyMVxuXDAwNWR1bW15XDAzMFwzNzdcMzc3XDM3N1wzNzdcMDAxIFwwMDEiICsKICAgICAgIihcMDEwXCJcMjA1XDAwMVxuXG5UZXN0T25lb2YyXDAyMjpcblwwMTBmb29fZW51bVwwMzBcMDA2IFwwMDEoXDAxNjImLnByIiArCiAgICAgICJvdG8zX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bUhcMDAwXCI0XG4iICsKICAgICAgIlxuTmVzdGVkRW51bVwwMjJcMDEzXG5cMDA3VU5LTk9XTlwwMjBcMDAwXDAyMlwwMDdcblwwMDNGT09cMDIwXDAwMVwwMjJcMDA3XG5cMDAzQkFSIiArCiAgICAgICJcMDIwXDAwMlwwMjJcMDA3XG5cMDAzQkFaXDAyMFwwMDNCXDAwNVxuXDAwM2ZvbypSXG5cMDEzRm9yZWlnbkVudW1cMDIyXDAyMFxuXDAxNEZPUiIgKwogICAgICAiRUlHTl9aRVJPXDAyMFwwMDBcMDIyXDAxN1xuXDAxM0ZPUkVJR05fRk9PXDAyMFwwMDRcMDIyXDAxN1xuXDAxM0ZPUkVJR05fIiArCiAgICAgICJCQVJcMDIwXDAwNVwwMjJcMDE3XG5cMDEzRk9SRUlHTl9CQVpcMDIwXDAwNkJcMDAySFwwMDFiXDAwNnByb3RvMyIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LmdldERlc2NyaXB0b3IoKSwKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiT3B0aW9uYWxJbnQzMiIsICJPcHRpb25hbEludDY0IiwgIk9wdGlvbmFsVWludDMyIiwgIk9wdGlvbmFsVWludDY0IiwgIk9wdGlvbmFsU2ludDMyIiwgIk9wdGlvbmFsU2ludDY0IiwgIk9wdGlvbmFsRml4ZWQzMiIsICJPcHRpb25hbEZpeGVkNjQiLCAiT3B0aW9uYWxTZml4ZWQzMiIsICJPcHRpb25hbFNmaXhlZDY0IiwgIk9wdGlvbmFsRmxvYXQiLCAiT3B0aW9uYWxEb3VibGUiLCAiT3B0aW9uYWxCb29sIiwgIk9wdGlvbmFsU3RyaW5nIiwgIk9wdGlvbmFsQnl0ZXMiLCAiT3B0aW9uYWxOZXN0ZWRNZXNzYWdlIiwgIk9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UiLCAiT3B0aW9uYWxJbXBvcnRNZXNzYWdlIiwgIk9wdGlvbmFsTmVzdGVkRW51bSIsICJPcHRpb25hbEZvcmVpZ25FbnVtIiwgIk9wdGlvbmFsU3RyaW5nUGllY2UiLCAiT3B0aW9uYWxDb3JkIiwgIk9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSIsICJPcHRpb25hbExhenlNZXNzYWdlIiwgIk9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlIiwgIk9wdGlvbmFsTGF6eUltcG9ydE1lc3NhZ2UiLCAiUmVwZWF0ZWRJbnQzMiIsICJSZXBlYXRlZEludDY0IiwgIlJlcGVhdGVkVWludDMyIiwgIlJlcGVhdGVkVWludDY0IiwgIlJlcGVhdGVkU2ludDMyIiwgIlJlcGVhdGVkU2ludDY0IiwgIlJlcGVhdGVkRml4ZWQzMiIsICJSZXBlYXRlZEZpeGVkNjQiLCAiUmVwZWF0ZWRTZml4ZWQzMiIsICJSZXBlYXRlZFNmaXhlZDY0IiwgIlJlcGVhdGVkRmxvYXQiLCAiUmVwZWF0ZWREb3VibGUiLCAiUmVwZWF0ZWRCb29sIiwgIlJlcGVhdGVkU3RyaW5nIiwgIlJlcGVhdGVkQnl0ZXMiLCAiUmVwZWF0ZWROZXN0ZWRNZXNzYWdlIiwgIlJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UiLCAiUmVwZWF0ZWRJbXBvcnRNZXNzYWdlIiwgIlJlcGVhdGVkTmVzdGVkRW51bSIsICJSZXBlYXRlZEZvcmVpZ25FbnVtIiwgIlJlcGVhdGVkU3RyaW5nUGllY2UiLCAiUmVwZWF0ZWRDb3JkIiwgIlJlcGVhdGVkTGF6eU1lc3NhZ2UiLCAiT25lb2ZVaW50MzIiLCAiT25lb2ZOZXN0ZWRNZXNzYWdlIiwgIk9uZW9mU3RyaW5nIiwgIk9uZW9mQnl0ZXMiLCAiT25lb2ZGaWVsZCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJCYiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJQYWNrZWRJbnQzMiIsICJQYWNrZWRJbnQ2NCIsICJQYWNrZWRVaW50MzIiLCAiUGFja2VkVWludDY0IiwgIlBhY2tlZFNpbnQzMiIsICJQYWNrZWRTaW50NjQiLCAiUGFja2VkRml4ZWQzMiIsICJQYWNrZWRGaXhlZDY0IiwgIlBhY2tlZFNmaXhlZDMyIiwgIlBhY2tlZFNmaXhlZDY0IiwgIlBhY2tlZEZsb2F0IiwgIlBhY2tlZERvdWJsZSIsICJQYWNrZWRCb29sIiwgIlBhY2tlZEVudW0iLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdFVucGFja2VkVHlwZXNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUmVwZWF0ZWRJbnQzMiIsICJSZXBlYXRlZEludDY0IiwgIlJlcGVhdGVkVWludDMyIiwgIlJlcGVhdGVkVWludDY0IiwgIlJlcGVhdGVkU2ludDMyIiwgIlJlcGVhdGVkU2ludDY0IiwgIlJlcGVhdGVkRml4ZWQzMiIsICJSZXBlYXRlZEZpeGVkNjQiLCAiUmVwZWF0ZWRTZml4ZWQzMiIsICJSZXBlYXRlZFNmaXhlZDY0IiwgIlJlcGVhdGVkRmxvYXQiLCAiUmVwZWF0ZWREb3VibGUiLCAiUmVwZWF0ZWRCb29sIiwgIlJlcGVhdGVkTmVzdGVkRW51bSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9OZXN0ZWRUZXN0QWxsVHlwZXNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJDaGlsZCIsICJQYXlsb2FkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkMiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoRHVtbXlfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG8zX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aER1bW15X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvM191bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhEdW1teV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRHVtbXkiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdE9uZW9mMl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdE9uZW9mMl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90bzNfdW5pdHRlc3RfVGVzdE9uZW9mMl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRm9vRW51bSIsICJGb28iLCB9KTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5nZXREZXNjcmlwdG9yKCk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQD9wSnjcuYLAHLmCwAoAAAAcHJvdG9idWZfdW5pdHRlc3QvTWFwUHJvdG8yVW5pdHRlc3QuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL21hcF9wcm90bzJfdW5pdHRlc3QucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIE1hcFByb3RvMlVuaXR0ZXN0IHsKICBwcml2YXRlIE1hcFByb3RvMlVuaXR0ZXN0KCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtfQogICAqLwogIHB1YmxpYyBlbnVtIFByb3RvMk1hcEVudW0KICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgLyoqCiAgICAgKiA8Y29kZT5QUk9UTzJfTUFQX0VOVU1fRk9PID0gMDs8L2NvZGU+CiAgICAgKi8KICAgIFBST1RPMl9NQVBfRU5VTV9GT08oMCksCiAgICAvKioKICAgICAqIDxjb2RlPlBST1RPMl9NQVBfRU5VTV9CQVIgPSAxOzwvY29kZT4KICAgICAqLwogICAgUFJPVE8yX01BUF9FTlVNX0JBUigxKSwKICAgIC8qKgogICAgICogPGNvZGU+UFJPVE8yX01BUF9FTlVNX0JBWiA9IDI7PC9jb2RlPgogICAgICovCiAgICBQUk9UTzJfTUFQX0VOVU1fQkFaKDIpLAogICAgOwoKICAgIC8qKgogICAgICogPGNvZGU+UFJPVE8yX01BUF9FTlVNX0ZPTyA9IDA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUk9UTzJfTUFQX0VOVU1fRk9PX1ZBTFVFID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+UFJPVE8yX01BUF9FTlVNX0JBUiA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUk9UTzJfTUFQX0VOVU1fQkFSX1ZBTFVFID0gMTsKICAgIC8qKgogICAgICogPGNvZGU+UFJPVE8yX01BUF9FTlVNX0JBWiA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUk9UTzJfTUFQX0VOVU1fQkFaX1ZBTFVFID0gMjsKCgogICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIHN0YXRpYyBQcm90bzJNYXBFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgUHJvdG8yTWFwRW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICBjYXNlIDA6IHJldHVybiBQUk9UTzJfTUFQX0VOVU1fRk9POwogICAgICAgIGNhc2UgMTogcmV0dXJuIFBST1RPMl9NQVBfRU5VTV9CQVI7CiAgICAgICAgY2FzZSAyOiByZXR1cm4gUFJPVE8yX01BUF9FTlVNX0JBWjsKICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxQcm90bzJNYXBFbnVtPgogICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICBQcm90bzJNYXBFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFByb3RvMk1hcEVudW0+KCkgewogICAgICAgICAgICBwdWJsaWMgUHJvdG8yTWFwRW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIFByb3RvMk1hcEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgIH0KICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQcm90bzJNYXBFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgcHVibGljIHN0YXRpYyBQcm90bzJNYXBFbnVtIHZhbHVlT2YoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgIH0KICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgfQoKICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgIHByaXZhdGUgUHJvdG8yTWFwRW51bShpbnQgdmFsdWUpIHsKICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0pCiAgfQoKICAvKioKICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhfQogICAqLwogIHB1YmxpYyBlbnVtIFByb3RvMk1hcEVudW1QbHVzRXh0cmEKICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgLyoqCiAgICAgKiA8Y29kZT5FX1BST1RPMl9NQVBfRU5VTV9GT08gPSAwOzwvY29kZT4KICAgICAqLwogICAgRV9QUk9UTzJfTUFQX0VOVU1fRk9PKDApLAogICAgLyoqCiAgICAgKiA8Y29kZT5FX1BST1RPMl9NQVBfRU5VTV9CQVIgPSAxOzwvY29kZT4KICAgICAqLwogICAgRV9QUk9UTzJfTUFQX0VOVU1fQkFSKDEpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FX1BST1RPMl9NQVBfRU5VTV9CQVogPSAyOzwvY29kZT4KICAgICAqLwogICAgRV9QUk9UTzJfTUFQX0VOVU1fQkFaKDIpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FX1BST1RPMl9NQVBfRU5VTV9FWFRSQSA9IDM7PC9jb2RlPgogICAgICovCiAgICBFX1BST1RPMl9NQVBfRU5VTV9FWFRSQSgzKSwKICAgIDsKCiAgICAvKioKICAgICAqIDxjb2RlPkVfUFJPVE8yX01BUF9FTlVNX0ZPTyA9IDA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFX1BST1RPMl9NQVBfRU5VTV9GT09fVkFMVUUgPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5FX1BST1RPMl9NQVBfRU5VTV9CQVIgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRV9QUk9UTzJfTUFQX0VOVU1fQkFSX1ZBTFVFID0gMTsKICAgIC8qKgogICAgICogPGNvZGU+RV9QUk9UTzJfTUFQX0VOVU1fQkFaID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVfUFJPVE8yX01BUF9FTlVNX0JBWl9WQUxVRSA9IDI7CiAgICAvKioKICAgICAqIDxjb2RlPkVfUFJPVE8yX01BUF9FTlVNX0VYVFJBID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVfUFJPVE8yX01BUF9FTlVNX0VYVFJBX1ZBTFVFID0gMzsKCgogICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIHN0YXRpYyBQcm90bzJNYXBFbnVtUGx1c0V4dHJhIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICBjYXNlIDA6IHJldHVybiBFX1BST1RPMl9NQVBfRU5VTV9GT087CiAgICAgICAgY2FzZSAxOiByZXR1cm4gRV9QUk9UTzJfTUFQX0VOVU1fQkFSOwogICAgICAgIGNhc2UgMjogcmV0dXJuIEVfUFJPVE8yX01BUF9FTlVNX0JBWjsKICAgICAgICBjYXNlIDM6IHJldHVybiBFX1BST1RPMl9NQVBfRU5VTV9FWFRSQTsKICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxQcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICBQcm90bzJNYXBFbnVtUGx1c0V4dHJhPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFByb3RvMk1hcEVudW1QbHVzRXh0cmE+KCkgewogICAgICAgICAgICBwdWJsaWMgUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIFByb3RvMk1hcEVudW1QbHVzRXh0cmEuZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgIH0KICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgxKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBQcm90bzJNYXBFbnVtUGx1c0V4dHJhW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgcHVibGljIHN0YXRpYyBQcm90bzJNYXBFbnVtUGx1c0V4dHJhIHZhbHVlT2YoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgIH0KICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgfQoKICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgIHByaXZhdGUgUHJvdG8yTWFwRW51bVBsdXNFeHRyYShpbnQgdmFsdWUpIHsKICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEpCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RFbnVtTWFwT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbnVtTWFwKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsga25vd25fbWFwX2ZpZWxkID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEtub3duTWFwRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyBrbm93bl9tYXBfZmllbGQgPSAxMDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zS25vd25NYXBGaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0S25vd25NYXBGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRLbm93bk1hcEZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IGtub3duX21hcF9maWVsZCA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRLbm93bk1hcEZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IGtub3duX21hcF9maWVsZCA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0S25vd25NYXBGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyBrbm93bl9tYXBfZmllbGQgPSAxMDE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldEtub3duTWFwRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGQgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGQgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZCA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkSW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogT3RoZXIgbWFwcyB3aXRoIGFsbCBrZXkgdHlwZXMgdG8gdGVzdCB0aGUgdW5rbm93biBlbnRyeSBzZXJpYWxpemF0aW9uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQ2NCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRJbnQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZEludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZEludDY0KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBPdGhlciBtYXBzIHdpdGggYWxsIGtleSB0eXBlcyB0byB0ZXN0IHRoZSB1bmtub3duIGVudHJ5IHNlcmlhbGl6YXRpb24KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDY0ID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZEludDY0TWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBPdGhlciBtYXBzIHdpdGggYWxsIGtleSB0eXBlcyB0byB0ZXN0IHRoZSB1bmtub3duIGVudHJ5IHNlcmlhbGl6YXRpb24KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDY0ID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRJbnQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZEludDY0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDY0ID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZFVpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50NjQgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkVWludDY0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkVWludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDY0ID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZFVpbnQ2NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDY0ID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRVaW50NjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50NjQgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZFVpbnQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkSW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQzMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRJbnQzMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkSW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkSW50MzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZEludDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDMyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRJbnQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDMyID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZFVpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50MzIgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkVWludDMyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRVaW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50MzIgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50MzIgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZFVpbnQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDMyID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRVaW50MzJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDMyID0gMjA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZEZpeGVkMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkMzIgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkRml4ZWQzMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMiA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMiA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkMzIgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZEZpeGVkMzJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDY0ID0gMjA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZEZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkNjQgPSAyMDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZEZpeGVkNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkNjQgPSAyMDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkNjQgPSAyMDU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZEZpeGVkNjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQ2NCA9IDIwNTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9ib29sID0gMjA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZEJvb2xDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2Jvb2wgPSAyMDY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkQm9vbCgKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZEJvb2xNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2Jvb2wgPSAyMDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkQm9vbE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2Jvb2wgPSAyMDY7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZEJvb2xPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfYm9vbCA9IDIwNjs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkQm9vbE9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3N0cmluZyA9IDIwNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRVbmtub3duTWFwRmllbGRTdHJpbmdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc3RyaW5nID0gMjA3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFN0cmluZygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc3RyaW5nID0gMjA3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zdHJpbmcgPSAyMDc7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZFN0cmluZ09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3N0cmluZyA9IDIwNzs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDMyID0gMjA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZFNpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50MzIgPSAyMDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkU2ludDMyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRTaW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50MzIgPSAyMDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50MzIgPSAyMDg7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZFNpbnQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDMyID0gMjA4OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRTaW50MzJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQ2NCA9IDIwOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRVbmtub3duTWFwRmllbGRTaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDY0ID0gMjA5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFNpbnQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFNpbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRVbmtub3duTWFwRmllbGRTaW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQ2NCA9IDIwOTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRVbmtub3duTWFwRmllbGRTaW50NjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQ2NCA9IDIwOTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkU2ludDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDY0ID0gMjA5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRTaW50NjRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyID0gMjEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkMzIgPSAyMTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFNmaXhlZDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyID0gMjEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyID0gMjEwOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQzMiA9IDIxMDs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkNjQgPSAyMTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQ2NCA9IDIxMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFNmaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDY0ID0gMjExOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDY0ID0gMjExOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkNjQgPSAyMTE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbnVtTWFwfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEVudW1NYXAgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVudW1NYXApCiAgICAgIFRlc3RFbnVtTWFwT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0RW51bU1hcC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0RW51bU1hcChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RFbnVtTWFwKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RFbnVtTWFwKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMTAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0S25vd25NYXBGaWVsZCgpOwogICAgICAgIGNhc2UgMTAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCk7CiAgICAgICAgY2FzZSAyMDA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpOwogICAgICAgIGNhc2UgMjAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCk7CiAgICAgICAgY2FzZSAyMDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpOwogICAgICAgIGNhc2UgMjAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCk7CiAgICAgICAgY2FzZSAyMDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCk7CiAgICAgICAgY2FzZSAyMDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCk7CiAgICAgICAgY2FzZSAyMDY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCk7CiAgICAgICAgY2FzZSAyMDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKTsKICAgICAgICBjYXNlIDIwODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpOwogICAgICAgIGNhc2UgMjA5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCk7CiAgICAgICAgY2FzZSAyMTA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpOwogICAgICAgIGNhc2UgMjExOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBLTk9XTl9NQVBfRklFTERfRklFTERfTlVNQkVSID0gMTAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgS25vd25NYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Lbm93bk1hcEZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5QUk9UTzJfTUFQX0VOVU1fRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4ga25vd25NYXBGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkgewogICAgICBpZiAoa25vd25NYXBGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEtub3duTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4ga25vd25NYXBGaWVsZF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4ga25vd25NYXBGaWVsZFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uUFJPVE8yX01BUF9FTlVNX0ZPTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkS25vd25NYXBGaWVsZE1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIGtub3duTWFwRmllbGRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEtub3duTWFwRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0S25vd25NYXBGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsga25vd25fbWFwX2ZpZWxkID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNLbm93bk1hcEZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEtub3duTWFwRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRLbm93bk1hcEZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRLbm93bk1hcEZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0S25vd25NYXBGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyBrbm93bl9tYXBfZmllbGQgPSAxMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldEtub3duTWFwRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRLbm93bk1hcEZpZWxkTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsga25vd25fbWFwX2ZpZWxkID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0S25vd25NYXBGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0S25vd25NYXBGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8ga25vd25NYXBGaWVsZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsga25vd25fbWFwX2ZpZWxkID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0S25vd25NYXBGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEtub3duTWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGtub3duTWFwRmllbGRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX01BUF9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBVbmtub3duTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5QUk9UTzJfTUFQX0VOVU1fRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpIHsKICAgICAgaWYgKHVua25vd25NYXBGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFVua25vd25NYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+IHVua25vd25NYXBGaWVsZFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uUFJPVE8yX01BUF9FTlVNX0ZPTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdW5rbm93bk1hcEZpZWxkVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZCA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkKCkgewogICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRVbmtub3duTWFwRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGQgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOS05PV05fTUFQX0ZJRUxEX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDIwMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFVua25vd25NYXBGaWVsZEludDY0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZEludDY0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uUFJPVE8yX01BUF9FTlVNX0ZPTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHVua25vd25NYXBGaWVsZEludDY0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkgewogICAgICBpZiAodW5rbm93bk1hcEZpZWxkSW50NjRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBVbmtub3duTWFwRmllbGRJbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRJbnQ2NF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4gdW5rbm93bk1hcEZpZWxkSW50NjRWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLlBST1RPMl9NQVBfRU5VTV9GT08pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEludDY0TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdW5rbm93bk1hcEZpZWxkSW50NjRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZEludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogT3RoZXIgbWFwcyB3aXRoIGFsbCBrZXkgdHlwZXMgdG8gdGVzdCB0aGUgdW5rbm93biBlbnRyeSBzZXJpYWxpemF0aW9uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQ2NCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkSW50NjQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkSW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZEludDY0KCkgewogICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkSW50NjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZEludDY0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkSW50NjRNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRJbnQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRJbnQ2NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRJbnQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkSW50NjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX01BUF9GSUVMRF9VSU5UNjRfRklFTERfTlVNQkVSID0gMjAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVW5rbm93bk1hcEZpZWxkVWludDY0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZFVpbnQ2NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5QUk9UTzJfTUFQX0VOVU1fRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkVWludDY0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpIHsKICAgICAgaWYgKHVua25vd25NYXBGaWVsZFVpbnQ2NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFVua25vd25NYXBGaWVsZFVpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRVaW50NjRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+IHVua25vd25NYXBGaWVsZFVpbnQ2NFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uUFJPVE8yX01BUF9FTlVNX0ZPTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkVWludDY0TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdW5rbm93bk1hcEZpZWxkVWludDY0VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRVaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDY0ID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRVaW50NjQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFVpbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCkgewogICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkVWludDY0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50NjQgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZFVpbnQ2NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFVpbnQ2NE1hcCgKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQ2NCA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZFVpbnQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkVWludDY0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDY0ID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkVWludDY0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkVWludDY0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9NQVBfRklFTERfSU5UMzJfRklFTERfTlVNQkVSID0gMjAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVW5rbm93bk1hcEZpZWxkSW50MzJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkSW50MzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLlBST1RPMl9NQVBfRU5VTV9GT08uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRJbnQzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpIHsKICAgICAgaWYgKHVua25vd25NYXBGaWVsZEludDMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkSW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkSW50MzJfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+IHVua25vd25NYXBGaWVsZEludDMyVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5QUk9UTzJfTUFQX0VOVU1fRk9PKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRJbnQzMk1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIHVua25vd25NYXBGaWVsZEludDMyVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRJbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZEludDMyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkSW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZEludDMyKCkgewogICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkSW50MzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZEludDMyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkSW50MzJNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDMyKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRJbnQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZEludDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQzMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZEludDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEludDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9NQVBfRklFTERfVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDIwMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFVua25vd25NYXBGaWVsZFVpbnQzMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRVaW50MzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5QUk9UTzJfTUFQX0VOVU1fRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkVWludDMyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQzMigpIHsKICAgICAgaWYgKHVua25vd25NYXBGaWVsZFVpbnQzMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFVua25vd25NYXBGaWVsZFVpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRVaW50MzJfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+IHVua25vd25NYXBGaWVsZFVpbnQzMlZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uUFJPVE8yX01BUF9FTlVNX0ZPTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkVWludDMyTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdW5rbm93bk1hcEZpZWxkVWludDMyVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRVaW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDMyID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRVaW50MzIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRVbmtub3duTWFwRmllbGRVaW50MzIoKSB7CiAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRVaW50MzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQzMiA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkVWludDMyTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDMyID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZFVpbnQzMlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQzMiA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZFVpbnQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkVWludDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9NQVBfRklFTERfRklYRUQzMl9GSUVMRF9OVU1CRVIgPSAyMDQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBVbmtub3duTWFwRmllbGRGaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZEZpeGVkMzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uUFJPVE8yX01BUF9FTlVNX0ZPTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHVua25vd25NYXBGaWVsZEZpeGVkMzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpIHsKICAgICAgaWYgKHVua25vd25NYXBGaWVsZEZpeGVkMzJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBVbmtub3duTWFwRmllbGRGaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEZpeGVkMzJfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+IHVua25vd25NYXBGaWVsZEZpeGVkMzJWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLlBST1RPMl9NQVBfRU5VTV9GT08pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEZpeGVkMzJNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCB1bmtub3duTWFwRmllbGRGaXhlZDMyVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMiA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkRml4ZWQzMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpIHsKICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZEZpeGVkMzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDMyID0gMjA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkRml4ZWQzMk1hcCgKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMiA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZEZpeGVkMzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZEZpeGVkMzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMiA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZEZpeGVkMzJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRGaXhlZDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9NQVBfRklFTERfRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSAyMDU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBVbmtub3duTWFwRmllbGRGaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZEZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLlBST1RPMl9NQVBfRU5VTV9GT08uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRGaXhlZDY0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKSB7CiAgICAgIGlmICh1bmtub3duTWFwRmllbGRGaXhlZDY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkRml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRGaXhlZDY0XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPiB1bmtub3duTWFwRmllbGRGaXhlZDY0VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5QUk9UTzJfTUFQX0VOVU1fRk9PKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRGaXhlZDY0TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdW5rbm93bk1hcEZpZWxkRml4ZWQ2NFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkNjQgPSAyMDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZEZpeGVkNjQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRGaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCkgewogICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkNjQgPSAyMDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZEZpeGVkNjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRGaXhlZDY0TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDY0ID0gMjA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZEZpeGVkNjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQ2NCA9IDIwNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZEZpeGVkNjRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkRml4ZWQ2NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOS05PV05fTUFQX0ZJRUxEX0JPT0xfRklFTERfTlVNQkVSID0gMjA2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVW5rbm93bk1hcEZpZWxkQm9vbERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRCb29sRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5QUk9UTzJfTUFQX0VOVU1fRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkQm9vbF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkgewogICAgICBpZiAodW5rbm93bk1hcEZpZWxkQm9vbF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFVua25vd25NYXBGaWVsZEJvb2xEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkQm9vbF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4gdW5rbm93bk1hcEZpZWxkQm9vbFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uUFJPVE8yX01BUF9FTlVNX0ZPTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkQm9vbE1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIHVua25vd25NYXBGaWVsZEJvb2xWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZEJvb2xDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9ib29sID0gMjA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRCb29sKAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkQm9vbE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpIHsKICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZEJvb2xNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9ib29sID0gMjA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRVbmtub3duTWFwRmllbGRCb29sTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkQm9vbE1hcCgKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfYm9vbCA9IDIwNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZEJvb2xPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRCb29sVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2Jvb2wgPSAyMDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRCb29sT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEJvb2woKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEJvb2xWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX01BUF9GSUVMRF9TVFJJTkdfRklFTERfTlVNQkVSID0gMjA3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVW5rbm93bk1hcEZpZWxkU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRTdHJpbmdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uUFJPVE8yX01BUF9FTlVNX0ZPTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkU3RyaW5nXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkgewogICAgICBpZiAodW5rbm93bk1hcEZpZWxkU3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFN0cmluZ187CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4gdW5rbm93bk1hcEZpZWxkU3RyaW5nVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5QUk9UTzJfTUFQX0VOVU1fRk9PKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFN0cmluZ01hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCB1bmtub3duTWFwRmllbGRTdHJpbmdWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZFN0cmluZ0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zdHJpbmcgPSAyMDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFN0cmluZygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZFN0cmluZygpIHsKICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZFN0cmluZ01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc3RyaW5nID0gMjA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZFN0cmluZ01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFN0cmluZ01hcCgKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3N0cmluZyA9IDIwNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZFN0cmluZ09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRTdHJpbmdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zdHJpbmcgPSAyMDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRTdHJpbmdPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFN0cmluZ1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOS05PV05fTUFQX0ZJRUxEX1NJTlQzMl9GSUVMRF9OVU1CRVIgPSAyMDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBVbmtub3duTWFwRmllbGRTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkU2ludDMyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uUFJPVE8yX01BUF9FTlVNX0ZPTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHVua25vd25NYXBGaWVsZFNpbnQzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKSB7CiAgICAgIGlmICh1bmtub3duTWFwRmllbGRTaW50MzJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBVbmtub3duTWFwRmllbGRTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ludDMyXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPiB1bmtub3duTWFwRmllbGRTaW50MzJWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLlBST1RPMl9NQVBfRU5VTV9GT08pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFNpbnQzMk1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIHVua25vd25NYXBGaWVsZFNpbnQzMlZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQzMiA9IDIwODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkU2ludDMyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFNpbnQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCkgewogICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50MzIgPSAyMDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGdldFVua25vd25NYXBGaWVsZFNpbnQzMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFNpbnQzMk1hcCgKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQzMiA9IDIwODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZFNpbnQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRTaW50MzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50MzIgPSAyMDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRTaW50MzJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNpbnQzMlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOS05PV05fTUFQX0ZJRUxEX1NJTlQ2NF9GSUVMRF9OVU1CRVIgPSAyMDk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBVbmtub3duTWFwRmllbGRTaW50NjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkU2ludDY0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLlBST1RPMl9NQVBfRU5VTV9GT08uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRTaW50NjRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkgewogICAgICBpZiAodW5rbm93bk1hcEZpZWxkU2ludDY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkU2ludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNpbnQ2NF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4gdW5rbm93bk1hcEZpZWxkU2ludDY0VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5QUk9UTzJfTUFQX0VOVU1fRk9PKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTaW50NjRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCB1bmtub3duTWFwRmllbGRTaW50NjRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZFNpbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50NjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50NjQgPSAyMDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFNpbnQ2NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkU2ludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRVbmtub3duTWFwRmllbGRTaW50NjQoKSB7CiAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRTaW50NjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQ2NCA9IDIwOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDY0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ludDY0TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50NjQoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDY0ID0gMjA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkU2ludDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRTaW50NjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50NjQgPSAyMDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRTaW50NjRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRTaW50NjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX01BUF9GSUVMRF9TRklYRUQzMl9GSUVMRF9OVU1CRVIgPSAyMTA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBVbmtub3duTWFwRmllbGRTZml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRTZml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uUFJPVE8yX01BUF9FTlVNX0ZPTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHVua25vd25NYXBGaWVsZFNmaXhlZDMyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkgewogICAgICBpZiAodW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBVbmtub3duTWFwRmllbGRTZml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRTZml4ZWQzMl87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4gdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLlBST1RPMl9NQVBfRU5VTV9GT08pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFNmaXhlZDMyTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQzMiA9IDIxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKSB7CiAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQzMiA9IDIxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTZml4ZWQzMk1hcCgKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQzMiA9IDIxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyID0gMjEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX01BUF9GSUVMRF9TRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSAyMTE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBVbmtub3duTWFwRmllbGRTZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRTZml4ZWQ2NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLlBST1RPMl9NQVBfRU5VTV9GT08uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRTZml4ZWQ2NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpIHsKICAgICAgaWYgKHVua25vd25NYXBGaWVsZFNmaXhlZDY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+IHVua25vd25NYXBGaWVsZFNmaXhlZDY0VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5QUk9UTzJfTUFQX0VOVU1fRk9PKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTZml4ZWQ2NE1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0sIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIHVua25vd25NYXBGaWVsZFNmaXhlZDY0VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkNjQgPSAyMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFNmaXhlZDY0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFNmaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDY0ID0gMjExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFNmaXhlZDY0TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDY0ID0gMjExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDY0ID0gMjExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNmaXhlZDY0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEtub3duTWFwRmllbGQoKSwKICAgICAgICAgIEtub3duTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKSwKICAgICAgICAgIFVua25vd25NYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCksCiAgICAgICAgICBVbmtub3duTWFwRmllbGRJbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpLAogICAgICAgICAgVW5rbm93bk1hcEZpZWxkVWludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIwMSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKSwKICAgICAgICAgIFVua25vd25NYXBGaWVsZEludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIwMik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCksCiAgICAgICAgICBVbmtub3duTWFwRmllbGRVaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjAzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCksCiAgICAgICAgICBVbmtub3duTWFwRmllbGRGaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIwNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLAogICAgICAgICAgVW5rbm93bk1hcEZpZWxkRml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEJvb2woKSwKICAgICAgICAgIFVua25vd25NYXBGaWVsZEJvb2xEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjA2KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpLAogICAgICAgICAgVW5rbm93bk1hcEZpZWxkU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIwNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCksCiAgICAgICAgICBVbmtub3duTWFwRmllbGRTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjA4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50NjQoKSwKICAgICAgICAgIFVua25vd25NYXBGaWVsZFNpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCksCiAgICAgICAgICBVbmtub3duTWFwRmllbGRTZml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMTApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCksCiAgICAgICAgICBVbmtub3duTWFwRmllbGRTZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMTEpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0S25vd25NYXBGaWVsZCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBrbm93bk1hcEZpZWxkX18gPSBLbm93bk1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDEsIGtub3duTWFwRmllbGRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHVua25vd25NYXBGaWVsZF9fID0gVW5rbm93bk1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDIsIHVua25vd25NYXBGaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICB1bmtub3duTWFwRmllbGRJbnQ2NF9fID0gVW5rbm93bk1hcEZpZWxkSW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwMCwgdW5rbm93bk1hcEZpZWxkSW50NjRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHVua25vd25NYXBGaWVsZFVpbnQ2NF9fID0gVW5rbm93bk1hcEZpZWxkVWludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMDEsIHVua25vd25NYXBGaWVsZFVpbnQ2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICB1bmtub3duTWFwRmllbGRJbnQzMl9fID0gVW5rbm93bk1hcEZpZWxkSW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwMiwgdW5rbm93bk1hcEZpZWxkSW50MzJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHVua25vd25NYXBGaWVsZFVpbnQzMl9fID0gVW5rbm93bk1hcEZpZWxkVWludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMDMsIHVua25vd25NYXBGaWVsZFVpbnQzMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHVua25vd25NYXBGaWVsZEZpeGVkMzJfXyA9IFVua25vd25NYXBGaWVsZEZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwNCwgdW5rbm93bk1hcEZpZWxkRml4ZWQzMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHVua25vd25NYXBGaWVsZEZpeGVkNjRfXyA9IFVua25vd25NYXBGaWVsZEZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwNSwgdW5rbm93bk1hcEZpZWxkRml4ZWQ2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHVua25vd25NYXBGaWVsZEJvb2xfXyA9IFVua25vd25NYXBGaWVsZEJvb2xEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwNiwgdW5rbm93bk1hcEZpZWxkQm9vbF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHVua25vd25NYXBGaWVsZFN0cmluZ19fID0gVW5rbm93bk1hcEZpZWxkU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMDcsIHVua25vd25NYXBGaWVsZFN0cmluZ19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgdW5rbm93bk1hcEZpZWxkU2ludDMyX18gPSBVbmtub3duTWFwRmllbGRTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwOCwgdW5rbm93bk1hcEZpZWxkU2ludDMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQ2NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICB1bmtub3duTWFwRmllbGRTaW50NjRfXyA9IFVua25vd25NYXBGaWVsZFNpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjA5LCB1bmtub3duTWFwRmllbGRTaW50NjRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfXyA9IFVua25vd25NYXBGaWVsZFNmaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMTAsIHVua25vd25NYXBGaWVsZFNmaXhlZDMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHVua25vd25NYXBGaWVsZFNmaXhlZDY0X18gPSBVbmtub3duTWFwRmllbGRTZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjExLCB1bmtub3duTWFwRmllbGRTZml4ZWQ2NF9fKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXApIG9iajsKCiAgICAgIGlmICghaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50NjQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50NjQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDMyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50NjQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQ2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoIWludGVybmFsR2V0S25vd25NYXBGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEtOT1dOX01BUF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5LTk9XTl9NQVBfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50NjQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVTktOT1dOX01BUF9GSUVMRF9JTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVOS05PV05fTUFQX0ZJRUxEX1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50NjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVOS05PV05fTUFQX0ZJRUxEX0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDMyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5LTk9XTl9NQVBfRklFTERfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQzMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVTktOT1dOX01BUF9GSUVMRF9GSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5LTk9XTl9NQVBfRklFTERfRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVOS05PV05fTUFQX0ZJRUxEX0JPT0xfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVOS05PV05fTUFQX0ZJRUxEX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVTktOT1dOX01BUF9GSUVMRF9TSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5LTk9XTl9NQVBfRklFTERfU0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQ2NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5LTk9XTl9NQVBfRklFTERfU0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVOS05PV05fTUFQX0ZJRUxEX1NGSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcCBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RW51bU1hcH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbnVtTWFwKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDEwMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0S25vd25NYXBGaWVsZCgpOwogICAgICAgICAgY2FzZSAxMDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpOwogICAgICAgICAgY2FzZSAyMDA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCk7CiAgICAgICAgICBjYXNlIDIwMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCk7CiAgICAgICAgICBjYXNlIDIwMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKTsKICAgICAgICAgIGNhc2UgMjAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKTsKICAgICAgICAgIGNhc2UgMjA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCk7CiAgICAgICAgICBjYXNlIDIwNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpOwogICAgICAgICAgY2FzZSAyMDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEJvb2woKTsKICAgICAgICAgIGNhc2UgMjA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKTsKICAgICAgICAgIGNhc2UgMjA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKTsKICAgICAgICAgIGNhc2UgMjA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50NjQoKTsKICAgICAgICAgIGNhc2UgMjEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpOwogICAgICAgICAgY2FzZSAyMTE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxMDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVLbm93bk1hcEZpZWxkKCk7CiAgICAgICAgICBjYXNlIDEwMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZCgpOwogICAgICAgICAgY2FzZSAyMDA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQ2NCgpOwogICAgICAgICAgY2FzZSAyMDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRVaW50NjQoKTsKICAgICAgICAgIGNhc2UgMjAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50MzIoKTsKICAgICAgICAgIGNhc2UgMjAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDMyKCk7CiAgICAgICAgICBjYXNlIDIwNDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEZpeGVkMzIoKTsKICAgICAgICAgIGNhc2UgMjA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpOwogICAgICAgICAgY2FzZSAyMDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRCb29sKCk7CiAgICAgICAgICBjYXNlIDIwNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFN0cmluZygpOwogICAgICAgICAgY2FzZSAyMDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTaW50MzIoKTsKICAgICAgICAgIGNhc2UgMjA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDY0KCk7CiAgICAgICAgICBjYXNlIDIxMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDMyKCk7CiAgICAgICAgICBjYXNlIDIxMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDY0KCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUtub3duTWFwRmllbGQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50NjQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50MzIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkQm9vbCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTaW50MzIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQ2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcCBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcCByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5rbm93bk1hcEZpZWxkXyA9IGludGVybmFsR2V0S25vd25NYXBGaWVsZCgpOwogICAgICAgICAgcmVzdWx0Lmtub3duTWFwRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRfID0gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRJbnQ2NF8gPSBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCk7CiAgICAgICAgICByZXN1bHQudW5rbm93bk1hcEZpZWxkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRVaW50NjRfID0gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50NjQoKTsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRJbnQzMl8gPSBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDMyKCk7CiAgICAgICAgICByZXN1bHQudW5rbm93bk1hcEZpZWxkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRVaW50MzJfID0gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKTsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRGaXhlZDMyXyA9IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpOwogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRGaXhlZDY0XyA9IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpOwogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRCb29sXyA9IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpOwogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRTdHJpbmdfID0gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKTsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRTdHJpbmdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRTaW50MzJfID0gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKTsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRTaW50NjRfID0gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50NjQoKTsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRTZml4ZWQzMl8gPSBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCk7CiAgICAgICAgICByZXN1bHQudW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRTZml4ZWQ2NF8gPSBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCk7CiAgICAgICAgICByZXN1bHQudW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcCkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXApb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUtub3duTWFwRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0S25vd25NYXBGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50NjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50NjQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQ2NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50NjQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEludDMyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDMyKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRVaW50MzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDMyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkQm9vbCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTdHJpbmcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTaW50MzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTaW50NjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAga25vd25NYXBGaWVsZF9fID0gS25vd25NYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5mb3JOdW1iZXIoa25vd25NYXBGaWVsZF9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMTAxLCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVLbm93bk1hcEZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIGtub3duTWFwRmllbGRfXy5nZXRLZXkoKSwga25vd25NYXBGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODEwCiAgICAgICAgICAgICAgY2FzZSA4MTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRfXyA9IFVua25vd25NYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5mb3JOdW1iZXIodW5rbm93bk1hcEZpZWxkX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgxMDIsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRfXy5nZXRLZXkoKSwgdW5rbm93bk1hcEZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MTgKICAgICAgICAgICAgICBjYXNlIDE2MDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRJbnQ2NF9fID0gVW5rbm93bk1hcEZpZWxkSW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uZm9yTnVtYmVyKHVua25vd25NYXBGaWVsZEludDY0X18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgyMDAsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZEludDY0X18uZ2V0S2V5KCksIHVua25vd25NYXBGaWVsZEludDY0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjAyCiAgICAgICAgICAgICAgY2FzZSAxNjEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkVWludDY0X18gPSBVbmtub3duTWFwRmllbGRVaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uZm9yTnVtYmVyKHVua25vd25NYXBGaWVsZFVpbnQ2NF9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMjAxLCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRVaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkVWludDY0X18uZ2V0S2V5KCksIHVua25vd25NYXBGaWVsZFVpbnQ2NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYxMAogICAgICAgICAgICAgIGNhc2UgMTYxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZEludDMyX18gPSBVbmtub3duTWFwRmllbGRJbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5mb3JOdW1iZXIodW5rbm93bk1hcEZpZWxkSW50MzJfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDIwMiwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50MzIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkSW50MzJfXy5nZXRLZXkoKSwgdW5rbm93bk1hcEZpZWxkSW50MzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MTgKICAgICAgICAgICAgICBjYXNlIDE2MjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRVaW50MzJfXyA9IFVua25vd25NYXBGaWVsZFVpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5mb3JOdW1iZXIodW5rbm93bk1hcEZpZWxkVWludDMyX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgyMDMsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQzMigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRVaW50MzJfXy5nZXRLZXkoKSwgdW5rbm93bk1hcEZpZWxkVWludDMyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjI2CiAgICAgICAgICAgICAgY2FzZSAxNjM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkRml4ZWQzMl9fID0gVW5rbm93bk1hcEZpZWxkRml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5mb3JOdW1iZXIodW5rbm93bk1hcEZpZWxkRml4ZWQzMl9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMjA0LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZEZpeGVkMzJfXy5nZXRLZXkoKSwgdW5rbm93bk1hcEZpZWxkRml4ZWQzMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYzNAogICAgICAgICAgICAgIGNhc2UgMTY0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZEZpeGVkNjRfXyA9IFVua25vd25NYXBGaWVsZEZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uZm9yTnVtYmVyKHVua25vd25NYXBGaWVsZEZpeGVkNjRfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDIwNSwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRGaXhlZDY0X18uZ2V0S2V5KCksIHVua25vd25NYXBGaWVsZEZpeGVkNjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2NDIKICAgICAgICAgICAgICBjYXNlIDE2NTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRCb29sX18gPSBVbmtub3duTWFwRmllbGRCb29sRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLmZvck51bWJlcih1bmtub3duTWFwRmllbGRCb29sX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgyMDYsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEJvb2woKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkQm9vbF9fLmdldEtleSgpLCB1bmtub3duTWFwRmllbGRCb29sX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjUwCiAgICAgICAgICAgICAgY2FzZSAxNjU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRTdHJpbmdfXyA9IFVua25vd25NYXBGaWVsZFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bS5mb3JOdW1iZXIodW5rbm93bk1hcEZpZWxkU3RyaW5nX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgyMDcsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFN0cmluZygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRTdHJpbmdfXy5nZXRLZXkoKSwgdW5rbm93bk1hcEZpZWxkU3RyaW5nX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjU4CiAgICAgICAgICAgICAgY2FzZSAxNjY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkU2ludDMyX18gPSBVbmtub3duTWFwRmllbGRTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uZm9yTnVtYmVyKHVua25vd25NYXBGaWVsZFNpbnQzMl9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMjA4LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTaW50MzIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkU2ludDMyX18uZ2V0S2V5KCksIHVua25vd25NYXBGaWVsZFNpbnQzMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTY2NgogICAgICAgICAgICAgIGNhc2UgMTY3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZFNpbnQ2NF9fID0gVW5rbm93bk1hcEZpZWxkU2ludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLmZvck51bWJlcih1bmtub3duTWFwRmllbGRTaW50NjRfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDIwOSwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZFNpbnQ2NF9fLmdldEtleSgpLCB1bmtub3duTWFwRmllbGRTaW50NjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2NzQKICAgICAgICAgICAgICBjYXNlIDE2ODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRTZml4ZWQzMl9fID0gVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0uZm9yTnVtYmVyKHVua25vd25NYXBGaWVsZFNmaXhlZDMyX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgyMTAsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZFNmaXhlZDMyX18uZ2V0S2V5KCksIHVua25vd25NYXBGaWVsZFNmaXhlZDMyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjgyCiAgICAgICAgICAgICAgY2FzZSAxNjkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRfXyA9IFVua25vd25NYXBGaWVsZFNmaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtLmZvck51bWJlcih1bmtub3duTWFwRmllbGRTZml4ZWQ2NF9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMjExLCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRTZml4ZWQ2NF9fLmdldEtleSgpLCB1bmtub3duTWFwRmllbGRTZml4ZWQ2NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTY5MAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGtub3duTWFwRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkgewogICAgICAgIGlmIChrbm93bk1hcEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEtub3duTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGtub3duTWFwRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVLbm93bk1hcEZpZWxkKCkgewogICAgICAgIGlmIChrbm93bk1hcEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBrbm93bk1hcEZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgS25vd25NYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWtub3duTWFwRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBrbm93bk1hcEZpZWxkXyA9IGtub3duTWFwRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBrbm93bk1hcEZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEtub3duTWFwRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyBrbm93bl9tYXBfZmllbGQgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0tub3duTWFwRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEtub3duTWFwRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRLbm93bk1hcEZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgICAgZ2V0S25vd25NYXBGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0S25vd25NYXBGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyBrbm93bl9tYXBfZmllbGQgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgICAgZ2V0S25vd25NYXBGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkS25vd25NYXBGaWVsZE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IGtub3duX21hcF9maWVsZCA9IDEwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldEtub3duTWFwRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0S25vd25NYXBGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IGtub3duTWFwRmllbGRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsga25vd25fbWFwX2ZpZWxkID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0S25vd25NYXBGaWVsZE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEtub3duTWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4ga25vd25NYXBGaWVsZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyS25vd25NYXBGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlS25vd25NYXBGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsga25vd25fbWFwX2ZpZWxkID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUtub3duTWFwRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUtub3duTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZUtub3duTWFwRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRLbm93bk1hcEZpZWxkTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlS25vd25NYXBGaWVsZCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IGtub3duX21hcF9maWVsZCA9IDEwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRLbm93bk1hcEZpZWxkKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUtub3duTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIGtub3duTWFwRmllbGRWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyBrbm93bl9tYXBfZmllbGQgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsS25vd25NYXBGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZEtub3duTWFwRmllbGRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUtub3duTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHVua25vd25NYXBGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkKCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXVua25vd25NYXBGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZF8gPSB1bmtub3duTWFwRmllbGRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZCA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICBnZXRVbmtub3duTWFwRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZCA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICBnZXRVbmtub3duTWFwRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGQgPSAxMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5rbm93bk1hcEZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVVua25vd25NYXBGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgICAgICAgIGdldE11dGFibGVVbmtub3duTWFwRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZCA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRVbmtub3duTWFwRmllbGQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB1bmtub3duTWFwRmllbGRWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZCA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxVbmtub3duTWFwRmllbGQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkSW50NjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkSW50NjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkSW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEludDY0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50NjQoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZEludDY0XyA9PSBudWxsKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRJbnQ2NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZEludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghdW5rbm93bk1hcEZpZWxkSW50NjRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRJbnQ2NF8gPSB1bmtub3duTWFwRmllbGRJbnQ2NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEludDY0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZEludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50NjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZEludDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50NjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRJbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgIGdldFVua25vd25NYXBGaWVsZEludDY0KCkgewogICAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRJbnQ2NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBPdGhlciBtYXBzIHdpdGggYWxsIGtleSB0eXBlcyB0byB0ZXN0IHRoZSB1bmtub3duIGVudHJ5IHNlcmlhbGl6YXRpb24KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDY0ID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgIGdldFVua25vd25NYXBGaWVsZEludDY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRJbnQ2NE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBPdGhlciBtYXBzIHdpdGggYWxsIGtleSB0eXBlcyB0byB0ZXN0IHRoZSB1bmtub3duIGVudHJ5IHNlcmlhbGl6YXRpb24KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDY0ID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkSW50NjRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkSW50NjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogT3RoZXIgbWFwcyB3aXRoIGFsbCBrZXkgdHlwZXMgdG8gdGVzdCB0aGUgdW5rbm93biBlbnRyeSBzZXJpYWxpemF0aW9uCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQ2NCA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZEludDY0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEludDY0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVbmtub3duTWFwRmllbGRJbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVW5rbm93bk1hcEZpZWxkSW50NjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRJbnQ2NE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogT3RoZXIgbWFwcyB3aXRoIGFsbCBrZXkgdHlwZXMgdG8gdGVzdCB0aGUgdW5rbm93biBlbnRyeSBzZXJpYWxpemF0aW9uCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQ2NCA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRVbmtub3duTWFwRmllbGRJbnQ2NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHVua25vd25NYXBGaWVsZEludDY0VmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogT3RoZXIgbWFwcyB3aXRoIGFsbCBrZXkgdHlwZXMgdG8gdGVzdCB0aGUgdW5rbm93biBlbnRyeSBzZXJpYWxpemF0aW9uCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQ2NCA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxVbmtub3duTWFwRmllbGRJbnQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEludDY0TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQ2NCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkVWludDY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRVaW50NjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkVWludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRVaW50NjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRVaW50NjQoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZFVpbnQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkVWludDY0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkVWludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghdW5rbm93bk1hcEZpZWxkVWludDY0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkVWludDY0XyA9IHVua25vd25NYXBGaWVsZFVpbnQ2NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFVpbnQ2NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRVaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50NjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50NjQgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFVpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFVpbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgIGdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpIHsKICAgICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkVWludDY0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50NjQgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkVWludDY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRVaW50NjRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50NjQgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRVaW50NjRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZFVpbnQ2NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDY0ID0gMjAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkVWludDY0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRVaW50NjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVua25vd25NYXBGaWVsZFVpbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDY0ID0gMjAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVVua25vd25NYXBGaWVsZFVpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkVWludDY0TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDY0KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQ2NCA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRVbmtub3duTWFwRmllbGRVaW50NjQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdW5rbm93bk1hcEZpZWxkVWludDY0VmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQ2NCA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxVbmtub3duTWFwRmllbGRVaW50NjQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRVaW50NjRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkSW50MzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkSW50MzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkSW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEludDMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50MzIoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZEludDMyXyA9PSBudWxsKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRJbnQzMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZEludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghdW5rbm93bk1hcEZpZWxkSW50MzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRJbnQzMl8gPSB1bmtub3duTWFwRmllbGRJbnQzMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEludDMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZEludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDMyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRJbnQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRJbnQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgIGdldFVua25vd25NYXBGaWVsZEludDMyKCkgewogICAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRJbnQzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQzMiA9IDIwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICBnZXRVbmtub3duTWFwRmllbGRJbnQzMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkSW50MzJNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRJbnQzMk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZEludDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDMyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkSW50MzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRJbnQzMlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5rbm93bk1hcEZpZWxkSW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQzMiA9IDIwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVVbmtub3duTWFwRmllbGRJbnQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkSW50MzJNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQzMigpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDMyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFVua25vd25NYXBGaWVsZEludDMyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB1bmtub3duTWFwRmllbGRJbnQzMlZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDMyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFVua25vd25NYXBGaWVsZEludDMyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkSW50MzJNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEludDMyKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRVaW50MzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZFVpbnQzMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRVaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFVpbnQzMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQzMigpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkVWludDMyXyA9PSBudWxsKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRVaW50MzJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRVaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF1bmtub3duTWFwRmllbGRVaW50MzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRVaW50MzJfID0gdW5rbm93bk1hcEZpZWxkVWludDMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkVWludDMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZFVpbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQzMiA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkVWludDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRVaW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICBnZXRVbmtub3duTWFwRmllbGRVaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZFVpbnQzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDMyID0gMjAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgIGdldFVua25vd25NYXBGaWVsZFVpbnQzMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkVWludDMyTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQzMigpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDMyID0gMjAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQzMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZFVpbnQzMlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDMyID0gMjAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFVpbnQzMlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5rbm93bk1hcEZpZWxkVWludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRVaW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50MzIgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVW5rbm93bk1hcEZpZWxkVWludDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRVaW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFVpbnQzMk1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQzMigpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50MzIgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0VW5rbm93bk1hcEZpZWxkVWludDMyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdW5rbm93bk1hcEZpZWxkVWludDMyVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQzMiA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxVbmtub3duTWFwRmllbGRVaW50MzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRVaW50MzJNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQzMigpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkRml4ZWQzMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZEZpeGVkMzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkRml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkRml4ZWQzMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEZpeGVkMzIoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZEZpeGVkMzJfID09IG51bGwpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZEZpeGVkMzJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRGaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghdW5rbm93bk1hcEZpZWxkRml4ZWQzMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZEZpeGVkMzJfID0gdW5rbm93bk1hcEZpZWxkRml4ZWQzMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEZpeGVkMzJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMiA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkRml4ZWQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZEZpeGVkMzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCkgewogICAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMiA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRGaXhlZDMyTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDMyID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkRml4ZWQzMlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkMzIgPSAyMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRGaXhlZDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVbmtub3duTWFwRmllbGRGaXhlZDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkMzIgPSAyMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVW5rbm93bk1hcEZpZWxkRml4ZWQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEZpeGVkMzJNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDMyID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFVua25vd25NYXBGaWVsZEZpeGVkMzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdW5rbm93bk1hcEZpZWxkRml4ZWQzMlZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMiA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxVbmtub3duTWFwRmllbGRGaXhlZDMyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkRml4ZWQzMk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkRml4ZWQ2NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZEZpeGVkNjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkRml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkRml4ZWQ2NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEZpeGVkNjQoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZEZpeGVkNjRfID09IG51bGwpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZEZpeGVkNjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRGaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghdW5rbm93bk1hcEZpZWxkRml4ZWQ2NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZEZpeGVkNjRfID0gdW5rbm93bk1hcEZpZWxkRml4ZWQ2NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEZpeGVkNjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQ2NCA9IDIwNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRGaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpIHsKICAgICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkNjQgPSAyMDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkRml4ZWQ2NE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQ2NCA9IDIwNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZEZpeGVkNjRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRGaXhlZDY0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQ2NCA9IDIwNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZEZpeGVkNjRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRGaXhlZDY0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVbmtub3duTWFwRmllbGRGaXhlZDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkNjQgPSAyMDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRGaXhlZDY0TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQ2NCA9IDIwNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRVbmtub3duTWFwRmllbGRGaXhlZDY0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB1bmtub3duTWFwRmllbGRGaXhlZDY0VmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDY0ID0gMjA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFVua25vd25NYXBGaWVsZEZpeGVkNjQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRGaXhlZDY0TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRCb29sXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkQm9vbF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRCb29sRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRCb29sXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkQm9vbCgpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkQm9vbF8gPT0gbnVsbCkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkQm9vbF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZEJvb2xEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF1bmtub3duTWFwRmllbGRCb29sXy5pc011dGFibGUoKSkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkQm9vbF8gPSB1bmtub3duTWFwRmllbGRCb29sXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkQm9vbF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRCb29sQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9ib29sID0gMjA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRCb29sKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZEJvb2xNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICBnZXRVbmtub3duTWFwRmllbGRCb29sKCkgewogICAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRCb29sTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfYm9vbCA9IDIwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICBnZXRVbmtub3duTWFwRmllbGRCb29sTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRCb29sTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEJvb2woKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9ib29sID0gMjA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkQm9vbE9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZEJvb2xWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9ib29sID0gMjA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkQm9vbE9yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEJvb2xWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVua25vd25NYXBGaWVsZEJvb2woKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEJvb2woKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfYm9vbCA9IDIwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVVbmtub3duTWFwRmllbGRCb29sKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkQm9vbCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEJvb2xNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRCb29sKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9ib29sID0gMjA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFVua25vd25NYXBGaWVsZEJvb2woCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEJvb2woKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHVua25vd25NYXBGaWVsZEJvb2xWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2Jvb2wgPSAyMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsVW5rbm93bk1hcEZpZWxkQm9vbCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEJvb2xNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEJvb2woKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkU3RyaW5nXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZFN0cmluZ18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFN0cmluZ187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU3RyaW5nKCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRTdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZFN0cmluZ18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXVua25vd25NYXBGaWVsZFN0cmluZ18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZFN0cmluZ18gPSB1bmtub3duTWFwRmllbGRTdHJpbmdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRTdHJpbmdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc3RyaW5nID0gMjA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkgewogICAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRTdHJpbmdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3N0cmluZyA9IDIwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgIGdldFVua25vd25NYXBGaWVsZFN0cmluZ01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU3RyaW5nTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc3RyaW5nID0gMjA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkU3RyaW5nVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zdHJpbmcgPSAyMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRTdHJpbmdPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRTdHJpbmdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVua25vd25NYXBGaWVsZFN0cmluZygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc3RyaW5nID0gMjA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVVua25vd25NYXBGaWVsZFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFN0cmluZygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFN0cmluZ01hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFN0cmluZygpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zdHJpbmcgPSAyMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0VW5rbm93bk1hcEZpZWxkU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFN0cmluZygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdW5rbm93bk1hcEZpZWxkU3RyaW5nVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3N0cmluZyA9IDIwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxVbmtub3duTWFwRmllbGRTdHJpbmcoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFN0cmluZ01hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRTaW50MzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZFNpbnQzMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNpbnQzMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQzMigpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkU2ludDMyXyA9PSBudWxsKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRTaW50MzJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF1bmtub3duTWFwRmllbGRTaW50MzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRTaW50MzJfID0gdW5rbm93bk1hcEZpZWxkU2ludDMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ludDMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZFNpbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQzMiA9IDIwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkU2ludDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRTaW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICBnZXRVbmtub3duTWFwRmllbGRTaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZFNpbnQzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDMyID0gMjA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgIGdldFVua25vd25NYXBGaWVsZFNpbnQzMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ludDMyTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDMyID0gMjA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZFNpbnQzMlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDMyID0gMjA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNpbnQzMlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5rbm93bk1hcEZpZWxkU2ludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTaW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50MzIgPSAyMDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVW5rbm93bk1hcEZpZWxkU2ludDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTaW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFNpbnQzMk1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50MzIgPSAyMDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0VW5rbm93bk1hcEZpZWxkU2ludDMyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdW5rbm93bk1hcEZpZWxkU2ludDMyVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQzMiA9IDIwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxVbmtub3duTWFwRmllbGRTaW50MzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTaW50MzJNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkU2ludDY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRTaW50NjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkU2ludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRTaW50NjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTaW50NjQoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZFNpbnQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkU2ludDY0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkU2ludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghdW5rbm93bk1hcEZpZWxkU2ludDY0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkU2ludDY0XyA9IHVua25vd25NYXBGaWVsZFNpbnQ2NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNpbnQ2NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRTaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50NjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50NjQgPSAyMDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFNpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFNpbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgIGdldFVua25vd25NYXBGaWVsZFNpbnQ2NCgpIHsKICAgICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkU2ludDY0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50NjQgPSAyMDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTaW50NjRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50NjQgPSAyMDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRTaW50NjRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQ2NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZFNpbnQ2NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDY0ID0gMjA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkU2ludDY0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQ2NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRTaW50NjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVua25vd25NYXBGaWVsZFNpbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDY0ID0gMjA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVVua25vd25NYXBGaWVsZFNpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ludDY0TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQ2NCA9IDIwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRVbmtub3duTWFwRmllbGRTaW50NjQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdW5rbm93bk1hcEZpZWxkU2ludDY0VmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQ2NCA9IDIwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxVbmtub3duTWFwRmllbGRTaW50NjQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTaW50NjRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQ2NCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNmaXhlZDMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZFNmaXhlZDMyXyA9PSBudWxsKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRTZml4ZWQzMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZFNmaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRTZml4ZWQzMl8gPSB1bmtub3duTWFwRmllbGRTZml4ZWQzMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNmaXhlZDMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyID0gMjEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRTZml4ZWQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkgewogICAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQzMiA9IDIxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkMzIgPSAyMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZFNmaXhlZDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyID0gMjEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRTZml4ZWQzMlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQzMiA9IDIxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVVbmtub3duTWFwRmllbGRTZml4ZWQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyID0gMjEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFVua25vd25NYXBGaWVsZFNmaXhlZDMyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB1bmtub3duTWFwRmllbGRTZml4ZWQzMlZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyID0gMjEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFVua25vd25NYXBGaWVsZFNmaXhlZDMyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRTZml4ZWQ2NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRTZml4ZWQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRTZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRfID09IG51bGwpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZFNmaXhlZDY0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF1bmtub3duTWFwRmllbGRTZml4ZWQ2NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZFNmaXhlZDY0XyA9IHVua25vd25NYXBGaWVsZFNmaXhlZDY0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkNjQgPSAyMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFNmaXhlZDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+CiAgICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkgewogICAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQ2NCA9IDIxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkNjQgPSAyMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRTZml4ZWQ2NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQ2NCA9IDIxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNmaXhlZDY0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDY0ID0gMjExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVVua25vd25NYXBGaWVsZFNmaXhlZDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW0mZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDY0ID0gMjExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFVua25vd25NYXBGaWVsZFNmaXhlZDY0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQ2NCA9IDIxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFNmaXhlZDY0TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVudW1NYXApCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbnVtTWFwKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEVudW1NYXA+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEVudW1NYXA+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0RW51bU1hcCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFbnVtTWFwPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFbnVtTWFwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RFbnVtTWFwUGx1c0V4dHJhT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsga25vd25fbWFwX2ZpZWxkID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldEtub3duTWFwRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyBrbm93bl9tYXBfZmllbGQgPSAxMDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zS25vd25NYXBGaWVsZCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0S25vd25NYXBGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRLbm93bk1hcEZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IGtub3duX21hcF9maWVsZCA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRLbm93bk1hcEZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IGtub3duX21hcF9maWVsZCA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0S25vd25NYXBGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyBrbm93bl9tYXBfZmllbGQgPSAxMDE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldEtub3duTWFwRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGQgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGQgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZCA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkSW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogT3RoZXIgbWFwcyB3aXRoIGFsbCBrZXkgdHlwZXMgdG8gdGVzdCB0aGUgdW5rbm93biBlbnRyeSBzZXJpYWxpemF0aW9uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQ2NCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRJbnQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZEludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZEludDY0KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBPdGhlciBtYXBzIHdpdGggYWxsIGtleSB0eXBlcyB0byB0ZXN0IHRoZSB1bmtub3duIGVudHJ5IHNlcmlhbGl6YXRpb24KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDY0ID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZEludDY0TWFwKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBPdGhlciBtYXBzIHdpdGggYWxsIGtleSB0eXBlcyB0byB0ZXN0IHRoZSB1bmtub3duIGVudHJ5IHNlcmlhbGl6YXRpb24KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDY0ID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRJbnQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZEludDY0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDY0ID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZFVpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50NjQgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkVWludDY0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkVWludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDY0ID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZFVpbnQ2NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDY0ID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRVaW50NjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50NjQgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFVpbnQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkSW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQzMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRJbnQzMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkSW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkSW50MzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZEludDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDMyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRJbnQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDMyID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZFVpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50MzIgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkVWludDMyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRVaW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50MzIgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50MzIgPSAyMDM7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFVpbnQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDMyID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRVaW50MzJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDMyID0gMjA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZEZpeGVkMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkMzIgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkRml4ZWQzMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMiA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMiA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkMzIgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZEZpeGVkMzJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDY0ID0gMjA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZEZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkNjQgPSAyMDU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZEZpeGVkNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkNjQgPSAyMDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkNjQgPSAyMDU7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZEZpeGVkNjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQ2NCA9IDIwNTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9ib29sID0gMjA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZEJvb2xDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2Jvb2wgPSAyMDY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkQm9vbCgKICAgICAgICBib29sZWFuIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZEJvb2xNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2Jvb2wgPSAyMDY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkQm9vbE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2Jvb2wgPSAyMDY7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZEJvb2xPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfYm9vbCA9IDIwNjs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkQm9vbE9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3N0cmluZyA9IDIwNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRVbmtub3duTWFwRmllbGRTdHJpbmdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc3RyaW5nID0gMjA3OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFN0cmluZygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc3RyaW5nID0gMjA3OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zdHJpbmcgPSAyMDc7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFN0cmluZ09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3N0cmluZyA9IDIwNzs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDMyID0gMjA4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZFNpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50MzIgPSAyMDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkU2ludDMyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRTaW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50MzIgPSAyMDg7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50MzIgPSAyMDg7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFNpbnQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDMyID0gMjA4OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTaW50MzJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQ2NCA9IDIwOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRVbmtub3duTWFwRmllbGRTaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDY0ID0gMjA5OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFNpbnQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFNpbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRVbmtub3duTWFwRmllbGRTaW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQ2NCA9IDIwOTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRVbmtub3duTWFwRmllbGRTaW50NjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQ2NCA9IDIwOTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDY0ID0gMjA5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTaW50NjRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyID0gMjEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkMzIgPSAyMTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFNmaXhlZDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyID0gMjEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyID0gMjEwOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQzMiA9IDIxMDs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkNjQgPSAyMTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQ2NCA9IDIxMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFNmaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDY0ID0gMjExOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDY0ID0gMjExOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhICAgICAgICAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkNjQgPSAyMTE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEVudW1NYXBQbHVzRXh0cmEgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmEpCiAgICAgIFRlc3RFbnVtTWFwUGx1c0V4dHJhT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0RW51bU1hcFBsdXNFeHRyYS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0RW51bU1hcFBsdXNFeHRyYShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RFbnVtTWFwUGx1c0V4dHJhKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RFbnVtTWFwUGx1c0V4dHJhKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMTAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0S25vd25NYXBGaWVsZCgpOwogICAgICAgIGNhc2UgMTAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCk7CiAgICAgICAgY2FzZSAyMDA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpOwogICAgICAgIGNhc2UgMjAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCk7CiAgICAgICAgY2FzZSAyMDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpOwogICAgICAgIGNhc2UgMjAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCk7CiAgICAgICAgY2FzZSAyMDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCk7CiAgICAgICAgY2FzZSAyMDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCk7CiAgICAgICAgY2FzZSAyMDY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCk7CiAgICAgICAgY2FzZSAyMDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKTsKICAgICAgICBjYXNlIDIwODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpOwogICAgICAgIGNhc2UgMjA5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCk7CiAgICAgICAgY2FzZSAyMTA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpOwogICAgICAgIGNhc2UgMjExOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBLTk9XTl9NQVBfRklFTERfRklFTERfTlVNQkVSID0gMTAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgS25vd25NYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Lbm93bk1hcEZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5FX1BST1RPMl9NQVBfRU5VTV9GT08uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBrbm93bk1hcEZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEtub3duTWFwRmllbGQoKSB7CiAgICAgIGlmIChrbm93bk1hcEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgS25vd25NYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBrbm93bk1hcEZpZWxkXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPiBrbm93bk1hcEZpZWxkVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5FX1BST1RPMl9NQVBfRU5VTV9GT08pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGludGVybmFsR2V0QWRhcHRlZEtub3duTWFwRmllbGRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBrbm93bk1hcEZpZWxkVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRLbm93bk1hcEZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEtub3duTWFwRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IGtub3duX21hcF9maWVsZCA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS25vd25NYXBGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0S25vd25NYXBGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0S25vd25NYXBGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldEtub3duTWFwRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsga25vd25fbWFwX2ZpZWxkID0gMTAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRLbm93bk1hcEZpZWxkTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkS25vd25NYXBGaWVsZE1hcCgKICAgICAgICAgIGludGVybmFsR2V0S25vd25NYXBGaWVsZCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IGtub3duX21hcF9maWVsZCA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldEtub3duTWFwRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEtub3duTWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IGtub3duTWFwRmllbGRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IGtub3duX21hcF9maWVsZCA9IDEwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldEtub3duTWFwRmllbGRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBrbm93bk1hcEZpZWxkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9NQVBfRklFTERfRklFTERfTlVNQkVSID0gMTAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVW5rbm93bk1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuRV9QUk9UTzJfTUFQX0VOVU1fRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpIHsKICAgICAgaWYgKHVua25vd25NYXBGaWVsZF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFVua25vd25NYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHVua25vd25NYXBGaWVsZFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuRV9QUk9UTzJfTUFQX0VOVU1fRk9PKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCB1bmtub3duTWFwRmllbGRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRVbmtub3duTWFwRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGQgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZE1hcCgKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGQgPSAxMDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZCA9IDEwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9NQVBfRklFTERfSU5UNjRfRklFTERfTlVNQkVSID0gMjAwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVW5rbm93bk1hcEZpZWxkSW50NjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkSW50NjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5FX1BST1RPMl9NQVBfRU5VTV9GT08uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRJbnQ2NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpIHsKICAgICAgaWYgKHVua25vd25NYXBGaWVsZEludDY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkSW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkSW50NjRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHVua25vd25NYXBGaWVsZEludDY0VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5FX1BST1RPMl9NQVBfRU5VTV9GT08pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEludDY0TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdW5rbm93bk1hcEZpZWxkSW50NjRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZEludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogT3RoZXIgbWFwcyB3aXRoIGFsbCBrZXkgdHlwZXMgdG8gdGVzdCB0aGUgdW5rbm93biBlbnRyeSBzZXJpYWxpemF0aW9uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQ2NCA9IDIwMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkSW50NjQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkSW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZEludDY0KCkgewogICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkSW50NjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZEludDY0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkSW50NjRNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRJbnQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRJbnQ2NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRJbnQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkSW50NjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX01BUF9GSUVMRF9VSU5UNjRfRklFTERfTlVNQkVSID0gMjAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVW5rbm93bk1hcEZpZWxkVWludDY0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFVpbnQ2NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5FX1BST1RPMl9NQVBfRU5VTV9GT08uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRVaW50NjRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCkgewogICAgICBpZiAodW5rbm93bk1hcEZpZWxkVWludDY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkVWludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFVpbnQ2NF87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4gdW5rbm93bk1hcEZpZWxkVWludDY0VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5FX1BST1RPMl9NQVBfRU5VTV9GT08pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFVpbnQ2NE1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEsIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIHVua25vd25NYXBGaWVsZFVpbnQ2NFZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkVWludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQ2NCA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkVWludDY0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50NjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRVaW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpIHsKICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZFVpbnQ2NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDY0ID0gMjAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRVbmtub3duTWFwRmllbGRVaW50NjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRVaW50NjRNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50NjQgPSAyMDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRVaW50NjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50NjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZFVpbnQ2NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQ2NCA9IDIwMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFVpbnQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50NjQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFVpbnQ2NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOS05PV05fTUFQX0ZJRUxEX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDIwMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFVua25vd25NYXBGaWVsZEludDMyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZEludDMyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5FX1BST1RPMl9NQVBfRU5VTV9GT08uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRJbnQzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpIHsKICAgICAgaWYgKHVua25vd25NYXBGaWVsZEludDMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkSW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkSW50MzJfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHVua25vd25NYXBGaWVsZEludDMyVmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5FX1BST1RPMl9NQVBfRU5VTV9GT08pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEludDMyTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdW5rbm93bk1hcEZpZWxkSW50MzJWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZEludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQzMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkSW50MzIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRVbmtub3duTWFwRmllbGRJbnQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKSB7CiAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRJbnQzMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQzMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkSW50MzJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRJbnQzMk1hcCgKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQzMiA9IDIwMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZEludDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkSW50MzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDMyID0gMjAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkSW50MzJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkSW50MzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX01BUF9GSUVMRF9VSU5UMzJfRklFTERfTlVNQkVSID0gMjAzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVW5rbm93bk1hcEZpZWxkVWludDMyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFVpbnQzMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLkVfUFJPVE8yX01BUF9FTlVNX0ZPTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHVua25vd25NYXBGaWVsZFVpbnQzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKSB7CiAgICAgIGlmICh1bmtub3duTWFwRmllbGRVaW50MzJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBVbmtub3duTWFwRmllbGRVaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkVWludDMyXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPiB1bmtub3duTWFwRmllbGRVaW50MzJWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLkVfUFJPVE8yX01BUF9FTlVNX0ZPTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkVWludDMyTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdW5rbm93bk1hcEZpZWxkVWludDMyVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRVaW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDMyID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRVaW50MzIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRVbmtub3duTWFwRmllbGRVaW50MzIoKSB7CiAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRVaW50MzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQzMiA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkVWludDMyTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDMyID0gMjAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZFVpbnQzMlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQzMiA9IDIwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFVpbnQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkVWludDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9NQVBfRklFTERfRklYRUQzMl9GSUVMRF9OVU1CRVIgPSAyMDQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBVbmtub3duTWFwRmllbGRGaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZEZpeGVkMzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuRV9QUk9UTzJfTUFQX0VOVU1fRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkRml4ZWQzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCkgewogICAgICBpZiAodW5rbm93bk1hcEZpZWxkRml4ZWQzMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFVua25vd25NYXBGaWVsZEZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkRml4ZWQzMl87CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4gdW5rbm93bk1hcEZpZWxkRml4ZWQzMlZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuRV9QUk9UTzJfTUFQX0VOVU1fRk9PKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRGaXhlZDMyTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdW5rbm93bk1hcEZpZWxkRml4ZWQzMlZhbHVlQ29udmVydGVyKTsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkMzIgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZEZpeGVkMzIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZEZpeGVkMzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKSB7CiAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMiA9IDIwNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEZpeGVkMzJNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkMzIgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRGaXhlZDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkMzIgPSAyMDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkRml4ZWQzMlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOS05PV05fTUFQX0ZJRUxEX0ZJWEVENjRfRklFTERfTlVNQkVSID0gMjA1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVW5rbm93bk1hcEZpZWxkRml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRGaXhlZDY0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5FX1BST1RPMl9NQVBfRU5VTV9GT08uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRGaXhlZDY0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKSB7CiAgICAgIGlmICh1bmtub3duTWFwRmllbGRGaXhlZDY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkRml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRGaXhlZDY0XzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPiB1bmtub3duTWFwRmllbGRGaXhlZDY0VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5FX1BST1RPMl9NQVBfRU5VTV9GT08pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEZpeGVkNjRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCB1bmtub3duTWFwRmllbGRGaXhlZDY0VmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRGaXhlZDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQ2NCA9IDIwNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZEZpeGVkNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKSB7CiAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRGaXhlZDY0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQ2NCA9IDIwNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEZpeGVkNjRNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkNjQgPSAyMDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRGaXhlZDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkRml4ZWQ2NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDY0ID0gMjA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRGaXhlZDY0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9NQVBfRklFTERfQk9PTF9GSUVMRF9OVU1CRVIgPSAyMDY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBVbmtub3duTWFwRmllbGRCb29sRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZEJvb2xFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLkVfUFJPVE8yX01BUF9FTlVNX0ZPTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IHVua25vd25NYXBGaWVsZEJvb2xfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpIHsKICAgICAgaWYgKHVua25vd25NYXBGaWVsZEJvb2xfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBVbmtub3duTWFwRmllbGRCb29sRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEJvb2xfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHVua25vd25NYXBGaWVsZEJvb2xWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLkVfUFJPVE8yX01BUF9FTlVNX0ZPTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkQm9vbE1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEsIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIHVua25vd25NYXBGaWVsZEJvb2xWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZEJvb2xDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9ib29sID0gMjA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRCb29sKAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkQm9vbE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpIHsKICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZEJvb2xNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9ib29sID0gMjA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRVbmtub3duTWFwRmllbGRCb29sTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkQm9vbE1hcCgKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfYm9vbCA9IDIwNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZEJvb2xPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRCb29sVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2Jvb2wgPSAyMDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRCb29sT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEJvb2woKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEJvb2xWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX01BUF9GSUVMRF9TVFJJTkdfRklFTERfTlVNQkVSID0gMjA3OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVW5rbm93bk1hcEZpZWxkU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRTdHJpbmdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuRV9QUk9UTzJfTUFQX0VOVU1fRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRTdHJpbmdfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKSB7CiAgICAgIGlmICh1bmtub3duTWFwRmllbGRTdHJpbmdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBVbmtub3duTWFwRmllbGRTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU3RyaW5nXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPiB1bmtub3duTWFwRmllbGRTdHJpbmdWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLkVfUFJPVE8yX01BUF9FTlVNX0ZPTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTdHJpbmdNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdW5rbm93bk1hcEZpZWxkU3RyaW5nVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRTdHJpbmdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc3RyaW5nID0gMjA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRTdHJpbmcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKSB7CiAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRTdHJpbmdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3N0cmluZyA9IDIwNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRVbmtub3duTWFwRmllbGRTdHJpbmdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTdHJpbmdNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zdHJpbmcgPSAyMDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTdHJpbmdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkU3RyaW5nVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc3RyaW5nID0gMjA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRTdHJpbmdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX01BUF9GSUVMRF9TSU5UMzJfRklFTERfTlVNQkVSID0gMjA4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVW5rbm93bk1hcEZpZWxkU2ludDMyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFNpbnQzMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLkVfUFJPVE8yX01BUF9FTlVNX0ZPTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHVua25vd25NYXBGaWVsZFNpbnQzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKSB7CiAgICAgIGlmICh1bmtub3duTWFwRmllbGRTaW50MzJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBVbmtub3duTWFwRmllbGRTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ludDMyXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPiB1bmtub3duTWFwRmllbGRTaW50MzJWYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLkVfUFJPVE8yX01BUF9FTlVNX0ZPTyk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ludDMyTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdW5rbm93bk1hcEZpZWxkU2ludDMyVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRTaW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDMyID0gMjA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRTaW50MzIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRVbmtub3duTWFwRmllbGRTaW50MzIoKSB7CiAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRTaW50MzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQzMiA9IDIwODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ludDMyTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDMyID0gMjA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZFNpbnQzMlZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQzMiA9IDIwODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFNpbnQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ludDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9NQVBfRklFTERfU0lOVDY0X0ZJRUxEX05VTUJFUiA9IDIwOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIFVua25vd25NYXBGaWVsZFNpbnQ2NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRTaW50NjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuRV9QUk9UTzJfTUFQX0VOVU1fRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkU2ludDY0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQ2NCgpIHsKICAgICAgaWYgKHVua25vd25NYXBGaWVsZFNpbnQ2NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFVua25vd25NYXBGaWVsZFNpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRTaW50NjRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHVua25vd25NYXBGaWVsZFNpbnQ2NFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuRV9QUk9UTzJfTUFQX0VOVU1fRk9PKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTaW50NjRNYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCB1bmtub3duTWFwRmllbGRTaW50NjRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZFNpbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50NjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50NjQgPSAyMDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFNpbnQ2NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkU2ludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBnZXRVbmtub3duTWFwRmllbGRTaW50NjQoKSB7CiAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRTaW50NjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQ2NCA9IDIwOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDY0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ludDY0TWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50NjQoKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDY0ID0gMjA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRTaW50NjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50NjQgPSAyMDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTaW50NjRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRTaW50NjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTktOT1dOX01BUF9GSUVMRF9TRklYRUQzMl9GSUVMRF9OVU1CRVIgPSAyMTA7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBVbmtub3duTWFwRmllbGRTZml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRTZml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuRV9QUk9UTzJfTUFQX0VOVU1fRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKSB7CiAgICAgIGlmICh1bmtub3duTWFwRmllbGRTZml4ZWQzMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIFVua25vd25NYXBGaWVsZFNmaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNmaXhlZDMyXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPiB1bmtub3duTWFwRmllbGRTZml4ZWQzMlZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuRV9QUk9UTzJfTUFQX0VOVU1fRk9PKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTZml4ZWQzMk1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEsIGphdmEubGFuZy5JbnRlZ2VyPigKICAgICAgICAgICAgICBtYXAsIHVua25vd25NYXBGaWVsZFNmaXhlZDMyVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkMzIgPSAyMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFNmaXhlZDMyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkgewogICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkMzIgPSAyMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkMzIgPSAyMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZFNmaXhlZDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQzMiA9IDIxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNmaXhlZDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5LTk9XTl9NQVBfRklFTERfU0ZJWEVENjRfRklFTERfTlVNQkVSID0gMjExOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRU5VTSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5FX1BST1RPMl9NQVBfRU5VTV9GT08uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRTZml4ZWQ2NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpIHsKICAgICAgaWYgKHVua25vd25NYXBGaWVsZFNmaXhlZDY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRfOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHVua25vd25NYXBGaWVsZFNmaXhlZDY0VmFsdWVDb252ZXJ0ZXIgPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIubmV3RW51bUNvbnZlcnRlcigKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuaW50ZXJuYWxHZXRWYWx1ZU1hcCgpLAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5FX1BST1RPMl9NQVBfRU5VTV9GT08pOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFNmaXhlZDY0TWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRWYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQ2NCA9IDIxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkgewogICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkNjQgPSAyMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRNYXAoCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuZ2V0TWFwKCkpO30KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkNjQgPSAyMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRTZml4ZWQ2NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkNjQgPSAyMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0S25vd25NYXBGaWVsZCgpLAogICAgICAgICAgS25vd25NYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMDEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpLAogICAgICAgICAgVW5rbm93bk1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwMik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50NjQoKSwKICAgICAgICAgIFVua25vd25NYXBGaWVsZEludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIwMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCksCiAgICAgICAgICBVbmtub3duTWFwRmllbGRVaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpLAogICAgICAgICAgVW5rbm93bk1hcEZpZWxkSW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjAyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKSwKICAgICAgICAgIFVua25vd25NYXBGaWVsZFVpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKSwKICAgICAgICAgIFVua25vd25NYXBGaWVsZEZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjA0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCksCiAgICAgICAgICBVbmtub3duTWFwRmllbGRGaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIwNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUJvb2xlYW5NYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpLAogICAgICAgICAgVW5rbm93bk1hcEZpZWxkQm9vbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCksCiAgICAgICAgICBVbmtub3duTWFwRmllbGRTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMjA3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKSwKICAgICAgICAgIFVua25vd25NYXBGaWVsZFNpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyMDgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQ2NCgpLAogICAgICAgICAgVW5rbm93bk1hcEZpZWxkU2ludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIwOSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKSwKICAgICAgICAgIFVua25vd25NYXBGaWVsZFNmaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIxMCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKSwKICAgICAgICAgIFVua25vd25NYXBGaWVsZFNmaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIxMSk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGtub3duTWFwRmllbGRfXyA9IEtub3duTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwMSwga25vd25NYXBGaWVsZF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgdW5rbm93bk1hcEZpZWxkX18gPSBVbmtub3duTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwMiwgdW5rbm93bk1hcEZpZWxkX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHVua25vd25NYXBGaWVsZEludDY0X18gPSBVbmtub3duTWFwRmllbGRJbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAwLCB1bmtub3duTWFwRmllbGRJbnQ2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50NjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgdW5rbm93bk1hcEZpZWxkVWludDY0X18gPSBVbmtub3duTWFwRmllbGRVaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwMSwgdW5rbm93bk1hcEZpZWxkVWludDY0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHVua25vd25NYXBGaWVsZEludDMyX18gPSBVbmtub3duTWFwRmllbGRJbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjAyLCB1bmtub3duTWFwRmllbGRJbnQzMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgdW5rbm93bk1hcEZpZWxkVWludDMyX18gPSBVbmtub3duTWFwRmllbGRVaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwMywgdW5rbm93bk1hcEZpZWxkVWludDMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgdW5rbm93bk1hcEZpZWxkRml4ZWQzMl9fID0gVW5rbm93bk1hcEZpZWxkRml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjA0LCB1bmtub3duTWFwRmllbGRGaXhlZDMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgdW5rbm93bk1hcEZpZWxkRml4ZWQ2NF9fID0gVW5rbm93bk1hcEZpZWxkRml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjA1LCB1bmtub3duTWFwRmllbGRGaXhlZDY0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEJvb2woKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgdW5rbm93bk1hcEZpZWxkQm9vbF9fID0gVW5rbm93bk1hcEZpZWxkQm9vbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjA2LCB1bmtub3duTWFwRmllbGRCb29sX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgdW5rbm93bk1hcEZpZWxkU3RyaW5nX18gPSBVbmtub3duTWFwRmllbGRTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwNywgdW5rbm93bk1hcEZpZWxkU3RyaW5nX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICB1bmtub3duTWFwRmllbGRTaW50MzJfXyA9IFVua25vd25NYXBGaWVsZFNpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMjA4LCB1bmtub3duTWFwRmllbGRTaW50MzJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIHVua25vd25NYXBGaWVsZFNpbnQ2NF9fID0gVW5rbm93bk1hcEZpZWxkU2ludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMDksIHVua25vd25NYXBGaWVsZFNpbnQ2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICB1bmtub3duTWFwRmllbGRTZml4ZWQzMl9fID0gVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIxMCwgdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRfXyA9IFVua25vd25NYXBGaWVsZFNmaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMTEsIHVua25vd25NYXBGaWVsZFNmaXhlZDY0X18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSkgb2JqOwoKICAgICAgaWYgKCFpbnRlcm5hbEdldEtub3duTWFwRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEtub3duTWFwRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50NjQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQ2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgS05PV05fTUFQX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldEtub3duTWFwRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVTktOT1dOX01BUF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVOS05PV05fTUFQX0ZJRUxEX0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5LTk9XTl9NQVBfRklFTERfVUlOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDMyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5LTk9XTl9NQVBfRklFTERfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVTktOT1dOX01BUF9GSUVMRF9VSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVOS05PV05fTUFQX0ZJRUxEX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVTktOT1dOX01BUF9GSUVMRF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5LTk9XTl9NQVBfRklFTERfQk9PTF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5LTk9XTl9NQVBfRklFTERfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVOS05PV05fTUFQX0ZJRUxEX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50NjQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVTktOT1dOX01BUF9GSUVMRF9TSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVTktOT1dOX01BUF9GSUVMRF9TRklYRUQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5LTk9XTl9NQVBfRklFTERfU0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmEgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmEgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmEpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmFPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMTAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCk7CiAgICAgICAgICBjYXNlIDEwMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCk7CiAgICAgICAgICBjYXNlIDIwMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50NjQoKTsKICAgICAgICAgIGNhc2UgMjAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50NjQoKTsKICAgICAgICAgIGNhc2UgMjAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpOwogICAgICAgICAgY2FzZSAyMDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQzMigpOwogICAgICAgICAgY2FzZSAyMDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKTsKICAgICAgICAgIGNhc2UgMjA1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCk7CiAgICAgICAgICBjYXNlIDIwNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpOwogICAgICAgICAgY2FzZSAyMDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpOwogICAgICAgICAgY2FzZSAyMDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpOwogICAgICAgICAgY2FzZSAyMDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQ2NCgpOwogICAgICAgICAgY2FzZSAyMTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCk7CiAgICAgICAgICBjYXNlIDIxMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDEwMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZUtub3duTWFwRmllbGQoKTsKICAgICAgICAgIGNhc2UgMTAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkKCk7CiAgICAgICAgICBjYXNlIDIwMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEludDY0KCk7CiAgICAgICAgICBjYXNlIDIwMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQ2NCgpOwogICAgICAgICAgY2FzZSAyMDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQzMigpOwogICAgICAgICAgY2FzZSAyMDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRVaW50MzIoKTsKICAgICAgICAgIGNhc2UgMjA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQzMigpOwogICAgICAgICAgY2FzZSAyMDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDY0KCk7CiAgICAgICAgICBjYXNlIDIwNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEJvb2woKTsKICAgICAgICAgIGNhc2UgMjA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU3RyaW5nKCk7CiAgICAgICAgICBjYXNlIDIwODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQzMigpOwogICAgICAgICAgY2FzZSAyMDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTaW50NjQoKTsKICAgICAgICAgIGNhc2UgMjEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKTsKICAgICAgICAgIGNhc2UgMjExOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmEuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlS25vd25NYXBGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQ2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDY0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDMyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRCb29sKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTdHJpbmcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDY0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmEgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmEuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmEgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lmtub3duTWFwRmllbGRfID0gaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCk7CiAgICAgICAgICByZXN1bHQua25vd25NYXBGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZF8gPSBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpOwogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZEludDY0XyA9IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50NjQoKTsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZFVpbnQ2NF8gPSBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpOwogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZEludDMyXyA9IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKTsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZFVpbnQzMl8gPSBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQzMigpOwogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZEZpeGVkMzJfID0gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCk7CiAgICAgICAgICByZXN1bHQudW5rbm93bk1hcEZpZWxkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZEZpeGVkNjRfID0gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCk7CiAgICAgICAgICByZXN1bHQudW5rbm93bk1hcEZpZWxkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZEJvb2xfID0gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCk7CiAgICAgICAgICByZXN1bHQudW5rbm93bk1hcEZpZWxkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZFN0cmluZ18gPSBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpOwogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZFN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZFNpbnQzMl8gPSBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpOwogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZFNpbnQ2NF8gPSBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQ2NCgpOwogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZFNmaXhlZDMyXyA9IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKTsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnVua25vd25NYXBGaWVsZFNmaXhlZDY0XyA9IGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKTsKICAgICAgICAgIHJlc3VsdC51bmtub3duTWFwRmllbGRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlS25vd25NYXBGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQ2NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDY0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50MzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQzMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEZpeGVkMzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRCb29sKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEJvb2woKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFN0cmluZygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQzMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQ2NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50NjQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4MTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBrbm93bk1hcEZpZWxkX18gPSBLbm93bk1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLmZvck51bWJlcihrbm93bk1hcEZpZWxkX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgxMDEsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUtub3duTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAga25vd25NYXBGaWVsZF9fLmdldEtleSgpLCBrbm93bk1hcEZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MTAKICAgICAgICAgICAgICBjYXNlIDgxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZF9fID0gVW5rbm93bk1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLmZvck51bWJlcih1bmtub3duTWFwRmllbGRfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDEwMiwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZF9fLmdldEtleSgpLCB1bmtub3duTWFwRmllbGRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxOAogICAgICAgICAgICAgIGNhc2UgMTYwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZEludDY0X18gPSBVbmtub3duTWFwRmllbGRJbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5mb3JOdW1iZXIodW5rbm93bk1hcEZpZWxkSW50NjRfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDIwMCwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50NjQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkSW50NjRfXy5nZXRLZXkoKSwgdW5rbm93bk1hcEZpZWxkSW50NjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MDIKICAgICAgICAgICAgICBjYXNlIDE2MTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRVaW50NjRfXyA9IFVua25vd25NYXBGaWVsZFVpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5mb3JOdW1iZXIodW5rbm93bk1hcEZpZWxkVWludDY0X18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgyMDEsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRVaW50NjRfXy5nZXRLZXkoKSwgdW5rbm93bk1hcEZpZWxkVWludDY0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjEwCiAgICAgICAgICAgICAgY2FzZSAxNjE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkSW50MzJfXyA9IFVua25vd25NYXBGaWVsZEludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLmZvck51bWJlcih1bmtub3duTWFwRmllbGRJbnQzMl9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMjAyLCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQzMigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRJbnQzMl9fLmdldEtleSgpLCB1bmtub3duTWFwRmllbGRJbnQzMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYxOAogICAgICAgICAgICAgIGNhc2UgMTYyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZFVpbnQzMl9fID0gVW5rbm93bk1hcEZpZWxkVWludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLmZvck51bWJlcih1bmtub3duTWFwRmllbGRVaW50MzJfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDIwMywgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZFVpbnQzMl9fLmdldEtleSgpLCB1bmtub3duTWFwRmllbGRVaW50MzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MjYKICAgICAgICAgICAgICBjYXNlIDE2MzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRGaXhlZDMyX18gPSBVbmtub3duTWFwRmllbGRGaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLmZvck51bWJlcih1bmtub3duTWFwRmllbGRGaXhlZDMyX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgyMDQsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkRml4ZWQzMl9fLmdldEtleSgpLCB1bmtub3duTWFwRmllbGRGaXhlZDMyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjM0CiAgICAgICAgICAgICAgY2FzZSAxNjQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkRml4ZWQ2NF9fID0gVW5rbm93bk1hcEZpZWxkRml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5mb3JOdW1iZXIodW5rbm93bk1hcEZpZWxkRml4ZWQ2NF9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMjA1LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZEZpeGVkNjRfXy5nZXRLZXkoKSwgdW5rbm93bk1hcEZpZWxkRml4ZWQ2NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTY0MgogICAgICAgICAgICAgIGNhc2UgMTY1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZEJvb2xfXyA9IFVua25vd25NYXBGaWVsZEJvb2xEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuZm9yTnVtYmVyKHVua25vd25NYXBGaWVsZEJvb2xfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDIwNiwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRCb29sX18uZ2V0S2V5KCksIHVua25vd25NYXBGaWVsZEJvb2xfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2NTAKICAgICAgICAgICAgICBjYXNlIDE2NTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZFN0cmluZ19fID0gVW5rbm93bk1hcEZpZWxkU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCkucGFyc2VGcm9tKGJ5dGVzKTsKICAgICAgICAgICAgICAgIGlmIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhLmZvck51bWJlcih1bmtub3duTWFwRmllbGRTdHJpbmdfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDIwNywgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZFN0cmluZ19fLmdldEtleSgpLCB1bmtub3duTWFwRmllbGRTdHJpbmdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2NTgKICAgICAgICAgICAgICBjYXNlIDE2NjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRTaW50MzJfXyA9IFVua25vd25NYXBGaWVsZFNpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5mb3JOdW1iZXIodW5rbm93bk1hcEZpZWxkU2ludDMyX18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgyMDgsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRTaW50MzJfXy5nZXRLZXkoKSwgdW5rbm93bk1hcEZpZWxkU2ludDMyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjY2CiAgICAgICAgICAgICAgY2FzZSAxNjc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkU2ludDY0X18gPSBVbmtub3duTWFwRmllbGRTaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuZm9yTnVtYmVyKHVua25vd25NYXBGaWVsZFNpbnQ2NF9fLmdldFZhbHVlKCkpID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duTGVuZ3RoRGVsaW1pdGVkRmllbGQoMjA5LCBieXRlcyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkU2ludDY0X18uZ2V0S2V5KCksIHVua25vd25NYXBGaWVsZFNpbnQ2NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTY3NAogICAgICAgICAgICAgIGNhc2UgMTY4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZFNmaXhlZDMyX18gPSBVbmtub3duTWFwRmllbGRTZml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYS5mb3JOdW1iZXIodW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDIxMCwgYnl0ZXMpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfXy5nZXRLZXkoKSwgdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2ODIKICAgICAgICAgICAgICBjYXNlIDE2OTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlcyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICB1bmtub3duTWFwRmllbGRTZml4ZWQ2NF9fID0gVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKS5wYXJzZUZyb20oYnl0ZXMpOwogICAgICAgICAgICAgICAgaWYgKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEuZm9yTnVtYmVyKHVua25vd25NYXBGaWVsZFNmaXhlZDY0X18uZ2V0VmFsdWUoKSkgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25MZW5ndGhEZWxpbWl0ZWRGaWVsZCgyMTEsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICAgIHVua25vd25NYXBGaWVsZFNmaXhlZDY0X18uZ2V0S2V5KCksIHVua25vd25NYXBGaWVsZFNmaXhlZDY0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjkwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4ga25vd25NYXBGaWVsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEtub3duTWFwRmllbGQoKSB7CiAgICAgICAgaWYgKGtub3duTWFwRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgS25vd25NYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4ga25vd25NYXBGaWVsZF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUtub3duTWFwRmllbGQoKSB7CiAgICAgICAgaWYgKGtub3duTWFwRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIGtub3duTWFwRmllbGRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBLbm93bk1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICgha25vd25NYXBGaWVsZF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIGtub3duTWFwRmllbGRfID0ga25vd25NYXBGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGtub3duTWFwRmllbGRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0S25vd25NYXBGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEtub3duTWFwRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IGtub3duX21hcF9maWVsZCA9IDEwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zS25vd25NYXBGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0S25vd25NYXBGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEtub3duTWFwRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgICBnZXRLbm93bk1hcEZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRLbm93bk1hcEZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IGtub3duX21hcF9maWVsZCA9IDEwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgICBnZXRLbm93bk1hcEZpZWxkTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRLbm93bk1hcEZpZWxkTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldEtub3duTWFwRmllbGQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsga25vd25fbWFwX2ZpZWxkID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0S25vd25NYXBGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRLbm93bk1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8ga25vd25NYXBGaWVsZFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyBrbm93bl9tYXBfZmllbGQgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRLbm93bk1hcEZpZWxkT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0S25vd25NYXBGaWVsZCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBrbm93bk1hcEZpZWxkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJLbm93bk1hcEZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVLbm93bk1hcEZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyBrbm93bl9tYXBfZmllbGQgPSAxMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlS25vd25NYXBGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlS25vd25NYXBGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgICAgICBnZXRNdXRhYmxlS25vd25NYXBGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZEtub3duTWFwRmllbGRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVLbm93bk1hcEZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsga25vd25fbWFwX2ZpZWxkID0gMTAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEtub3duTWFwRmllbGQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlS25vd25NYXBGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwga25vd25NYXBGaWVsZFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IGtub3duX21hcF9maWVsZCA9IDEwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxLbm93bk1hcEZpZWxkKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkS25vd25NYXBGaWVsZE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlS25vd25NYXBGaWVsZCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdW5rbm93bk1hcEZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkKCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGQoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghdW5rbm93bk1hcEZpZWxkXy5pc011dGFibGUoKSkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkXyA9IHVua25vd25NYXBGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgIGdldFVua25vd25NYXBGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgIGdldFVua25vd25NYXBGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZCA9IDEwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGQgPSAxMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVbmtub3duTWFwRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGQgPSAxMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVW5rbm93bk1hcEZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgICAgICAgZ2V0TXV0YWJsZVVua25vd25NYXBGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZCgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFVua25vd25NYXBGaWVsZCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHVua25vd25NYXBGaWVsZFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkID0gMTAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFVua25vd25NYXBGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRJbnQ2NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRJbnQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRJbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkSW50NjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQ2NCgpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkSW50NjRfID09IG51bGwpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZEludDY0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkSW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF1bmtub3duTWFwRmllbGRJbnQ2NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZEludDY0XyA9IHVua25vd25NYXBGaWVsZEludDY0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkSW50NjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkSW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogT3RoZXIgbWFwcyB3aXRoIGFsbCBrZXkgdHlwZXMgdG8gdGVzdCB0aGUgdW5rbm93biBlbnRyeSBzZXJpYWxpemF0aW9uCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQ2NCA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkSW50NjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZEludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkSW50NjQoKSB7CiAgICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZEludDY0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkSW50NjRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEludDY0TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE90aGVyIG1hcHMgd2l0aCBhbGwga2V5IHR5cGVzIHRvIHRlc3QgdGhlIHVua25vd24gZW50cnkgc2VyaWFsaXphdGlvbgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50NjQgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRJbnQ2NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50NjQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRJbnQ2NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBPdGhlciBtYXBzIHdpdGggYWxsIGtleSB0eXBlcyB0byB0ZXN0IHRoZSB1bmtub3duIGVudHJ5IHNlcmlhbGl6YXRpb24KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDY0ID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkSW50NjRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkSW50NjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkSW50NjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVua25vd25NYXBGaWVsZEludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogT3RoZXIgbWFwcyB3aXRoIGFsbCBrZXkgdHlwZXMgdG8gdGVzdCB0aGUgdW5rbm93biBlbnRyeSBzZXJpYWxpemF0aW9uCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQ2NCA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVVbmtub3duTWFwRmllbGRJbnQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgICAgIGdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEludDY0TWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50NjQoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBPdGhlciBtYXBzIHdpdGggYWxsIGtleSB0eXBlcyB0byB0ZXN0IHRoZSB1bmtub3duIGVudHJ5IHNlcmlhbGl6YXRpb24KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDY0ID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFVua25vd25NYXBGaWVsZEludDY0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdW5rbm93bk1hcEZpZWxkSW50NjRWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBPdGhlciBtYXBzIHdpdGggYWxsIGtleSB0eXBlcyB0byB0ZXN0IHRoZSB1bmtub3duIGVudHJ5IHNlcmlhbGl6YXRpb24KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDY0ID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFVua25vd25NYXBGaWVsZEludDY0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkSW50NjRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEludDY0KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRVaW50NjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50NjQoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZFVpbnQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRVaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFVpbnQ2NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQ2NCgpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkVWludDY0XyA9PSBudWxsKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRVaW50NjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRVaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF1bmtub3duTWFwRmllbGRVaW50NjRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRVaW50NjRfID0gdW5rbm93bk1hcEZpZWxkVWludDY0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkVWludDY0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZFVpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQ2NCA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkVWludDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkVWludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCkgewogICAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRVaW50NjRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQ2NCA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgICBnZXRVbmtub3duTWFwRmllbGRVaW50NjRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFVpbnQ2NE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50NjQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQ2NCA9IDIwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFVpbnQ2NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkVWludDY0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50NjQgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRVaW50NjRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFVpbnQ2NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5rbm93bk1hcEZpZWxkVWludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRVaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50NjQgPSAyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVW5rbm93bk1hcEZpZWxkVWludDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgICAgIGdldE11dGFibGVVbmtub3duTWFwRmllbGRVaW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRVaW50NjRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRVaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDY0ID0gMjAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFVua25vd25NYXBGaWVsZFVpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB1bmtub3duTWFwRmllbGRVaW50NjRWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDY0ID0gMjAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFVua25vd25NYXBGaWVsZFVpbnQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFVpbnQ2NE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDY0KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRJbnQzMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDMyKCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRJbnQzMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRJbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkSW50MzJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQzMigpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkSW50MzJfID09IG51bGwpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZEludDMyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkSW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF1bmtub3duTWFwRmllbGRJbnQzMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZEludDMyXyA9IHVua25vd25NYXBGaWVsZEludDMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkSW50MzJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkSW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZEludDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZEludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkSW50MzIoKSB7CiAgICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZEludDMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDMyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgIGdldFVua25vd25NYXBGaWVsZEludDMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRJbnQzMk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRJbnQzMigpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9pbnQzMiA9IDIwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZEludDMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkSW50MzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRJbnQzMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEludDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEludDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVbmtub3duTWFwRmllbGRJbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ludDMyID0gMjAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVVua25vd25NYXBGaWVsZEludDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRJbnQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgICAgICBnZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRJbnQzMk1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEludDMyKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0VW5rbm93bk1hcEZpZWxkSW50MzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHVua25vd25NYXBGaWVsZEludDMyVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfaW50MzIgPSAyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsVW5rbm93bk1hcEZpZWxkSW50MzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRJbnQzMk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkSW50MzIoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHVua25vd25NYXBGaWVsZFVpbnQzMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQzMigpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkVWludDMyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZFVpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkVWludDMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDMyKCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRVaW50MzJfID09IG51bGwpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZFVpbnQzMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZFVpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXVua25vd25NYXBGaWVsZFVpbnQzMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZFVpbnQzMl8gPSB1bmtub3duTWFwRmllbGRVaW50MzJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRVaW50MzJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDMyID0gMjAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRVaW50MzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFVpbnQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFVpbnQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgIGdldFVua25vd25NYXBGaWVsZFVpbnQzMigpIHsKICAgICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50MzIgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkVWludDMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRVaW50MzJNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50MzIgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRVaW50MzJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkVWludDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF91aW50MzIgPSAyMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRVaW50MzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRVaW50MzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkVWludDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVbmtub3duTWFwRmllbGRVaW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQzMiA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVVbmtub3duTWFwRmllbGRVaW50MzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFVpbnQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgICAgICBnZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkVWludDMyTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3VpbnQzMiA9IDIwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRVbmtub3duTWFwRmllbGRVaW50MzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB1bmtub3duTWFwRmllbGRVaW50MzJWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfdWludDMyID0gMjAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFVua25vd25NYXBGaWVsZFVpbnQzMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFVpbnQzMk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkVWludDMyKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRGaXhlZDMyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkRml4ZWQzMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRGaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRGaXhlZDMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQzMigpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkRml4ZWQzMl8gPT0gbnVsbCkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkRml4ZWQzMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZEZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF1bmtub3duTWFwRmllbGRGaXhlZDMyXy5pc011dGFibGUoKSkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkRml4ZWQzMl8gPSB1bmtub3duTWFwRmllbGRGaXhlZDMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkRml4ZWQzMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDMyID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRGaXhlZDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgIGdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKSB7CiAgICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZEZpeGVkMzJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDMyID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgIGdldFVua25vd25NYXBGaWVsZEZpeGVkMzJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEZpeGVkMzJNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkMzIgPSAyMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRGaXhlZDMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRGaXhlZDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMiA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZEZpeGVkMzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEZpeGVkMzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVua25vd25NYXBGaWVsZEZpeGVkMzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMiA9IDIwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVVbmtub3duTWFwRmllbGRGaXhlZDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgICAgIGdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkRml4ZWQzMk1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkMzIgPSAyMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0VW5rbm93bk1hcEZpZWxkRml4ZWQzMigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB1bmtub3duTWFwRmllbGRGaXhlZDMyVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDMyID0gMjA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFVua25vd25NYXBGaWVsZEZpeGVkMzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRGaXhlZDMyTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRGaXhlZDY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkRml4ZWQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRGaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRGaXhlZDY0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkRml4ZWQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkRml4ZWQ2NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZEZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF1bmtub3duTWFwRmllbGRGaXhlZDY0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkRml4ZWQ2NF8gPSB1bmtub3duTWFwRmllbGRGaXhlZDY0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkRml4ZWQ2NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRGaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDY0ID0gMjA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRGaXhlZDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZEZpeGVkNjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgICBnZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCkgewogICAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRGaXhlZDY0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQ2NCA9IDIwNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgICBnZXRVbmtub3duTWFwRmllbGRGaXhlZDY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRGaXhlZDY0TWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDY0ID0gMjA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZEZpeGVkNjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDY0ID0gMjA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkRml4ZWQ2NE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEZpeGVkNjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVua25vd25NYXBGaWVsZEZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfZml4ZWQ2NCA9IDIwNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVVbmtub3duTWFwRmllbGRGaXhlZDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgICAgICBnZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEZpeGVkNjRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRGaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9maXhlZDY0ID0gMjA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFVua25vd25NYXBGaWVsZEZpeGVkNjQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHVua25vd25NYXBGaWVsZEZpeGVkNjRWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2ZpeGVkNjQgPSAyMDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEZpeGVkNjRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+IHVua25vd25NYXBGaWVsZEJvb2xfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRCb29sXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZEJvb2xEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZEJvb2xfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRCb29sKCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRCb29sXyA9PSBudWxsKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRCb29sXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkQm9vbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXVua25vd25NYXBGaWVsZEJvb2xfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRCb29sXyA9IHVua25vd25NYXBGaWVsZEJvb2xfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRCb29sXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZEJvb2xDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2Jvb2wgPSAyMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZEJvb2woCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkQm9vbE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgIGdldFVua25vd25NYXBGaWVsZEJvb2woKSB7CiAgICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZEJvb2xNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9ib29sID0gMjA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgIGdldFVua25vd25NYXBGaWVsZEJvb2xNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZEJvb2xNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2Jvb2wgPSAyMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRCb29sT3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRCb29sKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkQm9vbFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2Jvb2wgPSAyMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRCb29sT3JUaHJvdygKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZEJvb2woKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkQm9vbFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5rbm93bk1hcEZpZWxkQm9vbCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9ib29sID0gMjA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVVua25vd25NYXBGaWVsZEJvb2woCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRCb29sKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgICAgIGdldE11dGFibGVVbmtub3duTWFwRmllbGRCb29sKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkQm9vbE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZEJvb2woKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX2Jvb2wgPSAyMDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0VW5rbm93bk1hcEZpZWxkQm9vbCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdW5rbm93bk1hcEZpZWxkQm9vbFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfYm9vbCA9IDIwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxVbmtub3duTWFwRmllbGRCb29sKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkQm9vbE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkQm9vbCgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRTdHJpbmdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFN0cmluZygpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkU3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU3RyaW5nXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTdHJpbmcoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZFN0cmluZ18gPT0gbnVsbCkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkU3RyaW5nXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghdW5rbm93bk1hcEZpZWxkU3RyaW5nXy5pc011dGFibGUoKSkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkU3RyaW5nXyA9IHVua25vd25NYXBGaWVsZFN0cmluZ18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFN0cmluZ187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRTdHJpbmdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zdHJpbmcgPSAyMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgICBnZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZFN0cmluZ01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc3RyaW5nID0gMjA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTdHJpbmdNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zdHJpbmcgPSAyMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTdHJpbmdPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyB1bmtub3duTWFwRmllbGRTdHJpbmdWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3N0cmluZyA9IDIwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFN0cmluZ09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFN0cmluZ1ZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5rbm93bk1hcEZpZWxkU3RyaW5nKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zdHJpbmcgPSAyMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVW5rbm93bk1hcEZpZWxkU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgICAgICBnZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU3RyaW5nKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU3RyaW5nTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3N0cmluZyA9IDIwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRVbmtub3duTWFwRmllbGRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB1bmtub3duTWFwRmllbGRTdHJpbmdWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc3RyaW5nID0gMjA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFVua25vd25NYXBGaWVsZFN0cmluZygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU3RyaW5nTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHVua25vd25NYXBGaWVsZFNpbnQzMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkU2ludDMyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZFNpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ludDMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDMyKCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRTaW50MzJfID09IG51bGwpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZFNpbnQzMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZFNpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXVua25vd25NYXBGaWVsZFNpbnQzMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZFNpbnQzMl8gPSB1bmtub3duTWFwRmllbGRTaW50MzJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRTaW50MzJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDMyID0gMjA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNVbmtub3duTWFwRmllbGRTaW50MzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFNpbnQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgIGdldFVua25vd25NYXBGaWVsZFNpbnQzMigpIHsKICAgICAgICByZXR1cm4gZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50MzIgPSAyMDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTaW50MzJNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50MzIgPSAyMDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTaW50MzJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkU2ludDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50MzIgPSAyMDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTaW50MzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50MzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ludDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVbmtub3duTWFwRmllbGRTaW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQzMiA9IDIwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVVbmtub3duTWFwRmllbGRTaW50MzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgICAgICBnZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ludDMyTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDMyKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQzMiA9IDIwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRVbmtub3duTWFwRmllbGRTaW50MzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB1bmtub3duTWFwRmllbGRTaW50MzJWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDMyID0gMjA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFVua25vd25NYXBGaWVsZFNpbnQzMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFNpbnQzMk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDMyKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRTaW50NjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50NjQoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZFNpbnQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRTaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNpbnQ2NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNpbnQ2NCgpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkU2ludDY0XyA9PSBudWxsKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRTaW50NjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRTaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF1bmtub3duTWFwRmllbGRTaW50NjRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICB1bmtub3duTWFwRmllbGRTaW50NjRfID0gdW5rbm93bk1hcEZpZWxkU2ludDY0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ludDY0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldFVua25vd25NYXBGaWVsZFNpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNpbnQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQ2NCA9IDIwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkU2ludDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0VW5rbm93bk1hcEZpZWxkU2ludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkgewogICAgICAgIHJldHVybiBnZXRVbmtub3duTWFwRmllbGRTaW50NjRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQ2NCA9IDIwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPgogICAgICBnZXRVbmtub3duTWFwRmllbGRTaW50NjRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFNpbnQ2NE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTaW50NjQoKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NpbnQ2NCA9IDIwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFNpbnQ2NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkU2ludDY0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50NjQgPSAyMDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTaW50NjRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNpbnQ2NFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5rbm93bk1hcEZpZWxkU2ludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zaW50NjQgPSAyMDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVW5rbm93bk1hcEZpZWxkU2ludDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgICAgIGdldE11dGFibGVVbmtub3duTWFwRmllbGRTaW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTaW50NjRNYXAoCiAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDY0ID0gMjA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dFVua25vd25NYXBGaWVsZFNpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB1bmtub3duTWFwRmllbGRTaW50NjRWYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ludDY0ID0gMjA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFVua25vd25NYXBGaWVsZFNpbnQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZFVua25vd25NYXBGaWVsZFNpbnQ2NE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ludDY0KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB1bmtub3duTWFwRmllbGRTZml4ZWQzMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRTZml4ZWQzMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRTZml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTZml4ZWQzMigpIHsKICAgICAgICBpZiAodW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfID09IG51bGwpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZFNmaXhlZDMyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCF1bmtub3duTWFwRmllbGRTZml4ZWQzMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHVua25vd25NYXBGaWVsZFNmaXhlZDMyXyA9IHVua25vd25NYXBGaWVsZFNmaXhlZDMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkMzIgPSAyMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1Vua25vd25NYXBGaWVsZFNmaXhlZDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFNmaXhlZDMyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKSB7CiAgICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyID0gMjEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTZml4ZWQzMk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQzMiA9IDIxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICAgID8gdW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkMzIgPSAyMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQzMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHVua25vd25NYXBGaWVsZFNmaXhlZDMyVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVbmtub3duTWFwRmllbGRTZml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyID0gMjEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVVua25vd25NYXBGaWVsZFNmaXhlZDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTZml4ZWQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgICAgICBnZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTZml4ZWQzMk1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkMzIgPSAyMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0VW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHVua25vd25NYXBGaWVsZFNmaXhlZDMyVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkMzIgPSAyMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTZml4ZWQzMk1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkpCiAgICAgICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IHVua25vd25NYXBGaWVsZFNmaXhlZDY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKSB7CiAgICAgICAgaWYgKHVua25vd25NYXBGaWVsZFNmaXhlZDY0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIFVua25vd25NYXBGaWVsZFNmaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRTZml4ZWQ2NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkgewogICAgICAgIGlmICh1bmtub3duTWFwRmllbGRTZml4ZWQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBVbmtub3duTWFwRmllbGRTZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXVua25vd25NYXBGaWVsZFNmaXhlZDY0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRfID0gdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB1bmtub3duTWFwRmllbGRTZml4ZWQ2NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQ2NCA9IDIxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFVua25vd25NYXBGaWVsZFNmaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4KICAgICAgZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKSB7CiAgICAgICAgcmV0dXJuIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDY0ID0gMjExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTZml4ZWQ2NE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhJmd0OyB1bmtub3duX21hcF9maWVsZF9zZml4ZWQ2NCA9IDIxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGdldFVua25vd25NYXBGaWVsZFNmaXhlZDY0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5Qcm90bzJNYXBFbnVtUGx1c0V4dHJhIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IHVua25vd25NYXBGaWVsZFNmaXhlZDY0VmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDY0ID0gMjExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgZ2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkNjQgPSAyMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVVbmtub3duTWFwRmllbGRTZml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE+CiAgICAgICAgICBnZXRNdXRhYmxlVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRVbmtub3duTWFwRmllbGRTZml4ZWQ2NE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYSZndDsgdW5rbm93bl9tYXBfZmllbGRfc2ZpeGVkNjQgPSAyMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0VW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB1bmtub3duTWFwRmllbGRTZml4ZWQ2NFZhbHVlQ29udmVydGVyLmRvQmFja3dhcmQodmFsdWUpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmEmZ3Q7IHVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDY0ID0gMjExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbFVua25vd25NYXBGaWVsZFNmaXhlZDY0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRBZGFwdGVkVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRNYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVVua25vd25NYXBGaWVsZFNmaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmEpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmEgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RW51bU1hcFBsdXNFeHRyYT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0RW51bU1hcFBsdXNFeHRyYT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RFbnVtTWFwUGx1c0V4dHJhIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEVudW1NYXBQbHVzRXh0cmE+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEVudW1NYXBQbHVzRXh0cmE+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1c0V4dHJhIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEltcG9ydEVudW1NYXBPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXApCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bUZvck1hcCZndDsgaW1wb3J0X2VudW1fYW1wID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRJbXBvcnRFbnVtQW1wQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW1Gb3JNYXAmZ3Q7IGltcG9ydF9lbnVtX2FtcCA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zSW1wb3J0RW51bUFtcCgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0SW1wb3J0RW51bUFtcE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtRm9yTWFwPgogICAgZ2V0SW1wb3J0RW51bUFtcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bUZvck1hcCZndDsgaW1wb3J0X2VudW1fYW1wID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtRm9yTWFwPgogICAgZ2V0SW1wb3J0RW51bUFtcE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bUZvck1hcCZndDsgaW1wb3J0X2VudW1fYW1wID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtRm9yTWFwIGdldEltcG9ydEVudW1BbXBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bUZvck1hcCAgICAgICAgIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtRm9yTWFwJmd0OyBpbXBvcnRfZW51bV9hbXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW1Gb3JNYXAgZ2V0SW1wb3J0RW51bUFtcE9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbXBvcnRFbnVtTWFwfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEltcG9ydEVudW1NYXAgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXApCiAgICAgIFRlc3RJbXBvcnRFbnVtTWFwT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0SW1wb3J0RW51bU1hcC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0SW1wb3J0RW51bU1hcChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RJbXBvcnRFbnVtTWFwKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RJbXBvcnRFbnVtTWFwKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbXBvcnRFbnVtTWFwX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEltcG9ydEVudW1BbXAoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SW1wb3J0RW51bU1hcF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbXBvcnRFbnVtTWFwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTVBPUlRfRU5VTV9BTVBfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEltcG9ydEVudW1BbXBEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEltcG9ydEVudW1NYXBfSW1wb3J0RW51bUFtcEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtRm9yTWFwLlVOS05PV04uZ2V0TnVtYmVyKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBpbXBvcnRFbnVtQW1wXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldEltcG9ydEVudW1BbXAoKSB7CiAgICAgIGlmIChpbXBvcnRFbnVtQW1wXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgSW1wb3J0RW51bUFtcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBpbXBvcnRFbnVtQW1wXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bUZvck1hcD4gaW1wb3J0RW51bUFtcFZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bUZvck1hcC5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bUZvck1hcC5VTktOT1dOKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtRm9yTWFwPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkSW1wb3J0RW51bUFtcE1hcCgKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtRm9yTWFwLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBpbXBvcnRFbnVtQW1wVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRJbXBvcnRFbnVtQW1wQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEltcG9ydEVudW1BbXAoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtRm9yTWFwJmd0OyBpbXBvcnRfZW51bV9hbXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNJbXBvcnRFbnVtQW1wKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldEltcG9ydEVudW1BbXAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRJbXBvcnRFbnVtQW1wTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtRm9yTWFwPgogICAgZ2V0SW1wb3J0RW51bUFtcCgpIHsKICAgICAgcmV0dXJuIGdldEltcG9ydEVudW1BbXBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW1Gb3JNYXAmZ3Q7IGltcG9ydF9lbnVtX2FtcCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW1Gb3JNYXA+CiAgICBnZXRJbXBvcnRFbnVtQW1wTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkSW1wb3J0RW51bUFtcE1hcCgKICAgICAgICAgIGludGVybmFsR2V0SW1wb3J0RW51bUFtcCgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtRm9yTWFwJmd0OyBpbXBvcnRfZW51bV9hbXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtRm9yTWFwIGdldEltcG9ydEVudW1BbXBPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bUZvck1hcCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRJbXBvcnRFbnVtQW1wKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgPyBpbXBvcnRFbnVtQW1wVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bUZvck1hcCZndDsgaW1wb3J0X2VudW1fYW1wID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bUZvck1hcCBnZXRJbXBvcnRFbnVtQW1wT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0SW1wb3J0RW51bUFtcCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gaW1wb3J0RW51bUFtcFZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRJbXBvcnRFbnVtQW1wKCksCiAgICAgICAgICBJbXBvcnRFbnVtQW1wRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0SW1wb3J0RW51bUFtcCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBpbXBvcnRFbnVtQW1wX18gPSBJbXBvcnRFbnVtQW1wRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBpbXBvcnRFbnVtQW1wX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbXBvcnRFbnVtTWFwKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCkgb2JqOwoKICAgICAgaWYgKCFpbnRlcm5hbEdldEltcG9ydEVudW1BbXAoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEltcG9ydEVudW1BbXAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoIWludGVybmFsR2V0SW1wb3J0RW51bUFtcCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElNUE9SVF9FTlVNX0FNUF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRJbXBvcnRFbnVtQW1wKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbXBvcnRFbnVtTWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXAgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbXBvcnRFbnVtTWFwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbXBvcnRFbnVtTWFwKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbXBvcnRFbnVtTWFwT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SW1wb3J0RW51bU1hcF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEltcG9ydEVudW1BbXAoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVJbXBvcnRFbnVtQW1wKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEltcG9ydEVudW1NYXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbXBvcnRFbnVtTWFwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXAubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUltcG9ydEVudW1BbXAoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEltcG9ydEVudW1NYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbXBvcnRFbnVtTWFwIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbXBvcnRFbnVtTWFwIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbXBvcnRFbnVtTWFwIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmltcG9ydEVudW1BbXBfID0gaW50ZXJuYWxHZXRJbXBvcnRFbnVtQW1wKCk7CiAgICAgICAgICByZXN1bHQuaW1wb3J0RW51bUFtcF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbXBvcnRFbnVtTWFwKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlSW1wb3J0RW51bUFtcCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRJbXBvcnRFbnVtQW1wKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnl0ZXMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgaW1wb3J0RW51bUFtcF9fID0gSW1wb3J0RW51bUFtcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLnBhcnNlRnJvbShieXRlcyk7CiAgICAgICAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW1Gb3JNYXAuZm9yTnVtYmVyKGltcG9ydEVudW1BbXBfXy5nZXRWYWx1ZSgpKSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93bkxlbmd0aERlbGltaXRlZEZpZWxkKDEsIGJ5dGVzKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUltcG9ydEVudW1BbXAoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgICAgaW1wb3J0RW51bUFtcF9fLmdldEtleSgpLCBpbXBvcnRFbnVtQW1wX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGltcG9ydEVudW1BbXBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRJbXBvcnRFbnVtQW1wKCkgewogICAgICAgIGlmIChpbXBvcnRFbnVtQW1wXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEltcG9ydEVudW1BbXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGltcG9ydEVudW1BbXBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbXBvcnRFbnVtQW1wKCkgewogICAgICAgIGlmIChpbXBvcnRFbnVtQW1wXyA9PSBudWxsKSB7CiAgICAgICAgICBpbXBvcnRFbnVtQW1wXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgSW1wb3J0RW51bUFtcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWltcG9ydEVudW1BbXBfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBpbXBvcnRFbnVtQW1wXyA9IGltcG9ydEVudW1BbXBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBpbXBvcnRFbnVtQW1wXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEltcG9ydEVudW1BbXBDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRJbXBvcnRFbnVtQW1wKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bUZvck1hcCZndDsgaW1wb3J0X2VudW1fYW1wID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zSW1wb3J0RW51bUFtcCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0SW1wb3J0RW51bUFtcCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEltcG9ydEVudW1BbXBNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bUZvck1hcD4KICAgICAgZ2V0SW1wb3J0RW51bUFtcCgpIHsKICAgICAgICByZXR1cm4gZ2V0SW1wb3J0RW51bUFtcE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bUZvck1hcCZndDsgaW1wb3J0X2VudW1fYW1wID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bUZvck1hcD4KICAgICAgZ2V0SW1wb3J0RW51bUFtcE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkSW1wb3J0RW51bUFtcE1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRJbXBvcnRFbnVtQW1wKCkuZ2V0TWFwKCkpO30KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtRm9yTWFwJmd0OyBpbXBvcnRfZW51bV9hbXAgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtRm9yTWFwIGdldEltcG9ydEVudW1BbXBPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW1Gb3JNYXAgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEltcG9ydEVudW1BbXAoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBpbXBvcnRFbnVtQW1wVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtRm9yTWFwJmd0OyBpbXBvcnRfZW51bV9hbXAgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtRm9yTWFwIGdldEltcG9ydEVudW1BbXBPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRJbXBvcnRFbnVtQW1wKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGltcG9ydEVudW1BbXBWYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckltcG9ydEVudW1BbXAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUltcG9ydEVudW1BbXAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtRm9yTWFwJmd0OyBpbXBvcnRfZW51bV9hbXAgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUltcG9ydEVudW1BbXAoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUltcG9ydEVudW1BbXAoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bUZvck1hcD4KICAgICAgICAgIGdldE11dGFibGVJbXBvcnRFbnVtQW1wKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkSW1wb3J0RW51bUFtcE1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUltcG9ydEVudW1BbXAoKS5nZXRNdXRhYmxlTWFwKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bUZvck1hcCZndDsgaW1wb3J0X2VudW1fYW1wID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRJbXBvcnRFbnVtQW1wKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtRm9yTWFwIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbXBvcnRFbnVtQW1wKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBpbXBvcnRFbnVtQW1wVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW1Gb3JNYXAmZ3Q7IGltcG9ydF9lbnVtX2FtcCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsSW1wb3J0RW51bUFtcCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtRm9yTWFwPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRJbXBvcnRFbnVtQW1wTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVJbXBvcnRFbnVtQW1wKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXApCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEltcG9ydEVudW1NYXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0SW1wb3J0RW51bU1hcD4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0SW1wb3J0RW51bU1hcD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RJbXBvcnRFbnVtTWFwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEltcG9ydEVudW1NYXA+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEltcG9ydEVudW1NYXA+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbXBvcnRFbnVtTWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEludEludE1hcE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbSA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG0gPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc00oCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE0oKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbSA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE1NYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbSA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RJbnRJbnRNYXAgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCkKICAgICAgVGVzdEludEludE1hcE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdEludEludE1hcC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0SW50SW50TWFwKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdEludEludE1hcCgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0SW50SW50TWFwKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbnRJbnRNYXBfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TSgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbnRJbnRNYXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1fRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1EZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEludEludE1hcF9NRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldE0oKSB7CiAgICAgIGlmIChtXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TSgpIHsKICAgICAgcmV0dXJuIGdldE1NYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1NYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE0oKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1PckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG0gPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRNT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNKCksCiAgICAgICAgICBNRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBtX18gPSBNRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBtX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgb2JqOwoKICAgICAgaWYgKCFpbnRlcm5hbEdldE0oKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE0oKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoIWludGVybmFsR2V0TSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SW50SW50TWFwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TSgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU0oKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SW50SW50TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbnRJbnRNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5tXyA9IGludGVybmFsR2V0TSgpOwogICAgICAgICAgcmVzdWx0Lm1fLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIG1fXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbV9fLmdldEtleSgpLCBtX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TSgpIHsKICAgICAgICBpZiAobV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTSgpIHsKICAgICAgICBpZiAobV8gPT0gbnVsbCkgewogICAgICAgICAgbV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtXy5pc011dGFibGUoKSkgewogICAgICAgICAgbV8gPSBtXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc00oCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE0oKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE0oKSB7CiAgICAgICAgcmV0dXJuIGdldE1NYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1NYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE0oKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG0gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRNT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlTSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU0oKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG0gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE0oCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEludEludE1hcD4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0SW50SW50TWFwPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdEludEludE1hcCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RJbnRJbnRNYXA+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEludEludE1hcD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RNYXBzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXBzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9pbnQzMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TUludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9pbnQzMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTUludDMyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNSW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgZ2V0TUludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1faW50MzIgPSAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgIGdldE1JbnQzMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TUludDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TUludDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1faW50NjQgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1JbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1faW50NjQgPSAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01JbnQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1JbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICBnZXRNSW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgZ2V0TUludDY0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1faW50NjQgPSAyOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNSW50NjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TUludDY0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV91aW50MzIgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1VaW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV91aW50MzIgPSAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01VaW50MzIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1VaW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgZ2V0TVVpbnQzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV91aW50MzIgPSAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgIGdldE1VaW50MzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fdWludDMyID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVVpbnQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fdWludDMyID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVVpbnQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1VaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01VaW50NjQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNVWludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgIGdldE1VaW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICBnZXRNVWludDY0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1VaW50NjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNVWludDY0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1TaW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01TaW50MzIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1TaW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgZ2V0TVNpbnQzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgIGdldE1TaW50MzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ludDMyID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVNpbnQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ludDMyID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVNpbnQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1TaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01TaW50NjQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNU2ludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgIGdldE1TaW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICBnZXRNU2ludDY0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1TaW50NjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNU2ludDY0T3JUaHJvdygKICAgICAgICBsb25nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TUZpeGVkMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTUZpeGVkMzIoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1GaXhlZDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgIGdldE1GaXhlZDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICBnZXRNRml4ZWQzMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1GaXhlZDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1GaXhlZDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNRml4ZWQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNNRml4ZWQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1GaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgIGdldE1GaXhlZDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICBnZXRNRml4ZWQ2NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1GaXhlZDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNRml4ZWQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TVNmaXhlZDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTVNmaXhlZDMyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNU2ZpeGVkMzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgZ2V0TVNmaXhlZDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgIGdldE1TZml4ZWQzMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVNmaXhlZDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVNmaXhlZDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNU2ZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTVNmaXhlZDY0KAogICAgICAgIGxvbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TVNmaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgIGdldE1TZml4ZWQ2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgZ2V0TVNmaXhlZDY0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVNmaXhlZDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNU2ZpeGVkNjRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9ib29sID0gMTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TUJvb2xDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fYm9vbCA9IDExOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01Cb29sKAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TUJvb2xNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgZ2V0TUJvb2woKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2Jvb2wgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICBnZXRNQm9vbE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fYm9vbCA9IDExOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNQm9vbE9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9ib29sID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1Cb29sT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zdHJpbmcgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNU3RyaW5nQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc3RyaW5nID0gMTI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTVN0cmluZygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1TdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICBnZXRNU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3N0cmluZyA9IDEyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgZ2V0TVN0cmluZ01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zdHJpbmcgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVN0cmluZ09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3N0cmluZyA9IDEyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNU3RyaW5nT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVGVzdCBhbGwga2V5IHR5cGVzOiBzdHJpbmcsIHBsdXMgdGhlIG5vbi1mbG9hdGluZy1wb2ludCBzY2FsYXJzLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcHN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0TWFwcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwcykKICAgICAgVGVzdE1hcHNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RNYXBzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNYXBzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE1hcHMoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdE1hcHMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TUludDMyKCk7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TUludDY0KCk7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TVVpbnQzMigpOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1VaW50NjQoKTsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU2ludDMyKCk7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TVNpbnQ2NCgpOwogICAgICAgIGNhc2UgNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1GaXhlZDMyKCk7CiAgICAgICAgY2FzZSA4OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TUZpeGVkNjQoKTsKICAgICAgICBjYXNlIDk6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU2ZpeGVkMzIoKTsKICAgICAgICBjYXNlIDEwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TVNmaXhlZDY0KCk7CiAgICAgICAgY2FzZSAxMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1Cb29sKCk7CiAgICAgICAgY2FzZSAxMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1TdHJpbmcoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNSW50MzJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01JbnQzMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IG1JbnQzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICBpbnRlcm5hbEdldE1JbnQzMigpIHsKICAgICAgaWYgKG1JbnQzMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1JbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtSW50MzJfOwogICAgfQogICAgcHVibGljIGludCBnZXRNSW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TUludDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTUludDMyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1JbnQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1JbnQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNSW50MzIoKSB7CiAgICAgIHJldHVybiBnZXRNSW50MzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9pbnQzMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZ2V0TUludDMyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNSW50MzIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9pbnQzMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNSW50MzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TUludDMyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9pbnQzMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNSW50MzJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1JbnQzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1fSU5UNjRfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1JbnQ2NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTUludDY0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IG1JbnQ2NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICBpbnRlcm5hbEdldE1JbnQ2NCgpIHsKICAgICAgaWYgKG1JbnQ2NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1JbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtSW50NjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRNSW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TUludDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTUludDY0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNSW50NjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNSW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZ2V0TUludDY0KCkgewogICAgICByZXR1cm4gZ2V0TUludDY0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1faW50NjQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1JbnQ2NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TUludDY0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1faW50NjQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TUludDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNSW50NjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1JbnQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1JbnQ2NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1fVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNVWludDMyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NVWludDMyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IG1VaW50MzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgaW50ZXJuYWxHZXRNVWludDMyKCkgewogICAgICBpZiAobVVpbnQzMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1VaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbVVpbnQzMl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1VaW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TVVpbnQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fdWludDMyID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTVVpbnQzMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNVWludDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TVVpbnQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNVWludDMyKCkgewogICAgICByZXR1cm4gZ2V0TVVpbnQzMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV91aW50MzIgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1VaW50MzJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1VaW50MzIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fdWludDMyID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1VaW50MzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TVVpbnQzMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNVWludDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNVWludDMyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTV9VSU5UNjRfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1VaW50NjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01VaW50NjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IG1VaW50NjRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgaW50ZXJuYWxHZXRNVWludDY0KCkgewogICAgICBpZiAobVVpbnQ2NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1VaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbVVpbnQ2NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1VaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TVVpbnQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTVVpbnQ2NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TVVpbnQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1VaW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZ2V0TVVpbnQ2NCgpIHsKICAgICAgcmV0dXJuIGdldE1VaW50NjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNVWludDY0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNVWludDY0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNVWludDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNVWludDY0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1VaW50NjRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNVWludDY0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTV9TSU5UMzJfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1TaW50MzJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01TaW50MzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gbVNpbnQzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICBpbnRlcm5hbEdldE1TaW50MzIoKSB7CiAgICAgIGlmIChtU2ludDMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTVNpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtU2ludDMyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TVNpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU2ludDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNU2ludDMyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1TaW50MzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNU2ludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1TaW50MzIoKSB7CiAgICAgIHJldHVybiBnZXRNU2ludDMyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZ2V0TVNpbnQzMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TVNpbnQzMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVNpbnQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNU2ludDMyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ludDMyID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1TaW50MzJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1TaW50MzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNX1NJTlQ2NF9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTVNpbnQ2NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVNpbnQ2NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gbVNpbnQ2NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICBpbnRlcm5hbEdldE1TaW50NjQoKSB7CiAgICAgIGlmIChtU2ludDY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTVNpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtU2ludDY0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TVNpbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU2ludDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNU2ludDY0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU2ludDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TVNpbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNU2ludDY0KCkgewogICAgICByZXR1cm4gZ2V0TVNpbnQ2NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1TaW50NjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1TaW50NjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1TaW50NjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1TaW50NjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVNpbnQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1TaW50NjQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNX0ZJWEVEMzJfRklFTERfTlVNQkVSID0gNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1GaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NRml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gbUZpeGVkMzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgaW50ZXJuYWxHZXRNRml4ZWQzMigpIHsKICAgICAgaWYgKG1GaXhlZDMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTUZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbUZpeGVkMzJfOwogICAgfQogICAgcHVibGljIGludCBnZXRNRml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNRml4ZWQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNRml4ZWQzMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNRml4ZWQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1GaXhlZDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1GaXhlZDMyKCkgewogICAgICByZXR1cm4gZ2V0TUZpeGVkMzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1GaXhlZDMyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNRml4ZWQzMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNRml4ZWQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNRml4ZWQzMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1GaXhlZDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNRml4ZWQzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1fRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSA4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTUZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01GaXhlZDY0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gbUZpeGVkNjRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgaW50ZXJuYWxHZXRNRml4ZWQ2NCgpIHsKICAgICAgaWYgKG1GaXhlZDY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTUZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbUZpeGVkNjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRNRml4ZWQ2NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNRml4ZWQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNRml4ZWQ2NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TUZpeGVkNjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNRml4ZWQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNRml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuIGdldE1GaXhlZDY0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNRml4ZWQ2NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TUZpeGVkNjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TUZpeGVkNjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1GaXhlZDY0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TUZpeGVkNjRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNRml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1fU0ZJWEVEMzJfRklFTERfTlVNQkVSID0gOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1TZml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVNmaXhlZDMyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gbVNmaXhlZDMyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgIGludGVybmFsR2V0TVNmaXhlZDMyKCkgewogICAgICBpZiAobVNmaXhlZDMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTVNmaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1TZml4ZWQzMl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1TZml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU2ZpeGVkMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNU2ZpeGVkMzIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TVNmaXhlZDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TVNmaXhlZDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1TZml4ZWQzMigpIHsKICAgICAgcmV0dXJuIGdldE1TZml4ZWQzMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNU2ZpeGVkMzJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1TZml4ZWQzMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1TZml4ZWQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNU2ZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1TZml4ZWQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TVNmaXhlZDMyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTV9TRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSAxMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1TZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVNmaXhlZDY0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IG1TZml4ZWQ2NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICBpbnRlcm5hbEdldE1TZml4ZWQ2NCgpIHsKICAgICAgaWYgKG1TZml4ZWQ2NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1TZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtU2ZpeGVkNjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRNU2ZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TVNmaXhlZDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01TZml4ZWQ2NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TVNmaXhlZDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TVNmaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1TZml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuIGdldE1TZml4ZWQ2NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZ2V0TVNmaXhlZDY0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU2ZpeGVkNjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVNmaXhlZDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNU2ZpeGVkNjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNU2ZpeGVkNjRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNU2ZpeGVkNjQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNX0JPT0xfRklFTERfTlVNQkVSID0gMTE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNQm9vbERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTUJvb2xFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5CT09MLAogICAgICAgICAgICAgICAgICBmYWxzZSwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBtQm9vbF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICBpbnRlcm5hbEdldE1Cb29sKCkgewogICAgICBpZiAobUJvb2xfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNQm9vbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtQm9vbF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1Cb29sQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1Cb29sKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fYm9vbCA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNQm9vbCgKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TUJvb2woKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNQm9vbE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNQm9vbCgpIHsKICAgICAgcmV0dXJuIGdldE1Cb29sTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9ib29sID0gMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZ2V0TUJvb2xNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1Cb29sKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9ib29sID0gMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNQm9vbE9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TUJvb2woKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fYm9vbCA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TUJvb2xPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNQm9vbCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1fU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDEyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTVN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01TdHJpbmdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLk1FU1NBR0UsCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gbVN0cmluZ187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgIGludGVybmFsR2V0TVN0cmluZygpIHsKICAgICAgaWYgKG1TdHJpbmdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1TdHJpbmdfOwogICAgfQogICAgcHVibGljIGludCBnZXRNU3RyaW5nQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1TdHJpbmcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3N0cmluZyA9IDEyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNU3RyaW5nKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU3RyaW5nKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TVN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1TdHJpbmcoKSB7CiAgICAgIHJldHVybiBnZXRNU3RyaW5nTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3N0cmluZyA9IDEyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZ2V0TVN0cmluZ01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TVN0cmluZygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zdHJpbmcgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1TdHJpbmdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TVN0cmluZygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3N0cmluZyA9IDEyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVN0cmluZ09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TVN0cmluZygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNSW50MzIoKSwKICAgICAgICAgIE1JbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNSW50NjQoKSwKICAgICAgICAgIE1JbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAyKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNVWludDMyKCksCiAgICAgICAgICBNVWludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1VaW50NjQoKSwKICAgICAgICAgIE1VaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TVNpbnQzMigpLAogICAgICAgICAgTVNpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNU2ludDY0KCksCiAgICAgICAgICBNU2ludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1GaXhlZDMyKCksCiAgICAgICAgICBNRml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNRml4ZWQ2NCgpLAogICAgICAgICAgTUZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TVNmaXhlZDMyKCksCiAgICAgICAgICBNU2ZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TVNmaXhlZDY0KCksCiAgICAgICAgICBNU2ZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1Cb29sKCksCiAgICAgICAgICBNQm9vbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNU3RyaW5nKCksCiAgICAgICAgICBNU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEyKTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TUludDMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgbUludDMyX18gPSBNSW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIG1JbnQzMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1JbnQ2NCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgICAgIG1JbnQ2NF9fID0gTUludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBtSW50NjRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNVWludDMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgbVVpbnQzMl9fID0gTVVpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgbVVpbnQzMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1VaW50NjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgICAgICBtVWludDY0X18gPSBNVWludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBtVWludDY0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TVNpbnQzMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgICAgIG1TaW50MzJfXyA9IE1TaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIG1TaW50MzJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNU2ludDY0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgbVNpbnQ2NF9fID0gTVNpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNiwgbVNpbnQ2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1GaXhlZDMyKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgbUZpeGVkMzJfXyA9IE1GaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3LCBtRml4ZWQzMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1GaXhlZDY0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgbUZpeGVkNjRfXyA9IE1GaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg4LCBtRml4ZWQ2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1TZml4ZWQzMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgICAgIG1TZml4ZWQzMl9fID0gTVNmaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5LCBtU2ZpeGVkMzJfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNU2ZpeGVkNjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgICAgICBtU2ZpeGVkNjRfXyA9IE1TZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTAsIG1TZml4ZWQ2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1Cb29sKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgbUJvb2xfXyA9IE1Cb29sRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMSwgbUJvb2xfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1TdHJpbmcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgICAgIG1TdHJpbmdfXyA9IE1TdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyLCBtU3RyaW5nX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcyBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcykgb2JqOwoKICAgICAgaWYgKCFpbnRlcm5hbEdldE1JbnQzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TUludDMyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNSW50NjQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1JbnQ2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TVVpbnQzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TVVpbnQzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TVVpbnQ2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TVVpbnQ2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TVNpbnQzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TVNpbnQzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TVNpbnQ2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TVNpbnQ2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TUZpeGVkMzIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1GaXhlZDMyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNRml4ZWQ2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TUZpeGVkNjQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1TZml4ZWQzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TVNmaXhlZDMyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNU2ZpeGVkNjQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1TZml4ZWQ2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TUJvb2woKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1Cb29sKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNU3RyaW5nKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNU3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1JbnQzMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1fSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TUludDMyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0TUludDY0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTV9JTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNSW50NjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNVWludDMyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTV9VSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TVVpbnQzMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldE1VaW50NjQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNX1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNVWludDY0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0TVNpbnQzMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1fU0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1TaW50MzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNU2ludDY0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTV9TSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TVNpbnQ2NCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldE1GaXhlZDMyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTV9GSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1GaXhlZDMyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0TUZpeGVkNjQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNX0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TUZpeGVkNjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNU2ZpeGVkMzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNX1NGSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1TZml4ZWQzMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldE1TZml4ZWQ2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1fU0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TVNmaXhlZDY0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0TUJvb2woKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNX0JPT0xfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TUJvb2woKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNU3RyaW5nKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTV9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TVN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRlc3QgYWxsIGtleSB0eXBlczogc3RyaW5nLCBwbHVzIHRoZSBub24tZmxvYXRpbmctcG9pbnQgc2NhbGFycy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXBzfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcHMpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TUludDMyKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1JbnQ2NCgpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNVWludDMyKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1VaW50NjQoKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TVNpbnQzMigpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU2ludDY0KCk7CiAgICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1GaXhlZDMyKCk7CiAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1GaXhlZDY0KCk7CiAgICAgICAgICBjYXNlIDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1TZml4ZWQzMigpOwogICAgICAgICAgY2FzZSAxMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TVNmaXhlZDY0KCk7CiAgICAgICAgICBjYXNlIDExOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNQm9vbCgpOwogICAgICAgICAgY2FzZSAxMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TVN0cmluZygpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1JbnQzMigpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTUludDY0KCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNVWludDMyKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNVWludDY0KCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNU2ludDMyKCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNU2ludDY0KCk7CiAgICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNRml4ZWQzMigpOwogICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTUZpeGVkNjQoKTsKICAgICAgICAgIGNhc2UgOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1TZml4ZWQzMigpOwogICAgICAgICAgY2FzZSAxMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1TZml4ZWQ2NCgpOwogICAgICAgICAgY2FzZSAxMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1Cb29sKCk7CiAgICAgICAgICBjYXNlIDEyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTVN0cmluZygpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNSW50MzIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1JbnQ2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVVpbnQzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVVpbnQ2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVNpbnQzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVNpbnQ2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUZpeGVkMzIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1GaXhlZDY0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNU2ZpeGVkMzIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TZml4ZWQ2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUJvb2woKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TdHJpbmcoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1JbnQzMl8gPSBpbnRlcm5hbEdldE1JbnQzMigpLmJ1aWxkKE1JbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1JbnQ2NF8gPSBpbnRlcm5hbEdldE1JbnQ2NCgpLmJ1aWxkKE1JbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1VaW50MzJfID0gaW50ZXJuYWxHZXRNVWludDMyKCkuYnVpbGQoTVVpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1VaW50NjRfID0gaW50ZXJuYWxHZXRNVWludDY0KCkuYnVpbGQoTVVpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1TaW50MzJfID0gaW50ZXJuYWxHZXRNU2ludDMyKCkuYnVpbGQoTVNpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1TaW50NjRfID0gaW50ZXJuYWxHZXRNU2ludDY0KCkuYnVpbGQoTVNpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1GaXhlZDMyXyA9IGludGVybmFsR2V0TUZpeGVkMzIoKS5idWlsZChNRml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1GaXhlZDY0XyA9IGludGVybmFsR2V0TUZpeGVkNjQoKS5idWlsZChNRml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1TZml4ZWQzMl8gPSBpbnRlcm5hbEdldE1TZml4ZWQzMigpLmJ1aWxkKE1TZml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1TZml4ZWQ2NF8gPSBpbnRlcm5hbEdldE1TZml4ZWQ2NCgpLmJ1aWxkKE1TZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1Cb29sXyA9IGludGVybmFsR2V0TUJvb2woKS5idWlsZChNQm9vbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1TdHJpbmdfID0gaW50ZXJuYWxHZXRNU3RyaW5nKCkuYnVpbGQoTVN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUludDMyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1JbnQzMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUludDY0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1JbnQ2NCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVVpbnQzMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNVWludDMyKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNVWludDY0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1VaW50NjQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TaW50MzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TVNpbnQzMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVNpbnQ2NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNU2ludDY0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNRml4ZWQzMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNRml4ZWQzMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUZpeGVkNjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TUZpeGVkNjQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TZml4ZWQzMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNU2ZpeGVkMzIoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TZml4ZWQ2NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNU2ZpeGVkNjQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1Cb29sKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1Cb29sKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNU3RyaW5nKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1TdHJpbmcoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgICAgICAgICBtSW50MzJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1JbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNSW50MzIoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1JbnQzMl9fLmdldEtleSgpLCBtSW50MzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgICAgICAgICBtSW50NjRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1JbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNSW50NjQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1JbnQ2NF9fLmdldEtleSgpLCBtSW50NjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgICAgICAgICBtVWludDMyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNVWludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1VaW50MzIoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1VaW50MzJfXy5nZXRLZXkoKSwgbVVpbnQzMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgICAgICAgICAgICAgIG1VaW50NjRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1VaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVVpbnQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbVVpbnQ2NF9fLmdldEtleSgpLCBtVWludDY0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgICBjYXNlIDQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgICAgICAgICAgICAgbVNpbnQzMl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTVNpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNU2ludDMyKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtU2ludDMyX18uZ2V0S2V5KCksIG1TaW50MzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MgogICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgICAgICAgICBtU2ludDY0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNU2ludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TaW50NjQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1TaW50NjRfXy5nZXRLZXkoKSwgbVNpbnQ2NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgICAgICAgICAgICAgIG1GaXhlZDMyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNRml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNRml4ZWQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbUZpeGVkMzJfXy5nZXRLZXkoKSwgbUZpeGVkMzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1OAogICAgICAgICAgICAgIGNhc2UgNjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgICAgICAgICBtRml4ZWQ2NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTUZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUZpeGVkNjQoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1GaXhlZDY0X18uZ2V0S2V5KCksIG1GaXhlZDY0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjYKICAgICAgICAgICAgICBjYXNlIDc0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgICAgICAgICAgICAgbVNmaXhlZDMyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNU2ZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVNmaXhlZDMyKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtU2ZpeGVkMzJfXy5nZXRLZXkoKSwgbVNmaXhlZDMyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgICBjYXNlIDgyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgICAgICAgICAgICAgbVNmaXhlZDY0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNU2ZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVNmaXhlZDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtU2ZpeGVkNjRfXy5nZXRLZXkoKSwgbVNmaXhlZDY0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBjYXNlIDkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgICAgICAgICAgICAgbUJvb2xfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1Cb29sRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1Cb29sKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtQm9vbF9fLmdldEtleSgpLCBtQm9vbF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkwCiAgICAgICAgICAgICAgY2FzZSA5ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgICAgICAgICAgICAgbVN0cmluZ19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTVN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNU3RyaW5nKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtU3RyaW5nX18uZ2V0S2V5KCksIG1TdHJpbmdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5OAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNSW50MzJDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgYnVpbGQocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB7IHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIE1JbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNSW50MzJDb252ZXJ0ZXIgbUludDMyQ29udmVydGVyID0gbmV3IE1JbnQzMkNvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+IG1JbnQzMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TUludDMyKCkgewogICAgICAgIGlmIChtSW50MzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihtSW50MzJDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbUludDMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNSW50MzIoKSB7CiAgICAgICAgaWYgKG1JbnQzMl8gPT0gbnVsbCkgewogICAgICAgICAgbUludDMyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KG1JbnQzMkNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbUludDMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1JbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1JbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1faW50MzIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNSW50MzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1JbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNSW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNSW50MzIoKSB7CiAgICAgICAgcmV0dXJuIGdldE1JbnQzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNSW50MzJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TUludDMyKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1faW50MzIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TUludDMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1JbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtSW50MzJDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNSW50MzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVNSW50MzIoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1JbnQzMkNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTUludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNSW50MzIoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNSW50MzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1JbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgICBnZXRNdXRhYmxlTUludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTUludDMyKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNSW50MzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUludDMyKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNSW50MzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUludDMyKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1faW50MzIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXIgcHV0TUludDMyQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgaW50IGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVNSW50MzIoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgewogICAgICAgICAgZW50cnkgPSAoKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1JbnQ2NENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBidWlsZChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIHsgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gTUludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1JbnQ2NENvbnZlcnRlciBtSW50NjRDb252ZXJ0ZXIgPSBuZXcgTUludDY0Q29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4gbUludDY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNSW50NjQoKSB7CiAgICAgICAgaWYgKG1JbnQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KG1JbnQ2NENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtSW50NjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1JbnQ2NCgpIHsKICAgICAgICBpZiAobUludDY0XyA9PSBudWxsKSB7CiAgICAgICAgICBtSW50NjRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obUludDY0Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtSW50NjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TUludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TUludDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01JbnQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1JbnQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNSW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNSW50NjQoKSB7CiAgICAgICAgcmV0dXJuIGdldE1JbnQ2NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNSW50NjRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TUludDY0KCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1faW50NjQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TUludDY0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVNSW50NjQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbUludDY0Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1faW50NjQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TUludDY0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1JbnQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbUludDY0Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNSW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1JbnQ2NCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1faW50NjQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1JbnQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1JbnQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgICBnZXRNdXRhYmxlTUludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTUludDY0KCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNSW50NjQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1JbnQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTUludDY0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1JbnQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyIHB1dE1JbnQ2NEJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGxvbmcga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1JbnQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB7CiAgICAgICAgICBlbnRyeSA9ICgocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTVVpbnQzMkNvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBidWlsZChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIHsgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gTVVpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNVWludDMyQ29udmVydGVyIG1VaW50MzJDb252ZXJ0ZXIgPSBuZXcgTVVpbnQzMkNvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+IG1VaW50MzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE1VaW50MzIoKSB7CiAgICAgICAgaWYgKG1VaW50MzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihtVWludDMyQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1VaW50MzJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1VaW50MzIoKSB7CiAgICAgICAgaWYgKG1VaW50MzJfID09IG51bGwpIHsKICAgICAgICAgIG1VaW50MzJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obVVpbnQzMkNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbVVpbnQzMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNVWludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TVVpbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01VaW50MzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1VaW50MzIoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TVVpbnQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1VaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIGdldE1VaW50MzJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fdWludDMyID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNVWludDMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1VaW50MzIoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fdWludDMyID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1VaW50MzJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTVVpbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtVWludDMyQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNVWludDMyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTVVpbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbVVpbnQzMkNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTVVpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVVpbnQzMigpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTVVpbnQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVVpbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgICBnZXRNdXRhYmxlTVVpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1VaW50MzIoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TVVpbnQzMigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNVWludDMyKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV91aW50MzIgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1VaW50MzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVVpbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV91aW50MzIgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXIgcHV0TVVpbnQzMkJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTVVpbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB7CiAgICAgICAgICBlbnRyeSA9ICgocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTVVpbnQ2NENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBidWlsZChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIHsgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gTVVpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNVWludDY0Q29udmVydGVyIG1VaW50NjRDb252ZXJ0ZXIgPSBuZXcgTVVpbnQ2NENvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+IG1VaW50NjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE1VaW50NjQoKSB7CiAgICAgICAgaWYgKG1VaW50NjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihtVWludDY0Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1VaW50NjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1VaW50NjQoKSB7CiAgICAgICAgaWYgKG1VaW50NjRfID09IG51bGwpIHsKICAgICAgICAgIG1VaW50NjRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obVVpbnQ2NENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbVVpbnQ2NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNVWludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TVVpbnQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01VaW50NjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNVWludDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1VaW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNVWludDY0KCkgewogICAgICAgIHJldHVybiBnZXRNVWludDY0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZ2V0TVVpbnQ2NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNVWludDY0KCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNVWludDY0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVNVWludDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1VaW50NjRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fdWludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1VaW50NjRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTVVpbnQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbVVpbnQ2NENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTVVpbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVVpbnQ2NCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTVVpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1VaW50NjQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgICAgICAgZ2V0TXV0YWJsZU1VaW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNVWludDY0KCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV91aW50NjQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1VaW50NjQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1VaW50NjQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTVVpbnQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNVWludDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlciBwdXRNVWludDY0QnVpbGRlcklmQWJzZW50KAogICAgICAgICAgbG9uZyBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTVVpbnQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB7CiAgICAgICAgICBlbnRyeSA9ICgocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTVNpbnQzMkNvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBidWlsZChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIHsgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gTVNpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNU2ludDMyQ29udmVydGVyIG1TaW50MzJDb252ZXJ0ZXIgPSBuZXcgTVNpbnQzMkNvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+IG1TaW50MzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE1TaW50MzIoKSB7CiAgICAgICAgaWYgKG1TaW50MzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihtU2ludDMyQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1TaW50MzJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TaW50MzIoKSB7CiAgICAgICAgaWYgKG1TaW50MzJfID09IG51bGwpIHsKICAgICAgICAgIG1TaW50MzJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obVNpbnQzMkNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbVNpbnQzMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNU2ludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TVNpbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01TaW50MzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1TaW50MzIoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TVNpbnQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1TaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIGdldE1TaW50MzJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNU2ludDMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1TaW50MzIoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1TaW50MzJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTVNpbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtU2ludDMyQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNU2ludDMyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTVNpbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbVNpbnQzMkNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTVNpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVNpbnQzMigpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTVNpbnQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVNpbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgICBnZXRNdXRhYmxlTVNpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1TaW50MzIoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TVNpbnQzMigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNU2ludDMyKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50MzIgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1TaW50MzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVNpbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50MzIgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXIgcHV0TVNpbnQzMkJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTVNpbnQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB7CiAgICAgICAgICBlbnRyeSA9ICgocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTVNpbnQ2NENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBidWlsZChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIHsgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gTVNpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNU2ludDY0Q29udmVydGVyIG1TaW50NjRDb252ZXJ0ZXIgPSBuZXcgTVNpbnQ2NENvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+IG1TaW50NjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE1TaW50NjQoKSB7CiAgICAgICAgaWYgKG1TaW50NjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihtU2ludDY0Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1TaW50NjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TaW50NjQoKSB7CiAgICAgICAgaWYgKG1TaW50NjRfID09IG51bGwpIHsKICAgICAgICAgIG1TaW50NjRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obVNpbnQ2NENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbVNpbnQ2NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNU2ludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TVNpbnQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01TaW50NjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU2ludDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1TaW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNU2ludDY0KCkgewogICAgICAgIHJldHVybiBnZXRNU2ludDY0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZ2V0TVNpbnQ2NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU2ludDY0KCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNU2ludDY0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVNU2ludDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1TaW50NjRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1TaW50NjRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTVNpbnQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbVNpbnQ2NENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTVNpbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVNpbnQ2NCgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTVNpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TaW50NjQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgICAgICAgZ2V0TXV0YWJsZU1TaW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNU2ludDY0KCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zaW50NjQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1TaW50NjQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TaW50NjQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTVNpbnQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNU2ludDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlciBwdXRNU2ludDY0QnVpbGRlcklmQWJzZW50KAogICAgICAgICAgbG9uZyBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTVNpbnQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB7CiAgICAgICAgICBlbnRyeSA9ICgocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTUZpeGVkMzJDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgYnVpbGQocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB7IHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIE1GaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1GaXhlZDMyQ29udmVydGVyIG1GaXhlZDMyQ29udmVydGVyID0gbmV3IE1GaXhlZDMyQ29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4gbUZpeGVkMzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE1GaXhlZDMyKCkgewogICAgICAgIGlmIChtRml4ZWQzMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KG1GaXhlZDMyQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1GaXhlZDMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNRml4ZWQzMigpIHsKICAgICAgICBpZiAobUZpeGVkMzJfID09IG51bGwpIHsKICAgICAgICAgIG1GaXhlZDMyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KG1GaXhlZDMyQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtRml4ZWQzMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNRml4ZWQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1GaXhlZDMyKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNRml4ZWQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TUZpeGVkMzIoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TUZpeGVkMzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNRml4ZWQzMigpIHsKICAgICAgICByZXR1cm4gZ2V0TUZpeGVkMzJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1GaXhlZDMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1GaXhlZDMyKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1GaXhlZDMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1GaXhlZDMyKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1GaXhlZDMyQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1GaXhlZDMyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTUZpeGVkMzIoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1GaXhlZDMyQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNRml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUZpeGVkMzIoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTUZpeGVkMzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1GaXhlZDMyKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgICAgICAgIGdldE11dGFibGVNRml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1GaXhlZDMyKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TUZpeGVkMzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUZpeGVkMzIoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNRml4ZWQzMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNRml4ZWQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlciBwdXRNRml4ZWQzMkJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTUZpeGVkMzIoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgewogICAgICAgICAgZW50cnkgPSAoKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1GaXhlZDY0Q29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGJ1aWxkKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgeyByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBNRml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNRml4ZWQ2NENvbnZlcnRlciBtRml4ZWQ2NENvbnZlcnRlciA9IG5ldyBNRml4ZWQ2NENvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+IG1GaXhlZDY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNRml4ZWQ2NCgpIHsKICAgICAgICBpZiAobUZpeGVkNjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihtRml4ZWQ2NENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtRml4ZWQ2NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUZpeGVkNjQoKSB7CiAgICAgICAgaWYgKG1GaXhlZDY0XyA9PSBudWxsKSB7CiAgICAgICAgICBtRml4ZWQ2NF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihtRml4ZWQ2NENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbUZpeGVkNjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TUZpeGVkNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNRml4ZWQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTUZpeGVkNjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNRml4ZWQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNRml4ZWQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1GaXhlZDY0KCkgewogICAgICAgIHJldHVybiBnZXRNRml4ZWQ2NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZ2V0TUZpeGVkNjRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TUZpeGVkNjQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TUZpeGVkNjRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1GaXhlZDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1GaXhlZDY0Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1GaXhlZDY0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1GaXhlZDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtRml4ZWQ2NENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTUZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1GaXhlZDY0KCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1GaXhlZDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUZpeGVkNjQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgICAgICAgZ2V0TXV0YWJsZU1GaXhlZDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTUZpeGVkNjQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNRml4ZWQ2NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUZpeGVkNjQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNRml4ZWQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNRml4ZWQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlciBwdXRNRml4ZWQ2NEJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGxvbmcga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1GaXhlZDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIHsKICAgICAgICAgIGVudHJ5ID0gKChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNU2ZpeGVkMzJDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgYnVpbGQocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB7IHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIE1TZml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNU2ZpeGVkMzJDb252ZXJ0ZXIgbVNmaXhlZDMyQ29udmVydGVyID0gbmV3IE1TZml4ZWQzMkNvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+IG1TZml4ZWQzMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TVNmaXhlZDMyKCkgewogICAgICAgIGlmIChtU2ZpeGVkMzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihtU2ZpeGVkMzJDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbVNmaXhlZDMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNU2ZpeGVkMzIoKSB7CiAgICAgICAgaWYgKG1TZml4ZWQzMl8gPT0gbnVsbCkgewogICAgICAgICAgbVNmaXhlZDMyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KG1TZml4ZWQzMkNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbVNmaXhlZDMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1TZml4ZWQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1TZml4ZWQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNU2ZpeGVkMzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1TZml4ZWQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNU2ZpeGVkMzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNU2ZpeGVkMzIoKSB7CiAgICAgICAgcmV0dXJuIGdldE1TZml4ZWQzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNU2ZpeGVkMzJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TVNmaXhlZDMyKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVNmaXhlZDMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1TZml4ZWQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtU2ZpeGVkMzJDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNU2ZpeGVkMzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVNU2ZpeGVkMzIoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1TZml4ZWQzMkNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTVNmaXhlZDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNU2ZpeGVkMzIoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNU2ZpeGVkMzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TZml4ZWQzMigpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgICBnZXRNdXRhYmxlTVNmaXhlZDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTVNmaXhlZDMyKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNU2ZpeGVkMzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVNmaXhlZDMyKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNU2ZpeGVkMzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVNmaXhlZDMyKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXIgcHV0TVNmaXhlZDMyQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgaW50IGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVNU2ZpeGVkMzIoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgewogICAgICAgICAgZW50cnkgPSAoKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1TZml4ZWQ2NENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBidWlsZChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIHsgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gTVNmaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1TZml4ZWQ2NENvbnZlcnRlciBtU2ZpeGVkNjRDb252ZXJ0ZXIgPSBuZXcgTVNmaXhlZDY0Q29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4gbVNmaXhlZDY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNU2ZpeGVkNjQoKSB7CiAgICAgICAgaWYgKG1TZml4ZWQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KG1TZml4ZWQ2NENvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtU2ZpeGVkNjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TZml4ZWQ2NCgpIHsKICAgICAgICBpZiAobVNmaXhlZDY0XyA9PSBudWxsKSB7CiAgICAgICAgICBtU2ZpeGVkNjRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obVNmaXhlZDY0Q29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtU2ZpeGVkNjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TVNmaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TVNmaXhlZDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNU2ZpeGVkNjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU2ZpeGVkNjQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TVNmaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZ2V0TVNmaXhlZDY0KCkgewogICAgICAgIHJldHVybiBnZXRNU2ZpeGVkNjRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1TZml4ZWQ2NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU2ZpeGVkNjQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVNmaXhlZDY0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVNU2ZpeGVkNjQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbVNmaXhlZDY0Q29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1TZml4ZWQ2NE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVNU2ZpeGVkNjQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1TZml4ZWQ2NENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTVNmaXhlZDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNU2ZpeGVkNjQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTVNmaXhlZDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVNmaXhlZDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4KICAgICAgICAgIGdldE11dGFibGVNU2ZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNU2ZpeGVkNjQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNU2ZpeGVkNjQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TZml4ZWQ2NCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1TZml4ZWQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNU2ZpeGVkNjQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXIgcHV0TVNmaXhlZDY0QnVpbGRlcklmQWJzZW50KAogICAgICAgICAgbG9uZyBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTVNmaXhlZDY0KCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIHsKICAgICAgICAgIGVudHJ5ID0gKChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNQm9vbENvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuQm9vbGVhbiwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBidWlsZChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIHsgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gTUJvb2xEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTUJvb2xDb252ZXJ0ZXIgbUJvb2xDb252ZXJ0ZXIgPSBuZXcgTUJvb2xDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyPiBtQm9vbF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TUJvb2woKSB7CiAgICAgICAgaWYgKG1Cb29sXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obUJvb2xDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbUJvb2xfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkJvb2xlYW4sIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1Cb29sKCkgewogICAgICAgIGlmIChtQm9vbF8gPT0gbnVsbCkgewogICAgICAgICAgbUJvb2xfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obUJvb2xDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1Cb29sXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1Cb29sQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TUJvb2woKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fYm9vbCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNQm9vbCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1Cb29sKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1Cb29sTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZ2V0TUJvb2woKSB7CiAgICAgICAgcmV0dXJuIGdldE1Cb29sTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9ib29sID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gZ2V0TUJvb2xNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TUJvb2woKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX2Jvb2wgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGdldE1Cb29sT3JEZWZhdWx0KAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVNQm9vbCgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtQm9vbENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fYm9vbCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TUJvb2xPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTUJvb2woKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1Cb29sQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNQm9vbCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUJvb2woKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fYm9vbCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1Cb29sKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTUJvb2woKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPgogICAgICAgICAgZ2V0TXV0YWJsZU1Cb29sKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTUJvb2woKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9ib29sID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TUJvb2woCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1Cb29sKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fYm9vbCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1Cb29sKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1Cb29sKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9ib29sID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlciBwdXRNQm9vbEJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1Cb29sKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIHsKICAgICAgICAgIGVudHJ5ID0gKChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNU3RyaW5nQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgYnVpbGQocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwKSB7IHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gTVN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNU3RyaW5nQ29udmVydGVyIG1TdHJpbmdDb252ZXJ0ZXIgPSBuZXcgTVN0cmluZ0NvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4gbVN0cmluZ187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNU3RyaW5nKCkgewogICAgICAgIGlmIChtU3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obVN0cmluZ0NvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtU3RyaW5nXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXBPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TdHJpbmcoKSB7CiAgICAgICAgaWYgKG1TdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIG1TdHJpbmdfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obVN0cmluZ0NvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbVN0cmluZ187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNU3RyaW5nQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TVN0cmluZygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3N0cmluZyA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNU3RyaW5nKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1TdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGdldE1TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIGdldE1TdHJpbmdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc3RyaW5nID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwPiBnZXRNU3RyaW5nTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1TdHJpbmcoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc3RyaW5nID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCBnZXRNU3RyaW5nT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0SW50SW50TWFwIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTVN0cmluZygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtU3RyaW5nQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3N0cmluZyA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgZ2V0TVN0cmluZ09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTVN0cmluZygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbVN0cmluZ0NvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTVN0cmluZygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVN0cmluZygpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3N0cmluZyA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1TdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1TdHJpbmcoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+CiAgICAgICAgICBnZXRNdXRhYmxlTVN0cmluZygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1TdHJpbmcoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TWFwJmd0OyBtX3N0cmluZyA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1TdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVN0cmluZygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYXAmZ3Q7IG1fc3RyaW5nID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTVN0cmluZygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcD4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXA+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTVN0cmluZygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEludEludE1hcCZndDsgbV9zdHJpbmcgPSAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5CdWlsZGVyIHB1dE1TdHJpbmdCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1TdHJpbmcoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcE9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcC5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdEludEludE1hcCkgewogICAgICAgICAgZW50cnkgPSAoKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXApIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RJbnRJbnRNYXAuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcHMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXBzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1hcHM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdE1hcHM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TWFwcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNYXBzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNYXBzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RTdWJtZXNzYWdlTWFwc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcHMgbSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNNKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwcyBtID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcyBnZXRNKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwcyBtID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzT3JCdWlsZGVyIGdldE1PckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUZXN0IG1hcHMgaW4gc3VibWVzc2FnZXMuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0U3VibWVzc2FnZU1hcHMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFN1Ym1lc3NhZ2VNYXBzKQogICAgICBUZXN0U3VibWVzc2FnZU1hcHNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RTdWJtZXNzYWdlTWFwcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0U3VibWVzc2FnZU1hcHMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0U3VibWVzc2FnZU1hcHMoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFN1Ym1lc3NhZ2VNYXBzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RTdWJtZXNzYWdlTWFwc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0U3VibWVzc2FnZU1hcHNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcyBtXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXBzIG0gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc00oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXBzIG0gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcyBnZXRNKCkgewogICAgICByZXR1cm4gbV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwcyBtID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwc09yQnVpbGRlciBnZXRNT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gbV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbV87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEsIGdldE0oKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRNKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFN1Ym1lc3NhZ2VNYXBzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcykgb2JqOwoKICAgICAgaWYgKGhhc00oKSAhPSBvdGhlci5oYXNNKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc00oKSkgewogICAgICAgIGlmICghZ2V0TSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc00oKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE0oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFN1Ym1lc3NhZ2VNYXBzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFN1Ym1lc3NhZ2VNYXBzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFN1Ym1lc3NhZ2VNYXBzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFN1Ym1lc3NhZ2VNYXBzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFN1Ym1lc3NhZ2VNYXBzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdCBtYXBzIGluIHN1Ym1lc3NhZ2VzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFN1Ym1lc3NhZ2VNYXBzfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFN1Ym1lc3NhZ2VNYXBzKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFN1Ym1lc3NhZ2VNYXBzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0U3VibWVzc2FnZU1hcHNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFN1Ym1lc3NhZ2VNYXBzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0TUZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgbV8gPSBudWxsOwogICAgICAgIGlmIChtQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG1CdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFN1Ym1lc3NhZ2VNYXBzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcyBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcyByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFN1Ym1lc3NhZ2VNYXBzKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5tXyA9IG1CdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBtXwogICAgICAgICAgICAgIDogbUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFN1Ym1lc3NhZ2VNYXBzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzTSgpKSB7CiAgICAgICAgICBtZXJnZU0ob3RoZXIuZ2V0TSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0TUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcyBtXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzT3JCdWlsZGVyPiBtQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcHMgbSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG0gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwcyBtID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG0uCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMgZ2V0TSgpIHsKICAgICAgICBpZiAobUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBtXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1CdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcHMgbSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TShwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcyB2YWx1ZSkgewogICAgICAgIGlmIChtQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBtXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXBzIG0gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE0oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChtQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwcyBtID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU0ocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMgdmFsdWUpIHsKICAgICAgICBpZiAobUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBtXyAhPSBudWxsICYmCiAgICAgICAgICAgIG1fICE9IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE1CdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1fID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1CdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAobV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcHMgbSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBtXyA9IG51bGw7CiAgICAgICAgaWYgKG1CdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBtQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgbUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwcyBtID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMuQnVpbGRlciBnZXRNQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE1GaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwcyBtID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHNPckJ1aWxkZXIgZ2V0TU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAobUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBtQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwcyBtID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcywgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdE1hcHNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0TUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAobUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1CdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RNYXBzLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0TWFwc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE0oKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG1fID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1CdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RTdWJtZXNzYWdlTWFwcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RTdWJtZXNzYWdlTWFwcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0U3VibWVzc2FnZU1hcHM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0U3VibWVzc2FnZU1hcHMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0U3VibWVzc2FnZU1hcHM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFN1Ym1lc3NhZ2VNYXBzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0U3VibWVzc2FnZU1hcHMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0UHJvdG8yQnl0ZXNNYXBPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvMkJ5dGVzTWFwKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2J5dGVzID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBCeXRlc0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9ieXRlcyA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwQnl0ZXMoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEJ5dGVzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgZ2V0TWFwQnl0ZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2J5dGVzID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldE1hcEJ5dGVzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9ieXRlcyA9IDE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0TWFwQnl0ZXNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2J5dGVzID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRNYXBCeXRlc09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgbWFwX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwU3RyaW5nQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmcgPSAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcFN0cmluZygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwU3RyaW5nTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldE1hcFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgbWFwX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0TWFwU3RyaW5nTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBtYXBfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0TWFwU3RyaW5nT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgbWFwX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE1hcFN0cmluZ09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RQcm90bzJCeXRlc01hcCBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXApCiAgICAgIFRlc3RQcm90bzJCeXRlc01hcE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFByb3RvMkJ5dGVzTWFwLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RQcm90bzJCeXRlc01hcChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RQcm90bzJCeXRlc01hcCgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0UHJvdG8yQnl0ZXNNYXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvMkJ5dGVzTWFwX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEJ5dGVzKCk7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU3RyaW5nKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvMkJ5dGVzTWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFByb3RvMkJ5dGVzTWFwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0JZVEVTX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBCeXRlc0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzJCeXRlc01hcF9NYXBCeXRlc0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJZVEVTLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwQnl0ZXNfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBpbnRlcm5hbEdldE1hcEJ5dGVzKCkgewogICAgICBpZiAobWFwQnl0ZXNfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNYXBCeXRlc0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtYXBCeXRlc187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcEJ5dGVzQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEJ5dGVzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfYnl0ZXMgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBCeXRlcygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBCeXRlcygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEJ5dGVzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0TWFwQnl0ZXMoKSB7CiAgICAgIHJldHVybiBnZXRNYXBCeXRlc01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfYnl0ZXMgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0TWFwQnl0ZXNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEJ5dGVzKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9ieXRlcyA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE1hcEJ5dGVzT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBCeXRlcygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9ieXRlcyA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE1hcEJ5dGVzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEJ5dGVzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX1NUUklOR19GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8yQnl0ZXNNYXBfTWFwU3RyaW5nRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwU3RyaW5nXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0TWFwU3RyaW5nKCkgewogICAgICBpZiAobWFwU3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcFN0cmluZ187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcFN0cmluZ0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTdHJpbmcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBtYXBfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwU3RyaW5nKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFN0cmluZygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNYXBTdHJpbmcoKSB7CiAgICAgIHJldHVybiBnZXRNYXBTdHJpbmdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmcgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldE1hcFN0cmluZ01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBtYXBfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldE1hcFN0cmluZ09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgbWFwX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRNYXBTdHJpbmdPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFN0cmluZygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBCeXRlcygpLAogICAgICAgICAgTWFwQnl0ZXNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwU3RyaW5nKCksCiAgICAgICAgICBNYXBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMik7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwQnl0ZXMoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgIG1hcEJ5dGVzX18gPSBNYXBCeXRlc0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgbWFwQnl0ZXNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBTdHJpbmcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBtYXBTdHJpbmdfXyA9IE1hcFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgbWFwU3RyaW5nX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFByb3RvMkJ5dGVzTWFwIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCkgb2JqOwoKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcEJ5dGVzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBCeXRlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwU3RyaW5nKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBTdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwQnl0ZXMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfQllURVNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TWFwQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBTdHJpbmcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcFN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFByb3RvMkJ5dGVzTWFwIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFByb3RvMkJ5dGVzTWFwIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFByb3RvMkJ5dGVzTWFwIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXBPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzJCeXRlc01hcF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEJ5dGVzKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFN0cmluZygpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEJ5dGVzKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmcoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8yQnl0ZXNNYXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFByb3RvMkJ5dGVzTWFwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEJ5dGVzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmcoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvMkJ5dGVzTWFwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFByb3RvMkJ5dGVzTWFwKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEJ5dGVzXyA9IGludGVybmFsR2V0TWFwQnl0ZXMoKTsKICAgICAgICAgIHJlc3VsdC5tYXBCeXRlc18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFN0cmluZ18gPSBpbnRlcm5hbEdldE1hcFN0cmluZygpOwogICAgICAgICAgcmVzdWx0Lm1hcFN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFByb3RvMkJ5dGVzTWFwKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFByb3RvMlVuaXR0ZXN0LlRlc3RQcm90bzJCeXRlc01hcCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEJ5dGVzKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEJ5dGVzKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmcoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwU3RyaW5nKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBtYXBCeXRlc19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwQnl0ZXNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwQnl0ZXMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcEJ5dGVzX18uZ2V0S2V5KCksIG1hcEJ5dGVzX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgICAgICAgbWFwU3RyaW5nX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBTdHJpbmdfXy5nZXRLZXkoKSwgbWFwU3RyaW5nX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwQnl0ZXNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TWFwQnl0ZXMoKSB7CiAgICAgICAgaWYgKG1hcEJ5dGVzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEJ5dGVzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBCeXRlc187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBCeXRlcygpIHsKICAgICAgICBpZiAobWFwQnl0ZXNfID09IG51bGwpIHsKICAgICAgICAgIG1hcEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwQnl0ZXNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtYXBCeXRlc18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG1hcEJ5dGVzXyA9IG1hcEJ5dGVzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwQnl0ZXNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwQnl0ZXNDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBCeXRlcygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2J5dGVzID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwQnl0ZXMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEJ5dGVzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwQnl0ZXNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldE1hcEJ5dGVzKCkgewogICAgICAgIHJldHVybiBnZXRNYXBCeXRlc01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfYnl0ZXMgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0TWFwQnl0ZXNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwQnl0ZXMoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2J5dGVzID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0TWFwQnl0ZXNPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwQnl0ZXMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9ieXRlcyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE1hcEJ5dGVzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEJ5dGVzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcEJ5dGVzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBCeXRlcygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2J5dGVzID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBCeXRlcygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwQnl0ZXMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwQnl0ZXMoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBCeXRlcygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2J5dGVzID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBCeXRlcygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEJ5dGVzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfYnl0ZXMgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcEJ5dGVzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBCeXRlcygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gbWFwU3RyaW5nXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTdHJpbmcoKSB7CiAgICAgICAgaWYgKG1hcFN0cmluZ18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcFN0cmluZ187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nKCkgewogICAgICAgIGlmIChtYXBTdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIG1hcFN0cmluZ18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE1hcFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW1hcFN0cmluZ18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG1hcFN0cmluZ18gPSBtYXBTdHJpbmdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtYXBTdHJpbmdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwU3RyaW5nQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU3RyaW5nKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgbWFwX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcFN0cmluZygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU3RyaW5nKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwU3RyaW5nTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gZ2V0TWFwU3RyaW5nKCkgewogICAgICAgIHJldHVybiBnZXRNYXBTdHJpbmdNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IGdldE1hcFN0cmluZ01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0TWFwU3RyaW5nT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgbWFwX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRNYXBTdHJpbmdPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcFN0cmluZygpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNYXBTdHJpbmcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFN0cmluZygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcFN0cmluZygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVNYXBTdHJpbmcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgc3RyaW5nJmd0OyBtYXBfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBTdHJpbmcoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIHN0cmluZyZndDsgbWFwX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwU3RyaW5nKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvMkJ5dGVzTWFwKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXApCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFByb3RvMkJ5dGVzTWFwKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBQcm90bzJVbml0dGVzdC5UZXN0UHJvdG8yQnl0ZXNNYXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UHJvdG8yQnl0ZXNNYXA+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFByb3RvMkJ5dGVzTWFwPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdFByb3RvMkJ5dGVzTWFwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFByb3RvMkJ5dGVzTWFwPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQcm90bzJCeXRlc01hcD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwUHJvdG8yVW5pdHRlc3QuVGVzdFByb3RvMkJ5dGVzTWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Lbm93bk1hcEZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfS25vd25NYXBGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkSW50NjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRJbnQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRVaW50NjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRVaW50NjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkSW50MzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRJbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRVaW50MzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRVaW50MzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkRml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZEZpeGVkMzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkRml4ZWQ2NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZEZpeGVkNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkQm9vbEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZEJvb2xFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkU3RyaW5nRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkU3RyaW5nRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZFNpbnQzMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZFNpbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRTaW50NjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRTaW50NjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRTZml4ZWQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRTZml4ZWQ2NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZFNmaXhlZDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Lbm93bk1hcEZpZWxkRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfS25vd25NYXBGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkSW50NjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRJbnQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRVaW50NjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRVaW50NjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkSW50MzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRJbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRVaW50MzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRVaW50MzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkRml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZEZpeGVkMzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkRml4ZWQ2NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZEZpeGVkNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkQm9vbEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZEJvb2xFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkU3RyaW5nRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkU3RyaW5nRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFNpbnQzMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFNpbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRTaW50NjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRTaW50NjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRTZml4ZWQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRTZml4ZWQ2NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFNmaXhlZDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbXBvcnRFbnVtTWFwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbXBvcnRFbnVtTWFwX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SW1wb3J0RW51bU1hcF9JbXBvcnRFbnVtQW1wRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEltcG9ydEVudW1NYXBfSW1wb3J0RW51bUFtcEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SW50SW50TWFwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbnRJbnRNYXBfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbnRJbnRNYXBfTUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbnRJbnRNYXBfTUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTUludDMyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTUludDMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01JbnQ2NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01JbnQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NVWludDMyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVVpbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NVWludDY0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVVpbnQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NU2ludDMyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVNpbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NU2ludDY0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVNpbnQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NRml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01GaXhlZDMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01GaXhlZDY0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTUZpeGVkNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVNmaXhlZDMyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVNmaXhlZDMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01TZml4ZWQ2NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01TZml4ZWQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NQm9vbEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01Cb29sRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01TdHJpbmdFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NU3RyaW5nRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RTdWJtZXNzYWdlTWFwc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0U3VibWVzc2FnZU1hcHNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzJCeXRlc01hcF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8yQnl0ZXNNYXBfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzJCeXRlc01hcF9NYXBCeXRlc0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzJCeXRlc01hcF9NYXBCeXRlc0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8yQnl0ZXNNYXBfTWFwU3RyaW5nRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvMkJ5dGVzTWFwX01hcFN0cmluZ0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG4pZ29vZ2xlL3Byb3RvYnVmL21hcF9wcm90bzJfdW5pdHRlc3QucHIiICsKICAgICAgIm90b1wwMjJcMDIxcHJvdG9idWZfdW5pdHRlc3RcMDMyJWdvb2dsZS9wcm90b2J1Zi8iICsKICAgICAgInVuaXR0ZXN0X2ltcG9ydC5wcm90b1wiXDMxMVwwMjRcblwwMTNUZXN0RW51bU1hcFwwMjJKXG4iICsKICAgICAgIlwwMTdrbm93bl9tYXBfZmllbGRcMDMwZSBcMDAzKFwwMTMyMS5wcm90b2J1Zl91bml0dGUiICsKICAgICAgInN0LlRlc3RFbnVtTWFwLktub3duTWFwRmllbGRFbnRyeVwwMjJOXG5cMDIxdW5rIiArCiAgICAgICJub3duX21hcF9maWVsZFwwMzBmIFwwMDMoXDAxMzIzLnByb3RvYnVmX3VuaXR0ZXN0IiArCiAgICAgICIuVGVzdEVudW1NYXAuVW5rbm93bk1hcEZpZWxkRW50cnlcMDIyWlxuXDAyN3VuayIgKwogICAgICAibm93bl9tYXBfZmllbGRfaW50NjRcMDMwXDMxMFwwMDEgXDAwMyhcMDEzMjgucHJvdG9idWZfdSIgKwogICAgICAibml0dGVzdC5UZXN0RW51bU1hcC5Vbmtub3duTWFwRmllbGRJbnQ2NCIgKwogICAgICAiRW50cnlcMDIyXFxcblwwMzB1bmtub3duX21hcF9maWVsZF91aW50NjRcMDMwXDMxMVwwMDEgXDAwMyhcMDEzIiArCiAgICAgICIyOS5wcm90b2J1Zl91bml0dGVzdC5UZXN0RW51bU1hcC5Vbmtub3duIiArCiAgICAgICJNYXBGaWVsZFVpbnQ2NEVudHJ5XDAyMlpcblwwMjd1bmtub3duX21hcF9maWVsZCIgKwogICAgICAiX2ludDMyXDAzMFwzMTJcMDAxIFwwMDMoXDAxMzI4LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbiIgKwogICAgICAidW1NYXAuVW5rbm93bk1hcEZpZWxkSW50MzJFbnRyeVwwMjJcXFxuXDAzMHVua25vIiArCiAgICAgICJ3bl9tYXBfZmllbGRfdWludDMyXDAzMFwzMTNcMDAxIFwwMDMoXDAxMzI5LnByb3RvYnVmX3VuIiArCiAgICAgICJpdHRlc3QuVGVzdEVudW1NYXAuVW5rbm93bk1hcEZpZWxkVWludDMyIiArCiAgICAgICJFbnRyeVwwMjJeXG5cMDMxdW5rbm93bl9tYXBfZmllbGRfZml4ZWQzMlwwMzBcMzE0XDAwMSBcMDAzKCIgKwogICAgICAiXDAxMzI6LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbnVtTWFwLlVua25vdyIgKwogICAgICAibk1hcEZpZWxkRml4ZWQzMkVudHJ5XDAyMl5cblwwMzF1bmtub3duX21hcF9maWUiICsKICAgICAgImxkX2ZpeGVkNjRcMDMwXDMxNVwwMDEgXDAwMyhcMDEzMjoucHJvdG9idWZfdW5pdHRlc3QuVGUiICsKICAgICAgInN0RW51bU1hcC5Vbmtub3duTWFwRmllbGRGaXhlZDY0RW50cnlcMDIyWFxuIiArCiAgICAgICJcMDI2dW5rbm93bl9tYXBfZmllbGRfYm9vbFwwMzBcMzE2XDAwMSBcMDAzKFwwMTMyNy5wcm90b2J1IiArCiAgICAgICJmX3VuaXR0ZXN0LlRlc3RFbnVtTWFwLlVua25vd25NYXBGaWVsZEJvIiArCiAgICAgICJvbEVudHJ5XDAyMlxcXG5cMDMwdW5rbm93bl9tYXBfZmllbGRfc3RyaW5nXDAzMFwzMTdcMDAxIFwwMDMiICsKICAgICAgIihcMDEzMjkucHJvdG9idWZfdW5pdHRlc3QuVGVzdEVudW1NYXAuVW5rbm8iICsKICAgICAgInduTWFwRmllbGRTdHJpbmdFbnRyeVwwMjJcXFxuXDAzMHVua25vd25fbWFwX2ZpZSIgKwogICAgICAibGRfc2ludDMyXDAzMFwzMjBcMDAxIFwwMDMoXDAxMzI5LnByb3RvYnVmX3VuaXR0ZXN0LlRlcyIgKwogICAgICAidEVudW1NYXAuVW5rbm93bk1hcEZpZWxkU2ludDMyRW50cnlcMDIyXFxcblwwMzB1IiArCiAgICAgICJua25vd25fbWFwX2ZpZWxkX3NpbnQ2NFwwMzBcMzIxXDAwMSBcMDAzKFwwMTMyOS5wcm90b2J1IiArCiAgICAgICJmX3VuaXR0ZXN0LlRlc3RFbnVtTWFwLlVua25vd25NYXBGaWVsZFNpIiArCiAgICAgICJudDY0RW50cnlcMDIyYFxuXDAzMnVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyXDAzMCIgKwogICAgICAiXDMyMlwwMDEgXDAwMyhcMDEzMjsucHJvdG9idWZfdW5pdHRlc3QuVGVzdEVudW1NYXAuVSIgKwogICAgICAibmtub3duTWFwRmllbGRTZml4ZWQzMkVudHJ5XDAyMmBcblwwMzJ1bmtub3duX20iICsKICAgICAgImFwX2ZpZWxkX3NmaXhlZDY0XDAzMFwzMjNcMDAxIFwwMDMoXDAxMzI7LnByb3RvYnVmX3VuaXQiICsKICAgICAgInRlc3QuVGVzdEVudW1NYXAuVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQiICsKICAgICAgIkVudHJ5XDAzMlZcblwwMjJLbm93bk1hcEZpZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNSIgKwogICAgICAiXDAyMi9cblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjIgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3QiICsKICAgICAgIm8yTWFwRW51bTpcMDAyOFwwMDFcMDMyWFxuXDAyNFVua25vd25NYXBGaWVsZEVudHJ5XDAyMlwwMTNcbiIgKwogICAgICAiXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjIvXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyIC5wcm90b2J1Zl91bmkiICsKICAgICAgInR0ZXN0LlByb3RvMk1hcEVudW06XDAwMjhcMDAxXDAzMl1cblwwMzFVbmtub3duTWFwRmllIiArCiAgICAgICJsZEludDY0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwM1wwMjIvXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYiICsKICAgICAgIjIgLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW06XDAwMjhcMDAxXDAzMl4iICsKICAgICAgIlxuXDAzMlVua25vd25NYXBGaWVsZFVpbnQ2NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAwNFwwMjIvXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyIC5wcm90b2J1Zl91bml0dGVzdC5Qcm8iICsKICAgICAgInRvMk1hcEVudW06XDAwMjhcMDAxXDAzMl1cblwwMzFVbmtub3duTWFwRmllbGRJbnQzMkVuIiArCiAgICAgICJ0cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjIvXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyIC5wcm90b2IiICsKICAgICAgInVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW06XDAwMjhcMDAxXDAzMl5cblwwMzJVbmtub3duIiArCiAgICAgICJNYXBGaWVsZFVpbnQzMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFxyXDAyMi9cblwwMDV2YWx1IiArCiAgICAgICJlXDAzMFwwMDIgXDAwMShcMDE2MiAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51IiArCiAgICAgICJtOlwwMDI4XDAwMVwwMzJfXG5cMDMzVW5rbm93bk1hcEZpZWxkRml4ZWQzMkVudHJ5XDAyMlwwMTNcblwwMDMiICsKICAgICAgImtleVwwMzBcMDAxIFwwMDEoXDAwN1wwMjIvXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyIC5wcm90b2J1Zl91bml0IiArCiAgICAgICJ0ZXN0LlByb3RvMk1hcEVudW06XDAwMjhcMDAxXDAzMl9cblwwMzNVbmtub3duTWFwRmllbCIgKwogICAgICAiZEZpeGVkNjRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMi9cblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoIiArCiAgICAgICJcMDE2MiAucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bTpcMDAyOFwwMDFcMDMyIiArCiAgICAgICJcXFxuXDAzMFVua25vd25NYXBGaWVsZEJvb2xFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwIiArCiAgICAgICJcMDIyL1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MiAucHJvdG9idWZfdW5pdHRlc3QuUHJvdCIgKwogICAgICAibzJNYXBFbnVtOlwwMDI4XDAwMVwwMzJeXG5cMDMyVW5rbm93bk1hcEZpZWxkU3RyaW5nRW4iICsKICAgICAgInRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjIvXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyIC5wcm90b2IiICsKICAgICAgInVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW06XDAwMjhcMDAxXDAzMl5cblwwMzJVbmtub3duIiArCiAgICAgICJNYXBGaWVsZFNpbnQzMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjFcMDIyL1xuXDAwNXZhbHUiICsKICAgICAgImVcMDMwXDAwMiBcMDAxKFwwMTYyIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnUiICsKICAgICAgIm06XDAwMjhcMDAxXDAzMl5cblwwMzJVbmtub3duTWFwRmllbGRTaW50NjRFbnRyeVwwMjJcMDEzXG5cMDAzayIgKwogICAgICAiZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyL1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MiAucHJvdG9idWZfdW5pdHQiICsKICAgICAgImVzdC5Qcm90bzJNYXBFbnVtOlwwMDI4XDAwMVwwMzJgXG5cMDM0VW5rbm93bk1hcEZpZWxkIiArCiAgICAgICJTZml4ZWQzMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyL1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMSgiICsKICAgICAgIlwwMTYyIC5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzJNYXBFbnVtOlwwMDI4XDAwMVwwMzIiICsKICAgICAgImBcblwwMzRVbmtub3duTWFwRmllbGRTZml4ZWQ2NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSIgKwogICAgICAiIFwwMDEoXDAyMFwwMjIvXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyIC5wcm90b2J1Zl91bml0dGVzdC4iICsKICAgICAgIlByb3RvMk1hcEVudW06XDAwMjhcMDAxXCJcMzE2XDAyNlxuXDAyNFRlc3RFbnVtTWFwUGx1c0V4dCIgKwogICAgICAicmFcMDIyU1xuXDAxN2tub3duX21hcF9maWVsZFwwMzBlIFwwMDMoXDAxMzI6LnByb3RvYnVmX3UiICsKICAgICAgIm5pdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmEuS25vd25NYXBGaWUiICsKICAgICAgImxkRW50cnlcMDIyV1xuXDAyMXVua25vd25fbWFwX2ZpZWxkXDAzMGYgXDAwMyhcMDEzMjwucHJvIiArCiAgICAgICJ0b2J1Zl91bml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYS5VbmtuIiArCiAgICAgICJvd25NYXBGaWVsZEVudHJ5XDAyMmNcblwwMjd1bmtub3duX21hcF9maWVsZF9pbiIgKwogICAgICAidDY0XDAzMFwzMTBcMDAxIFwwMDMoXDAxMzJBLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbnVtTSIgKwogICAgICAiYXBQbHVzRXh0cmEuVW5rbm93bk1hcEZpZWxkSW50NjRFbnRyeVwwMjJlXG4iICsKICAgICAgIlwwMzB1bmtub3duX21hcF9maWVsZF91aW50NjRcMDMwXDMxMVwwMDEgXDAwMyhcMDEzMkIucHJvdG8iICsKICAgICAgImJ1Zl91bml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYS5Vbmtub3ciICsKICAgICAgIm5NYXBGaWVsZFVpbnQ2NEVudHJ5XDAyMmNcblwwMjd1bmtub3duX21hcF9maWVsIiArCiAgICAgICJkX2ludDMyXDAzMFwzMTJcMDAxIFwwMDMoXDAxMzJBLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFIiArCiAgICAgICJudW1NYXBQbHVzRXh0cmEuVW5rbm93bk1hcEZpZWxkSW50MzJFbnRyIiArCiAgICAgICJ5XDAyMmVcblwwMzB1bmtub3duX21hcF9maWVsZF91aW50MzJcMDMwXDMxM1wwMDEgXDAwMyhcMDEzMkIucCIgKwogICAgICAicm90b2J1Zl91bml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYS5VbiIgKwogICAgICAia25vd25NYXBGaWVsZFVpbnQzMkVudHJ5XDAyMmdcblwwMzF1bmtub3duX21hcF8iICsKICAgICAgImZpZWxkX2ZpeGVkMzJcMDMwXDMxNFwwMDEgXDAwMyhcMDEzMkMucHJvdG9idWZfdW5pdHRlc3QiICsKICAgICAgIi5UZXN0RW51bU1hcFBsdXNFeHRyYS5Vbmtub3duTWFwRmllbGRGaXgiICsKICAgICAgImVkMzJFbnRyeVwwMjJnXG5cMDMxdW5rbm93bl9tYXBfZmllbGRfZml4ZWQ2NFwwMzBcMzE1IiArCiAgICAgICJcMDAxIFwwMDMoXDAxMzJDLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbnVtTWFwUGx1IiArCiAgICAgICJzRXh0cmEuVW5rbm93bk1hcEZpZWxkRml4ZWQ2NEVudHJ5XDAyMmFcblwwMjZ1biIgKwogICAgICAia25vd25fbWFwX2ZpZWxkX2Jvb2xcMDMwXDMxNlwwMDEgXDAwMyhcMDEzMkAucHJvdG9idWZfdSIgKwogICAgICAibml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYS5Vbmtub3duTWFwRiIgKwogICAgICAiaWVsZEJvb2xFbnRyeVwwMjJlXG5cMDMwdW5rbm93bl9tYXBfZmllbGRfc3RyaW4iICsKICAgICAgImdcMDMwXDMxN1wwMDEgXDAwMyhcMDEzMkIucHJvdG9idWZfdW5pdHRlc3QuVGVzdEVudW1NYXAiICsKICAgICAgIlBsdXNFeHRyYS5Vbmtub3duTWFwRmllbGRTdHJpbmdFbnRyeVwwMjJlXG5cMDMwIiArCiAgICAgICJ1bmtub3duX21hcF9maWVsZF9zaW50MzJcMDMwXDMyMFwwMDEgXDAwMyhcMDEzMkIucHJvdG9iIiArCiAgICAgICJ1Zl91bml0dGVzdC5UZXN0RW51bU1hcFBsdXNFeHRyYS5Vbmtub3duIiArCiAgICAgICJNYXBGaWVsZFNpbnQzMkVudHJ5XDAyMmVcblwwMzB1bmtub3duX21hcF9maWVsZCIgKwogICAgICAiX3NpbnQ2NFwwMzBcMzIxXDAwMSBcMDAzKFwwMTMyQi5wcm90b2J1Zl91bml0dGVzdC5UZXN0RSIgKwogICAgICAibnVtTWFwUGx1c0V4dHJhLlVua25vd25NYXBGaWVsZFNpbnQ2NEVudCIgKwogICAgICAicnlcMDIyaVxuXDAzMnVua25vd25fbWFwX2ZpZWxkX3NmaXhlZDMyXDAzMFwzMjJcMDAxIFwwMDMoXDAxMzIiICsKICAgICAgIkQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmEiICsKICAgICAgIi5Vbmtub3duTWFwRmllbGRTZml4ZWQzMkVudHJ5XDAyMmlcblwwMzJ1bmtub3duIiArCiAgICAgICJfbWFwX2ZpZWxkX3NmaXhlZDY0XDAzMFwzMjNcMDAxIFwwMDMoXDAxMzJELnByb3RvYnVmX3VuIiArCiAgICAgICJpdHRlc3QuVGVzdEVudW1NYXBQbHVzRXh0cmEuVW5rbm93bk1hcEZpIiArCiAgICAgICJlbGRTZml4ZWQ2NEVudHJ5XDAzMl9cblwwMjJLbm93bk1hcEZpZWxkRW50cnlcMDIyXDAxMyIgKwogICAgICAiXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMjhcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjIpLnByb3RvYnVmX3VuIiArCiAgICAgICJpdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYTpcMDAyOFwwMDFcMDMyYVxuXDAyNFVuayIgKwogICAgICAibm93bk1hcEZpZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjI4XG5cMDA1dmFsdWVcMDMwIiArCiAgICAgICJcMDAyIFwwMDEoXDAxNjIpLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QIiArCiAgICAgICJsdXNFeHRyYTpcMDAyOFwwMDFcMDMyZlxuXDAzMVVua25vd25NYXBGaWVsZEludDY0RW50ciIgKwogICAgICAieVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDAzXDAyMjhcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjIpLnByb3RvYnVmIiArCiAgICAgICJfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYTpcMDAyOFwwMDFcMDMyZ1xuXDAzMiIgKwogICAgICAiVW5rbm93bk1hcEZpZWxkVWludDY0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjIiICsKICAgICAgIjhcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjIpLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvIiArCiAgICAgICIyTWFwRW51bVBsdXNFeHRyYTpcMDAyOFwwMDFcMDMyZlxuXDAzMVVua25vd25NYXBGaWVsZCIgKwogICAgICAiSW50MzJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMjhcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjIpIiArCiAgICAgICIucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyIiArCiAgICAgICJhOlwwMDI4XDAwMVwwMzJnXG5cMDMyVW5rbm93bk1hcEZpZWxkVWludDMyRW50cnlcMDIyXDAxM1xuXDAwM2siICsKICAgICAgImV5XDAzMFwwMDEgXDAwMShcclwwMjI4XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyKS5wcm90b2J1Zl91bml0dCIgKwogICAgICAiZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE6XDAwMjhcMDAxXDAzMmhcblwwMzNVbmtub3ciICsKICAgICAgIm5NYXBGaWVsZEZpeGVkMzJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA3XDAyMjhcblwwMDV2YSIgKwogICAgICAibHVlXDAzMFwwMDIgXDAwMShcMDE2MikucHJvdG9idWZfdW5pdHRlc3QuUHJvdG8yTWFwRSIgKwogICAgICAibnVtUGx1c0V4dHJhOlwwMDI4XDAwMVwwMzJoXG5cMDMzVW5rbm93bk1hcEZpZWxkRml4ZWQiICsKICAgICAgIjY0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNlwwMjI4XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyKS5wciIgKwogICAgICAib3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE6XDAwMiIgKwogICAgICAiOFwwMDFcMDMyZVxuXDAzMFVua25vd25NYXBGaWVsZEJvb2xFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgIiArCiAgICAgICJcMDAxKFwwMTBcMDIyOFxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE2MikucHJvdG9idWZfdW5pdHRlc3QuUCIgKwogICAgICAicm90bzJNYXBFbnVtUGx1c0V4dHJhOlwwMDI4XDAwMVwwMzJnXG5cMDMyVW5rbm93bk1hcEYiICsKICAgICAgImllbGRTdHJpbmdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjI4XG5cMDA1dmFsdWVcMDMwXDAwMiAiICsKICAgICAgIlwwMDEoXDAxNjIpLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHUiICsKICAgICAgInNFeHRyYTpcMDAyOFwwMDFcMDMyZ1xuXDAzMlVua25vd25NYXBGaWVsZFNpbnQzMkVudHJ5IiArCiAgICAgICJcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAyMVwwMjI4XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyKS5wcm90b2J1Zl8iICsKICAgICAgInVuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXh0cmE6XDAwMjhcMDAxXDAzMmdcblwwMzJVIiArCiAgICAgICJua25vd25NYXBGaWVsZFNpbnQ2NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjJcMDIyOCIgKwogICAgICAiXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyKS5wcm90b2J1Zl91bml0dGVzdC5Qcm90bzIiICsKICAgICAgIk1hcEVudW1QbHVzRXh0cmE6XDAwMjhcMDAxXDAzMmlcblwwMzRVbmtub3duTWFwRmllbGRTIiArCiAgICAgICJmaXhlZDMyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjI4XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYiICsKICAgICAgIjIpLnByb3RvYnVmX3VuaXR0ZXN0LlByb3RvMk1hcEVudW1QbHVzRXgiICsKICAgICAgInRyYTpcMDAyOFwwMDFcMDMyaVxuXDAzNFVua25vd25NYXBGaWVsZFNmaXhlZDY0RW50cnlcMDIyIiArCiAgICAgICJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIwXDAyMjhcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNjIpLnByb3RvYnVmX3UiICsKICAgICAgIm5pdHRlc3QuUHJvdG8yTWFwRW51bVBsdXNFeHRyYTpcMDAyOFwwMDFcIlwzMDdcMDAxXG5cMDIxVCIgKwogICAgICAiZXN0SW1wb3J0RW51bU1hcFwwMjJQXG5cMDE3aW1wb3J0X2VudW1fYW1wXDAzMFwwMDEgXDAwMygiICsKICAgICAgIlwwMTMyNy5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW1wb3J0RW51bU1hcC4iICsKICAgICAgIkltcG9ydEVudW1BbXBFbnRyeVwwMzJgXG5cMDIySW1wb3J0RW51bUFtcEVudHJ5IiArCiAgICAgICJcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjI5XG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyKi5wcm90b2J1Zl8iICsKICAgICAgInVuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtRm9yTWFwOlwwMDI4XDAwMVwibVxuXHIiICsKICAgICAgIlRlc3RJbnRJbnRNYXBcMDIyMlxuXDAwMW1cMDMwXDAwMSBcMDAzKFwwMTMyXCcucHJvdG9idWZfdW5pdCIgKwogICAgICAidGVzdC5UZXN0SW50SW50TWFwLk1FbnRyeVwwMzIoXG5cMDA2TUVudHJ5XDAyMlwwMTNcblwwMDNrIiArCiAgICAgICJleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDI4XDAwMVwiXDI3MFxyXG5cMDEwVGVzdE1hcHMiICsKICAgICAgIlwwMjI4XG5cMDA3bV9pbnQzMlwwMzBcMDAxIFwwMDMoXDAxMzJcJy5wcm90b2J1Zl91bml0dGVzdC5UZSIgKwogICAgICAic3RNYXBzLk1JbnQzMkVudHJ5XDAyMjhcblwwMDdtX2ludDY0XDAzMFwwMDIgXDAwMyhcMDEzMlwnLnByIiArCiAgICAgICJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcHMuTUludDY0RW50cnlcMDIyOlxuXDAxMCIgKwogICAgICAibV91aW50MzJcMDMwXDAwMyBcMDAzKFwwMTMyKC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TSIgKwogICAgICAiYXBzLk1VaW50MzJFbnRyeVwwMjI6XG5cMDEwbV91aW50NjRcMDMwXDAwNCBcMDAzKFwwMTMyKC5wcm8iICsKICAgICAgInRvYnVmX3VuaXR0ZXN0LlRlc3RNYXBzLk1VaW50NjRFbnRyeVwwMjI6XG5cMDEwIiArCiAgICAgICJtX3NpbnQzMlwwMzBcMDA1IFwwMDMoXDAxMzIoLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNIiArCiAgICAgICJhcHMuTVNpbnQzMkVudHJ5XDAyMjpcblwwMTBtX3NpbnQ2NFwwMzBcMDA2IFwwMDMoXDAxMzIoLnBybyIgKwogICAgICAidG9idWZfdW5pdHRlc3QuVGVzdE1hcHMuTVNpbnQ2NEVudHJ5XDAyMjxcblx0IiArCiAgICAgICJtX2ZpeGVkMzJcMDMwXDAwNyBcMDAzKFwwMTMyKS5wcm90b2J1Zl91bml0dGVzdC5UZXN0IiArCiAgICAgICJNYXBzLk1GaXhlZDMyRW50cnlcMDIyPFxuXHRtX2ZpeGVkNjRcMDMwXDAxMCBcMDAzKFwwMTMyKS4iICsKICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXBzLk1GaXhlZDY0RW50cnkiICsKICAgICAgIlwwMjI+XG5cbm1fc2ZpeGVkMzJcMDMwXHQgXDAwMyhcMDEzMioucHJvdG9idWZfdW5pdHRlc3QiICsKICAgICAgIi5UZXN0TWFwcy5NU2ZpeGVkMzJFbnRyeVwwMjI+XG5cbm1fc2ZpeGVkNjRcMDMwXG4iICsKICAgICAgIiBcMDAzKFwwMTMyKi5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwcy5NU2ZpeGUiICsKICAgICAgImQ2NEVudHJ5XDAyMjZcblwwMDZtX2Jvb2xcMDMwXDAxMyBcMDAzKFwwMTMyJi5wcm90b2J1Zl91bml0IiArCiAgICAgICJ0ZXN0LlRlc3RNYXBzLk1Cb29sRW50cnlcMDIyOlxuXDAxMG1fc3RyaW5nXDAzMFwwMTQgXDAwMyIgKwogICAgICAiKFwwMTMyKC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwcy5NU3RyaW5nRSIgKwogICAgICAibnRyeVwwMzJPXG5cMDEzTUludDMyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjIvXG5cMDA1dmFsdSIgKwogICAgICAiZVwwMzBcMDAyIFwwMDEoXDAxMzIgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnRJbnRNYSIgKwogICAgICAicDpcMDAyOFwwMDFcMDMyT1xuXDAxM01JbnQ2NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyL1xuXDAwNXZhbCIgKwogICAgICAidWVcMDMwXDAwMiBcMDAxKFwwMTMyIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW50TSIgKwogICAgICAiYXA6XDAwMjhcMDAxXDAzMlBcblwwMTRNVWludDMyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyL1xuXDAwNXYiICsKICAgICAgImFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SW50SW4iICsKICAgICAgInRNYXA6XDAwMjhcMDAxXDAzMlBcblwwMTRNVWludDY0RW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjIvXG4iICsKICAgICAgIlwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJbnQiICsKICAgICAgIkludE1hcDpcMDAyOFwwMDFcMDMyUFxuXDAxNE1TaW50MzJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMiIgKwogICAgICAiL1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMiAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEkiICsKICAgICAgIm50SW50TWFwOlwwMDI4XDAwMVwwMzJQXG5cMDE0TVNpbnQ2NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAyMlwwMjIvXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyIC5wcm90b2J1Zl91bml0dGVzdC5UZXMiICsKICAgICAgInRJbnRJbnRNYXA6XDAwMjhcMDAxXDAzMlFcblxyTUZpeGVkMzJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEiICsKICAgICAgIiBcMDAxKFwwMDdcMDIyL1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMiAucHJvdG9idWZfdW5pdHRlc3QuIiArCiAgICAgICJUZXN0SW50SW50TWFwOlwwMDI4XDAwMVwwMzJRXG5cck1GaXhlZDY0RW50cnlcMDIyXDAxM1xuXDAwM2tlIiArCiAgICAgICJ5XDAzMFwwMDEgXDAwMShcMDA2XDAyMi9cblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIgLnByb3RvYnVmX3VuaXR0ZSIgKwogICAgICAic3QuVGVzdEludEludE1hcDpcMDAyOFwwMDFcMDMyUlxuXDAxNk1TZml4ZWQzMkVudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAxN1wwMjIvXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyIC5wcm90b2J1Zl91biIgKwogICAgICAiaXR0ZXN0LlRlc3RJbnRJbnRNYXA6XDAwMjhcMDAxXDAzMlJcblwwMTZNU2ZpeGVkNjRFbnQiICsKICAgICAgInJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyL1xuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDEzMiAucHJvdG9idSIgKwogICAgICAiZl91bml0dGVzdC5UZXN0SW50SW50TWFwOlwwMDI4XDAwMVwwMzJOXG5cbk1Cb29sRW50IiArCiAgICAgICJyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwXDAyMi9cblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIgLnByb3RvYnUiICsKICAgICAgImZfdW5pdHRlc3QuVGVzdEludEludE1hcDpcMDAyOFwwMDFcMDMyUFxuXDAxNE1TdHJpbmdFIiArCiAgICAgICJudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMi9cblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIgLnByb3RvIiArCiAgICAgICJidWZfdW5pdHRlc3QuVGVzdEludEludE1hcDpcMDAyOFwwMDFcIjxcblwwMjJUZXN0U3UiICsKICAgICAgImJtZXNzYWdlTWFwc1wwMjImXG5cMDAxbVwwMzBcMDAxIFwwMDEoXDAxMzJcMDMzLnByb3RvYnVmX3VuaXR0IiArCiAgICAgICJlc3QuVGVzdE1hcHNcIlwyMTFcMDAyXG5cMDIyVGVzdFByb3RvMkJ5dGVzTWFwXDAyMkZcblx0bSIgKwogICAgICAiYXBfYnl0ZXNcMDMwXDAwMSBcMDAzKFwwMTMyMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UCIgKwogICAgICAicm90bzJCeXRlc01hcC5NYXBCeXRlc0VudHJ5XDAyMkhcblxubWFwX3N0cmluIiArCiAgICAgICJnXDAzMFwwMDIgXDAwMyhcMDEzMjQucHJvdG9idWZfdW5pdHRlc3QuVGVzdFByb3RvMkJ5IiArCiAgICAgICJ0ZXNNYXAuTWFwU3RyaW5nRW50cnlcMDMyL1xuXHJNYXBCeXRlc0VudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDE0OlwwMDI4XDAwMVwwMzIwXG5cMDE2TWFwU3RyIiArCiAgICAgICJpbmdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMSIgKwogICAgICAiKlpcblxyUHJvdG8yTWFwRW51bVwwMjJcMDI3XG5cMDIzUFJPVE8yX01BUF9FTlVNX0ZPTyIgKwogICAgICAiXDAyMFwwMDBcMDIyXDAyN1xuXDAyM1BST1RPMl9NQVBfRU5VTV9CQVJcMDIwXDAwMVwwMjJcMDI3XG5cMDIzUFJPVE8yX01BIiArCiAgICAgICJQX0VOVU1fQkFaXDAyMFwwMDIqXDIwNlwwMDFcblwwMjZQcm90bzJNYXBFbnVtUGx1c0V4dHJhXDAyMiIgKwogICAgICAiXDAzMVxuXDAyNUVfUFJPVE8yX01BUF9FTlVNX0ZPT1wwMjBcMDAwXDAyMlwwMzFcblwwMjVFX1BST1RPMl9NIiArCiAgICAgICJBUF9FTlVNX0JBUlwwMjBcMDAxXDAyMlwwMzFcblwwMjVFX1BST1RPMl9NQVBfRU5VTV9CQVpcMDIwXDAwMiIgKwogICAgICAiXDAyMlwwMzNcblwwMjdFX1BST1RPMl9NQVBfRU5VTV9FWFRSQVwwMjBcMDAzQlwwMDNcMzcwXDAwMVwwMDEiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5nZXREZXNjcmlwdG9yKCksCiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktub3duTWFwRmllbGQiLCAiVW5rbm93bk1hcEZpZWxkIiwgIlVua25vd25NYXBGaWVsZEludDY0IiwgIlVua25vd25NYXBGaWVsZFVpbnQ2NCIsICJVbmtub3duTWFwRmllbGRJbnQzMiIsICJVbmtub3duTWFwRmllbGRVaW50MzIiLCAiVW5rbm93bk1hcEZpZWxkRml4ZWQzMiIsICJVbmtub3duTWFwRmllbGRGaXhlZDY0IiwgIlVua25vd25NYXBGaWVsZEJvb2wiLCAiVW5rbm93bk1hcEZpZWxkU3RyaW5nIiwgIlVua25vd25NYXBGaWVsZFNpbnQzMiIsICJVbmtub3duTWFwRmllbGRTaW50NjQiLCAiVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzIiLCAiVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Lbm93bk1hcEZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX0tub3duTWFwRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Lbm93bk1hcEZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkSW50NjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkSW50NjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRJbnQ2NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRVaW50NjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkVWludDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkVWludDY0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZEludDMyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZEludDMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkSW50MzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkVWludDMyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZFVpbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZFVpbnQzMkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRGaXhlZDMyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZEZpeGVkMzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRGaXhlZDMyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZEZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkRml4ZWQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZEZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkQm9vbEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRCb29sRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkQm9vbEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRTdHJpbmdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkU3RyaW5nRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkU3RyaW5nRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZFNpbnQzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkU2ludDMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkU2ludDMyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZFNpbnQ2NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkU2ludDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBfVW5rbm93bk1hcEZpZWxkU2ludDY0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZFNmaXhlZDMyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRTZml4ZWQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZFNmaXhlZDMyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZFNmaXhlZDY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcF9Vbmtub3duTWFwRmllbGRTZml4ZWQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwX1Vua25vd25NYXBGaWVsZFNmaXhlZDY0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLbm93bk1hcEZpZWxkIiwgIlVua25vd25NYXBGaWVsZCIsICJVbmtub3duTWFwRmllbGRJbnQ2NCIsICJVbmtub3duTWFwRmllbGRVaW50NjQiLCAiVW5rbm93bk1hcEZpZWxkSW50MzIiLCAiVW5rbm93bk1hcEZpZWxkVWludDMyIiwgIlVua25vd25NYXBGaWVsZEZpeGVkMzIiLCAiVW5rbm93bk1hcEZpZWxkRml4ZWQ2NCIsICJVbmtub3duTWFwRmllbGRCb29sIiwgIlVua25vd25NYXBGaWVsZFN0cmluZyIsICJVbmtub3duTWFwRmllbGRTaW50MzIiLCAiVW5rbm93bk1hcEZpZWxkU2ludDY0IiwgIlVua25vd25NYXBGaWVsZFNmaXhlZDMyIiwgIlVua25vd25NYXBGaWVsZFNmaXhlZDY0IiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfS25vd25NYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Lbm93bk1hcEZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfS25vd25NYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZEludDY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZEludDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkSW50NjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkVWludDY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFVpbnQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFVpbnQ2NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRJbnQzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRJbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZEludDMyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFVpbnQzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRVaW50MzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRVaW50MzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkRml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRGaXhlZDMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkRml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRGaXhlZDY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZEZpeGVkNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRGaXhlZDY0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZEJvb2xFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkQm9vbEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZEJvb2xFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkU3RyaW5nRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFN0cmluZ0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFN0cmluZ0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRTaW50MzJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFNpbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFNpbnQzMkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRTaW50NjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFNpbnQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbnVtTWFwUGx1c0V4dHJhX1Vua25vd25NYXBGaWVsZFNpbnQ2NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRTZml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkU2ZpeGVkMzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRTZml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRTZml4ZWQ2NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVudW1NYXBQbHVzRXh0cmFfVW5rbm93bk1hcEZpZWxkU2ZpeGVkNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW51bU1hcFBsdXNFeHRyYV9Vbmtub3duTWFwRmllbGRTZml4ZWQ2NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SW1wb3J0RW51bU1hcF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SW1wb3J0RW51bU1hcF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SW1wb3J0RW51bU1hcF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSW1wb3J0RW51bUFtcCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbXBvcnRFbnVtTWFwX0ltcG9ydEVudW1BbXBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbXBvcnRFbnVtTWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEltcG9ydEVudW1NYXBfSW1wb3J0RW51bUFtcEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbXBvcnRFbnVtTWFwX0ltcG9ydEVudW1BbXBFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEludEludE1hcF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SW50SW50TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbnRJbnRNYXBfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk0iLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SW50SW50TWFwX01FbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJbnRJbnRNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SW50SW50TWFwX01FbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SW50SW50TWFwX01FbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk1JbnQzMiIsICJNSW50NjQiLCAiTVVpbnQzMiIsICJNVWludDY0IiwgIk1TaW50MzIiLCAiTVNpbnQ2NCIsICJNRml4ZWQzMiIsICJNRml4ZWQ2NCIsICJNU2ZpeGVkMzIiLCAiTVNmaXhlZDY0IiwgIk1Cb29sIiwgIk1TdHJpbmciLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NSW50MzJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTUludDMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTUludDMyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01JbnQ2NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NSW50NjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NSW50NjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVVpbnQzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NVWludDMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVVpbnQzMkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NVWludDY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01VaW50NjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NVWludDY0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01TaW50MzJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVNpbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01TaW50MzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVNpbnQ2NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NU2ludDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVNpbnQ2NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NRml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NRml4ZWQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01GaXhlZDMyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01GaXhlZDY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01GaXhlZDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTUZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVNmaXhlZDMyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01TZml4ZWQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01TZml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NU2ZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoOSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVNmaXhlZDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcHNfTVNmaXhlZDY0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01Cb29sRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NQm9vbEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01Cb29sRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01TdHJpbmdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBzX01TdHJpbmdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwc19NU3RyaW5nRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RTdWJtZXNzYWdlTWFwc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0U3VibWVzc2FnZU1hcHNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFN1Ym1lc3NhZ2VNYXBzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJNIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvMkJ5dGVzTWFwX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzJCeXRlc01hcF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8yQnl0ZXNNYXBfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk1hcEJ5dGVzIiwgIk1hcFN0cmluZyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzJCeXRlc01hcF9NYXBCeXRlc0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvMkJ5dGVzTWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvMkJ5dGVzTWFwX01hcEJ5dGVzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFByb3RvMkJ5dGVzTWFwX01hcEJ5dGVzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzJCeXRlc01hcF9NYXBTdHJpbmdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzJCeXRlc01hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQcm90bzJCeXRlc01hcF9NYXBTdHJpbmdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UHJvdG8yQnl0ZXNNYXBfTWFwU3RyaW5nRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LmdldERlc2NyaXB0b3IoKTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAI91YmVUmgoAVJoKACIAAABwcm90b2J1Zl91bml0dGVzdC9NYXBVbml0dGVzdC5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKCnB1YmxpYyBmaW5hbCBjbGFzcyBNYXBVbml0dGVzdCB7CiAgcHJpdmF0ZSBNYXBVbml0dGVzdCgpIHt9CiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgcmVnaXN0cnkpIHsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bX0KICAgKi8KICBwdWJsaWMgZW51bSBNYXBFbnVtCiAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgIC8qKgogICAgICogPGNvZGU+TUFQX0VOVU1fRk9PID0gMDs8L2NvZGU+CiAgICAgKi8KICAgIE1BUF9FTlVNX0ZPTygwKSwKICAgIC8qKgogICAgICogPGNvZGU+TUFQX0VOVU1fQkFSID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIE1BUF9FTlVNX0JBUigxKSwKICAgIC8qKgogICAgICogPGNvZGU+TUFQX0VOVU1fQkFaID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIE1BUF9FTlVNX0JBWigyKSwKICAgIFVOUkVDT0dOSVpFRCgtMSksCiAgICA7CgogICAgLyoqCiAgICAgKiA8Y29kZT5NQVBfRU5VTV9GT08gPSAwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0VOVU1fRk9PX1ZBTFVFID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+TUFQX0VOVU1fQkFSID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9FTlVNX0JBUl9WQUxVRSA9IDE7CiAgICAvKioKICAgICAqIDxjb2RlPk1BUF9FTlVNX0JBWiA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfRU5VTV9CQVpfVkFMVUUgPSAyOwoKCiAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgaWYgKHRoaXMgPT0gVU5SRUNPR05JWkVEKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJDYW4ndCBnZXQgdGhlIG51bWJlciBvZiBhbiB1bmtub3duIGVudW0gdmFsdWUuIik7CiAgICAgIH0KICAgICAgcmV0dXJuIHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgc3RhdGljIE1hcEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBNYXBFbnVtIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgIGNhc2UgMDogcmV0dXJuIE1BUF9FTlVNX0ZPTzsKICAgICAgICBjYXNlIDE6IHJldHVybiBNQVBfRU5VTV9CQVI7CiAgICAgICAgY2FzZSAyOiByZXR1cm4gTUFQX0VOVU1fQkFaOwogICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE1hcEVudW0+CiAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgIE1hcEVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TWFwRW51bT4oKSB7CiAgICAgICAgICAgIHB1YmxpYyBNYXBFbnVtIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gTWFwRW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKCiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICBpZiAodGhpcyA9PSBVTlJFQ09HTklaRUQpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxTdGF0ZUV4Y2VwdGlvbigKICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgZGVzY3JpcHRvciBvZiBhbiB1bnJlY29nbml6ZWQgZW51bSB2YWx1ZS4iKTsKICAgICAgfQogICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgfQogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcEVudW1bXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICBwdWJsaWMgc3RhdGljIE1hcEVudW0gdmFsdWVPZigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgfQogICAgICBpZiAoZGVzYy5nZXRJbmRleCgpID09IC0xKSB7CiAgICAgICAgcmV0dXJuIFVOUkVDT0dOSVpFRDsKICAgICAgfQogICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgcHJpdmF0ZSBNYXBFbnVtKGludCB2YWx1ZSkgewogICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSkKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE1hcE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ludDMyX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBJbnQzMkludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ludDMyX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNNYXBJbnQzMkludDMyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRNYXBJbnQzMkludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9pbnQzMl9pbnQzMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE1hcEludDMySW50MzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ludDMyX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBJbnQzMkludDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9pbnQzMl9pbnQzMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwSW50MzJJbnQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBtYXBfaW50NjRfaW50NjQgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcEludDY0SW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBtYXBfaW50NjRfaW50NjQgPSAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcEludDY0SW50NjQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQ2NEludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRNYXBJbnQ2NEludDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IG1hcF9pbnQ2NF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldE1hcEludDY0SW50NjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgbWFwX2ludDY0X2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0TWFwSW50NjRJbnQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IG1hcF9pbnQ2NF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldE1hcEludDY0SW50NjRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcFVpbnQzMlVpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcFVpbnQzMlVpbnQzMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwVWludDMyVWludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRNYXBVaW50MzJVaW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBtYXBfdWludDMyX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE1hcFVpbnQzMlVpbnQzMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IG1hcF91aW50MzJfdWludDMyID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBVaW50MzJVaW50MzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBtYXBfdWludDMyX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwVWludDMyVWludDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcFVpbnQ2NFVpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcFVpbnQ2NFVpbnQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFVpbnQ2NFVpbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0TWFwVWludDY0VWludDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRNYXBVaW50NjRVaW50NjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBtYXBfdWludDY0X3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldE1hcFVpbnQ2NFVpbnQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRNYXBVaW50NjRVaW50NjRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgbWFwX3NpbnQzMl9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcFNpbnQzMlNpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgbWFwX3NpbnQzMl9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcFNpbnQzMlNpbnQzMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwU2ludDMyU2ludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRNYXBTaW50MzJTaW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBtYXBfc2ludDMyX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE1hcFNpbnQzMlNpbnQzMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IG1hcF9zaW50MzJfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBTaW50MzJTaW50MzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBtYXBfc2ludDMyX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwU2ludDMyU2ludDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgbWFwX3NpbnQ2NF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcFNpbnQ2NFNpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgbWFwX3NpbnQ2NF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcFNpbnQ2NFNpbnQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFNpbnQ2NFNpbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0TWFwU2ludDY0U2ludDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgbWFwX3NpbnQ2NF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRNYXBTaW50NjRTaW50NjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBtYXBfc2ludDY0X3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldE1hcFNpbnQ2NFNpbnQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgbWFwX3NpbnQ2NF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRNYXBTaW50NjRTaW50NjRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBGaXhlZDMyRml4ZWQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNNYXBGaXhlZDMyRml4ZWQzMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwRml4ZWQzMkZpeGVkMzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE1hcEZpeGVkMzJGaXhlZDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TWFwRml4ZWQzMkZpeGVkMzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IG1hcF9maXhlZDMyX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcEZpeGVkMzJGaXhlZDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBGaXhlZDMyRml4ZWQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwRml4ZWQ2NEZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwRml4ZWQ2NEZpeGVkNjQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBGaXhlZDY0Rml4ZWQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0TWFwRml4ZWQ2NEZpeGVkNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IG1hcF9maXhlZDY0X2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRNYXBGaXhlZDY0Rml4ZWQ2NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldE1hcEZpeGVkNjRGaXhlZDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IG1hcF9maXhlZDY0X2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRNYXBGaXhlZDY0Rml4ZWQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNNYXBTZml4ZWQzMlNmaXhlZDMyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBTZml4ZWQzMlNmaXhlZDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IG1hcF9zZml4ZWQzMl9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE1hcFNmaXhlZDMyU2ZpeGVkMzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IG1hcF9zZml4ZWQzMl9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwU2ZpeGVkMzJTZml4ZWQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBTZml4ZWQ2NFNmaXhlZDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwU2ZpeGVkNjRTZml4ZWQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFNmaXhlZDY0U2ZpeGVkNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldE1hcFNmaXhlZDY0U2ZpeGVkNjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldE1hcFNmaXhlZDY0U2ZpeGVkNjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgbWFwX2ludDMyX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwSW50MzJGbG9hdENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IG1hcF9pbnQzMl9mbG9hdCA9IDExOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcEludDMyRmxvYXQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyRmxvYXRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRNYXBJbnQzMkZsb2F0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IG1hcF9pbnQzMl9mbG9hdCA9IDExOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0TWFwSW50MzJGbG9hdE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBtYXBfaW50MzJfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldE1hcEludDMyRmxvYXRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBtYXBfaW50MzJfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldE1hcEludDMyRmxvYXRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IG1hcF9pbnQzMl9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBJbnQzMkRvdWJsZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBtYXBfaW50MzJfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJEb3VibGUoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyRG91YmxlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldE1hcEludDMyRG91YmxlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBtYXBfaW50MzJfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0TWFwSW50MzJEb3VibGVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IG1hcF9pbnQzMl9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRNYXBJbnQzMkRvdWJsZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgbWFwX2ludDMyX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldE1hcEludDMyRG91YmxlT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwQm9vbEJvb2xDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgbWFwX2Jvb2xfYm9vbCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcEJvb2xCb29sKAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwQm9vbEJvb2xNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldE1hcEJvb2xCb29sKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldE1hcEJvb2xCb29sTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldE1hcEJvb2xCb29sT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IG1hcF9ib29sX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0TWFwQm9vbEJvb2xPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBTdHJpbmdTdHJpbmdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmdfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwU3RyaW5nU3RyaW5nKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwU3RyaW5nU3RyaW5nTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0TWFwU3RyaW5nU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldE1hcFN0cmluZ1N0cmluZ01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmdfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldE1hcFN0cmluZ1N0cmluZ09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TWFwU3RyaW5nU3RyaW5nT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfaW50MzJfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBJbnQzMkJ5dGVzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2ludDMyX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJCeXRlcygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJCeXRlc01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldE1hcEludDMyQnl0ZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2ludDMyX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRNYXBJbnQzMkJ5dGVzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9pbnQzMl9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE1hcEludDMyQnl0ZXNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2ludDMyX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0TWFwSW50MzJCeXRlc09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcEludDMyRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJFbnVtKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkVudW1NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtPgogICAgZ2V0TWFwSW50MzJFbnVtKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtPgogICAgZ2V0TWFwSW50MzJFbnVtTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtIGdldE1hcEludDMyRW51bU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWFwRW51bSBnZXRNYXBJbnQzMkVudW1PclRocm93KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkVudW1WYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TWFwSW50MzJFbnVtVmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TWFwSW50MzJFbnVtVmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBJbnQzMkVudW1WYWx1ZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcEludDMyRW51bVZhbHVlT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJGb3JlaWduTWVzc2FnZSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+CiAgICBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPgogICAgZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX3N0cmluZ19mb3JlaWduX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX3N0cmluZ19mb3JlaWduX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPgogICAgZ2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfc3RyaW5nX2ZvcmVpZ25fbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPgogICAgZ2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfc3RyaW5nX2ZvcmVpZ25fbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX3N0cmluZ19mb3JlaWduX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyZndDsgbWFwX2ludDMyX2FsbF90eXBlcyA9IDE5OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcEludDMyQWxsVHlwZXNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMmZ3Q7IG1hcF9pbnQzMl9hbGxfdHlwZXMgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNNYXBJbnQzMkFsbFR5cGVzKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkFsbFR5cGVzTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+CiAgICBnZXRNYXBJbnQzMkFsbFR5cGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyZndDsgbWFwX2ludDMyX2FsbF90eXBlcyA9IDE5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+CiAgICBnZXRNYXBJbnQzMkFsbFR5cGVzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyZndDsgbWFwX2ludDMyX2FsbF90eXBlcyA9IDE5OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0TWFwSW50MzJBbGxUeXBlc09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyZndDsgbWFwX2ludDMyX2FsbF90eXBlcyA9IDE5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0TWFwSW50MzJBbGxUeXBlc09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVGVzdHMgbWFwcy4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXB9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0TWFwIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXApCiAgICAgIFRlc3RNYXBPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RNYXAubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdE1hcChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RNYXAoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdE1hcCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMySW50MzIoKTsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCk7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCk7CiAgICAgICAgY2FzZSA0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwVWludDY0VWludDY0KCk7CiAgICAgICAgY2FzZSA1OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCk7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ludDY0U2ludDY0KCk7CiAgICAgICAgY2FzZSA3OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKTsKICAgICAgICBjYXNlIDg6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpOwogICAgICAgIGNhc2UgOToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNmaXhlZDMyU2ZpeGVkMzIoKTsKICAgICAgICBjYXNlIDEwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgpOwogICAgICAgIGNhc2UgMTE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCk7CiAgICAgICAgY2FzZSAxMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRG91YmxlKCk7CiAgICAgICAgY2FzZSAxMzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEJvb2xCb29sKCk7CiAgICAgICAgY2FzZSAxNDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFN0cmluZ1N0cmluZygpOwogICAgICAgIGNhc2UgMTU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCk7CiAgICAgICAgY2FzZSAxNjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpOwogICAgICAgIGNhc2UgMTc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCk7CiAgICAgICAgY2FzZSAxODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlKCk7CiAgICAgICAgY2FzZSAxOToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyQWxsVHlwZXMoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfSU5UMzJfSU5UMzJfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcEludDMySW50MzJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBJbnQzMkludDMyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXBJbnQzMkludDMyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldE1hcEludDMySW50MzIoKSB7CiAgICAgIGlmIChtYXBJbnQzMkludDMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwSW50MzJJbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtYXBJbnQzMkludDMyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJJbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXBfaW50MzJfaW50MzIgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBJbnQzMkludDMyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMySW50MzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBJbnQzMkludDMyKCkgewogICAgICByZXR1cm4gZ2V0TWFwSW50MzJJbnQzMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXBfaW50MzJfaW50MzIgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBJbnQzMkludDMyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9pbnQzMl9pbnQzMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1hcEludDMySW50MzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9pbnQzMl9pbnQzMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1hcEludDMySW50MzJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0lOVDY0X0lOVDY0X0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBJbnQ2NEludDY0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50NjRJbnQ2NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXBJbnQ2NEludDY0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKSB7CiAgICAgIGlmIChtYXBJbnQ2NEludDY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwSW50NjRJbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtYXBJbnQ2NEludDY0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50NjRJbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBtYXBfaW50NjRfaW50NjQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBJbnQ2NEludDY0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50NjRJbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwSW50NjRJbnQ2NCgpIHsKICAgICAgcmV0dXJuIGdldE1hcEludDY0SW50NjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgbWFwX2ludDY0X2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwSW50NjRJbnQ2NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50NjRJbnQ2NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBtYXBfaW50NjRfaW50NjQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0TWFwSW50NjRJbnQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBtYXBfaW50NjRfaW50NjQgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0TWFwSW50NjRJbnQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX1VJTlQzMl9VSU5UMzJfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcFVpbnQzMlVpbnQzMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFVpbnQzMlVpbnQzMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXBVaW50MzJVaW50MzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkgewogICAgICBpZiAobWFwVWludDMyVWludDMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwVWludDMyVWludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcFVpbnQzMlVpbnQzMl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcFVpbnQzMlVpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBVaW50MzJVaW50MzIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwVWludDMyVWludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBVaW50MzJVaW50MzIoKSB7CiAgICAgIHJldHVybiBnZXRNYXBVaW50MzJVaW50MzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBtYXBfdWludDMyX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1hcFVpbnQzMlVpbnQzMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRNYXBVaW50MzJVaW50MzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBtYXBfdWludDMyX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1hcFVpbnQzMlVpbnQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFVpbnQzMlVpbnQzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9VSU5UNjRfVUlOVDY0X0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBVaW50NjRVaW50NjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBVaW50NjRVaW50NjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXBVaW50NjRVaW50NjRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0TWFwVWludDY0VWludDY0KCkgewogICAgICBpZiAobWFwVWludDY0VWludDY0XyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwVWludDY0VWludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcFVpbnQ2NFVpbnQ2NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcFVpbnQ2NFVpbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBVaW50NjRVaW50NjQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFVpbnQ2NFVpbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwVWludDY0VWludDY0KCkgewogICAgICByZXR1cm4gZ2V0TWFwVWludDY0VWludDY0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRNYXBVaW50NjRVaW50NjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IG1hcF91aW50NjRfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE1hcFVpbnQ2NFVpbnQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0TWFwVWludDY0VWludDY0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9TSU5UMzJfU0lOVDMyX0ZJRUxEX05VTUJFUiA9IDU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBTaW50MzJTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBTaW50MzJTaW50MzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwU2ludDMyU2ludDMyXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldE1hcFNpbnQzMlNpbnQzMigpIHsKICAgICAgaWYgKG1hcFNpbnQzMlNpbnQzMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcFNpbnQzMlNpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtYXBTaW50MzJTaW50MzJfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBTaW50MzJTaW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IG1hcF9zaW50MzJfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwU2ludDMyU2ludDMyKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNpbnQzMlNpbnQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFNpbnQzMlNpbnQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwU2ludDMyU2ludDMyKCkgewogICAgICByZXR1cm4gZ2V0TWFwU2ludDMyU2ludDMyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgbWFwX3NpbnQzMl9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBTaW50MzJTaW50MzJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNpbnQzMlNpbnQzMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IG1hcF9zaW50MzJfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TWFwU2ludDMyU2ludDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFNpbnQzMlNpbnQzMigpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgbWFwX3NpbnQzMl9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRNYXBTaW50MzJTaW50MzJPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfU0lOVDY0X1NJTlQ2NF9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwU2ludDY0U2ludDY0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwU2ludDY0U2ludDY0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwU2ludDY0U2ludDY0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpIHsKICAgICAgaWYgKG1hcFNpbnQ2NFNpbnQ2NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcFNpbnQ2NFNpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtYXBTaW50NjRTaW50NjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBTaW50NjRTaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ludDY0U2ludDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IG1hcF9zaW50NjRfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwU2ludDY0U2ludDY0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBTaW50NjRTaW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcFNpbnQ2NFNpbnQ2NCgpIHsKICAgICAgcmV0dXJuIGdldE1hcFNpbnQ2NFNpbnQ2NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IG1hcF9zaW50NjRfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwU2ludDY0U2ludDY0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBtYXBfc2ludDY0X3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRNYXBTaW50NjRTaW50NjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IG1hcF9zaW50NjRfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE1hcFNpbnQ2NFNpbnQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfRklYRUQzMl9GSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBGaXhlZDMyRml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEZpeGVkMzJGaXhlZDMyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRklYRUQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwRml4ZWQzMkZpeGVkMzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKSB7CiAgICAgIGlmIChtYXBGaXhlZDMyRml4ZWQzMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcEZpeGVkMzJGaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcEZpeGVkMzJGaXhlZDMyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TWFwRml4ZWQzMkZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwRml4ZWQzMkZpeGVkMzIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBGaXhlZDMyRml4ZWQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwRml4ZWQzMkZpeGVkMzIoKSB7CiAgICAgIHJldHVybiBnZXRNYXBGaXhlZDMyRml4ZWQzMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgbWFwX2ZpeGVkMzJfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1hcEZpeGVkMzJGaXhlZDMyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgbWFwX2ZpeGVkMzJfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1hcEZpeGVkMzJGaXhlZDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpeGVkMzJGaXhlZDMyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IG1hcF9maXhlZDMyX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRNYXBGaXhlZDMyRml4ZWQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpeGVkMzJGaXhlZDMyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0ZJWEVENjRfRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSA4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwRml4ZWQ2NEZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBGaXhlZDY0Rml4ZWQ2NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwRml4ZWQ2NEZpeGVkNjRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKSB7CiAgICAgIGlmIChtYXBGaXhlZDY0Rml4ZWQ2NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcEZpeGVkNjRGaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcEZpeGVkNjRGaXhlZDY0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TWFwRml4ZWQ2NEZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBtYXBfZml4ZWQ2NF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwRml4ZWQ2NEZpeGVkNjQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwRml4ZWQ2NEZpeGVkNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcEZpeGVkNjRGaXhlZDY0KCkgewogICAgICByZXR1cm4gZ2V0TWFwRml4ZWQ2NEZpeGVkNjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IG1hcF9maXhlZDY0X2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRNYXBGaXhlZDY0Rml4ZWQ2NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IG1hcF9maXhlZDY0X2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0TWFwRml4ZWQ2NEZpeGVkNjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBtYXBfZml4ZWQ2NF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE1hcEZpeGVkNjRGaXhlZDY0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX1NGSVhFRDMyX1NGSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBTZml4ZWQzMlNmaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwU2ZpeGVkMzJTZml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwU2ZpeGVkMzJTZml4ZWQzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCkgewogICAgICBpZiAobWFwU2ZpeGVkMzJTZml4ZWQzMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcFNmaXhlZDMyU2ZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwU2ZpeGVkMzJTZml4ZWQzMl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcFNmaXhlZDMyU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwU2ZpeGVkMzJTZml4ZWQzMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwU2ZpeGVkMzJTZml4ZWQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpIHsKICAgICAgcmV0dXJuIGdldE1hcFNmaXhlZDMyU2ZpeGVkMzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwU2ZpeGVkMzJTZml4ZWQzMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9TRklYRUQ2NF9TRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSAxMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcFNmaXhlZDY0U2ZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBTZml4ZWQ2NFNmaXhlZDY0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcFNmaXhlZDY0U2ZpeGVkNjRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGludGVybmFsR2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgpIHsKICAgICAgaWYgKG1hcFNmaXhlZDY0U2ZpeGVkNjRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNYXBTZml4ZWQ2NFNmaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcFNmaXhlZDY0U2ZpeGVkNjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBTZml4ZWQ2NFNmaXhlZDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBTZml4ZWQ2NFNmaXhlZDY0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuIGdldE1hcFNmaXhlZDY0U2ZpeGVkNjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcFNmaXhlZDY0U2ZpeGVkNjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRNYXBTZml4ZWQ2NFNmaXhlZDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0lOVDMyX0ZMT0FUX0ZJRUxEX05VTUJFUiA9IDExOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwSW50MzJGbG9hdERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0Pm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJGbG9hdEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZMT0FULAogICAgICAgICAgICAgICAgICAwRik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXBJbnQzMkZsb2F0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCkgewogICAgICBpZiAobWFwSW50MzJGbG9hdF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcEludDMyRmxvYXREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwSW50MzJGbG9hdF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcEludDMyRmxvYXRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJGbG9hdCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgbWFwX2ludDMyX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEludDMyRmxvYXQoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJGbG9hdCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyRmxvYXRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRNYXBJbnQzMkZsb2F0KCkgewogICAgICByZXR1cm4gZ2V0TWFwSW50MzJGbG9hdE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBtYXBfaW50MzJfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldE1hcEludDMyRmxvYXRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgbWFwX2ludDMyX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0TWFwSW50MzJGbG9hdE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgbWFwX2ludDMyX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0TWFwSW50MzJGbG9hdE9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0lOVDMyX0RPVUJMRV9GSUVMRF9OVU1CRVIgPSAxMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcEludDMyRG91YmxlRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMyRG91YmxlRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwSW50MzJEb3VibGVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpIHsKICAgICAgaWYgKG1hcEludDMyRG91YmxlXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwSW50MzJEb3VibGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwSW50MzJEb3VibGVfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBJbnQzMkRvdWJsZUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IG1hcF9pbnQzMl9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJEb3VibGUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkRvdWJsZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRNYXBJbnQzMkRvdWJsZSgpIHsKICAgICAgcmV0dXJuIGdldE1hcEludDMyRG91YmxlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBtYXBfaW50MzJfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0TWFwSW50MzJEb3VibGVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRG91YmxlKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBtYXBfaW50MzJfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldE1hcEludDMyRG91YmxlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgbWFwX2ludDMyX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRNYXBJbnQzMkRvdWJsZU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfQk9PTF9CT09MX0ZJRUxEX05VTUJFUiA9IDEzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwQm9vbEJvb2xEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBCb29sQm9vbEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkJPT0wsCiAgICAgICAgICAgICAgICAgIGZhbHNlKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwQm9vbEJvb2xfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGludGVybmFsR2V0TWFwQm9vbEJvb2woKSB7CiAgICAgIGlmIChtYXBCb29sQm9vbF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcEJvb2xCb29sRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcEJvb2xCb29sXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TWFwQm9vbEJvb2xDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwQm9vbEJvb2woKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEJvb2xCb29sKAogICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEJvb2xCb29sTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBnZXRNYXBCb29sQm9vbCgpIHsKICAgICAgcmV0dXJuIGdldE1hcEJvb2xCb29sTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IGdldE1hcEJvb2xCb29sTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgbWFwX2Jvb2xfYm9vbCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0TWFwQm9vbEJvb2xPckRlZmF1bHQoCiAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRNYXBCb29sQm9vbE9yVGhyb3coCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9TVFJJTkdfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDE0OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwU3RyaW5nU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBTdHJpbmdTdHJpbmdFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwU3RyaW5nU3RyaW5nXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKSB7CiAgICAgIGlmIChtYXBTdHJpbmdTdHJpbmdfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNYXBTdHJpbmdTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwU3RyaW5nU3RyaW5nXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TWFwU3RyaW5nU3RyaW5nQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFN0cmluZ1N0cmluZygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfc3RyaW5nX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBTdHJpbmdTdHJpbmcoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFN0cmluZ1N0cmluZygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFN0cmluZ1N0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldE1hcFN0cmluZ1N0cmluZygpIHsKICAgICAgcmV0dXJuIGdldE1hcFN0cmluZ1N0cmluZ01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmdfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNYXBTdHJpbmdTdHJpbmdNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFN0cmluZ1N0cmluZygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmdfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRNYXBTdHJpbmdTdHJpbmdPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwU3RyaW5nU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfc3RyaW5nX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TWFwU3RyaW5nU3RyaW5nT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfSU5UMzJfQllURVNfRklFTERfTlVNQkVSID0gMTU7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBJbnQzMkJ5dGVzRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBJbnQzMkJ5dGVzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXBJbnQzMkJ5dGVzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkgewogICAgICBpZiAobWFwSW50MzJCeXRlc18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcEludDMyQnl0ZXNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwSW50MzJCeXRlc187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcEludDMyQnl0ZXNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJCeXRlcygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2ludDMyX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEludDMyQnl0ZXMoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJCeXRlcygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyQnl0ZXNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRNYXBJbnQzMkJ5dGVzKCkgewogICAgICByZXR1cm4gZ2V0TWFwSW50MzJCeXRlc01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfaW50MzJfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldE1hcEludDMyQnl0ZXNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyQnl0ZXMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2ludDMyX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE1hcEludDMyQnl0ZXNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyQnl0ZXMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfaW50MzJfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0TWFwSW50MzJCeXRlc09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0lOVDMyX0VOVU1fRklFTERfTlVNQkVSID0gMTY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBJbnQzMkVudW1EZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBJbnQzMkVudW1FbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5FTlVNLAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtLk1BUF9FTlVNX0ZPTy5nZXROdW1iZXIoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcEludDMyRW51bV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKSB7CiAgICAgIGlmIChtYXBJbnQzMkVudW1fID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNYXBJbnQzMkVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwSW50MzJFbnVtXzsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtPiBtYXBJbnQzMkVudW1WYWx1ZUNvbnZlcnRlciA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5uZXdFbnVtQ29udmVydGVyKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWFwRW51bS5pbnRlcm5hbEdldFZhbHVlTWFwKCksCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtLlVOUkVDT0dOSVpFRCk7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtPgogICAgaW50ZXJuYWxHZXRBZGFwdGVkTWFwSW50MzJFbnVtTWFwKAogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXApIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLk1hcEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWFwRW51bSwgamF2YS5sYW5nLkludGVnZXI+KAogICAgICAgICAgICAgIG1hcCwgbWFwSW50MzJFbnVtVmFsdWVDb252ZXJ0ZXIpOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBJbnQzMkVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBJbnQzMkVudW0oCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJFbnVtTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0+CiAgICBnZXRNYXBJbnQzMkVudW0oKSB7CiAgICAgIHJldHVybiBnZXRNYXBJbnQzMkVudW1NYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtPgogICAgZ2V0TWFwSW50MzJFbnVtTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkTWFwSW50MzJFbnVtTWFwKAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5nZXRNYXAoKSk7fQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0gZ2V0TWFwSW50MzJFbnVtT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWFwRW51bSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpCiAgICAgICAgICAgICA/IG1hcEludDMyRW51bVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtIGdldE1hcEludDMyRW51bU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwSW50MzJFbnVtVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyRW51bVZhbHVlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TWFwSW50MzJFbnVtVmFsdWUoKSB7CiAgICAgIHJldHVybiBnZXRNYXBJbnQzMkVudW1WYWx1ZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TWFwSW50MzJFbnVtVmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRNYXBJbnQzMkVudW1WYWx1ZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRNYXBJbnQzMkVudW1WYWx1ZU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9JTlQzMl9GT1JFSUdOX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBJbnQzMkZvcmVpZ25NZXNzYWdlRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMyRm9yZWlnbk1lc3NhZ2VFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBtYXBJbnQzMkZvcmVpZ25NZXNzYWdlXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4KICAgIGludGVybmFsR2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZSgpIHsKICAgICAgaWYgKG1hcEludDMyRm9yZWlnbk1lc3NhZ2VfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNYXBJbnQzMkZvcmVpZ25NZXNzYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcEludDMyRm9yZWlnbk1lc3NhZ2VfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEludDMyRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyRm9yZWlnbk1lc3NhZ2VNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIGdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2VNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UmZ3Q7IG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9TVFJJTkdfRk9SRUlHTl9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDE4OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IG1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPgogICAgaW50ZXJuYWxHZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpIHsKICAgICAgaWYgKG1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfc3RyaW5nX2ZvcmVpZ25fbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IGdldE1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlKCkgewogICAgICByZXR1cm4gZ2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfc3RyaW5nX2ZvcmVpZ25fbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gZ2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX3N0cmluZ19mb3JlaWduX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIGdldE1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfc3RyaW5nX2ZvcmVpZ25fbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0lOVDMyX0FMTF9UWVBFU19GSUVMRF9OVU1CRVIgPSAxOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcEludDMyQWxsVHlwZXNEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBJbnQzMkFsbFR5cGVzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBtYXBJbnQzMkFsbFR5cGVzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+CiAgICBpbnRlcm5hbEdldE1hcEludDMyQWxsVHlwZXMoKSB7CiAgICAgIGlmIChtYXBJbnQzMkFsbFR5cGVzXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwSW50MzJBbGxUeXBlc0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtYXBJbnQzMkFsbFR5cGVzXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJBbGxUeXBlc0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkFsbFR5cGVzKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMmZ3Q7IG1hcF9pbnQzMl9hbGxfdHlwZXMgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJBbGxUeXBlcygKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkFsbFR5cGVzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJBbGxUeXBlc01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0TWFwSW50MzJBbGxUeXBlcygpIHsKICAgICAgcmV0dXJuIGdldE1hcEludDMyQWxsVHlwZXNNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzJmd0OyBtYXBfaW50MzJfYWxsX3R5cGVzID0gMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGdldE1hcEludDMyQWxsVHlwZXNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyQWxsVHlwZXMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzJmd0OyBtYXBfaW50MzJfYWxsX3R5cGVzID0gMTk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0TWFwSW50MzJBbGxUeXBlc09yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyQWxsVHlwZXMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMmZ3Q7IG1hcF9pbnQzMl9hbGxfdHlwZXMgPSAxOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRNYXBJbnQzMkFsbFR5cGVzT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJBbGxUeXBlcygpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCksCiAgICAgICAgICBNYXBJbnQzMkludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKSwKICAgICAgICAgIE1hcEludDY0SW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCksCiAgICAgICAgICBNYXBVaW50MzJVaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwVWludDY0VWludDY0KCksCiAgICAgICAgICBNYXBVaW50NjRVaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCksCiAgICAgICAgICBNYXBTaW50MzJTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUxvbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwU2ludDY0U2ludDY0KCksCiAgICAgICAgICBNYXBTaW50NjRTaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKSwKICAgICAgICAgIE1hcEZpeGVkMzJGaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDcpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCksCiAgICAgICAgICBNYXBGaXhlZDY0Rml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA4KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCksCiAgICAgICAgICBNYXBTZml4ZWQzMlNmaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKSwKICAgICAgICAgIE1hcFNmaXhlZDY0U2ZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTApOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKSwKICAgICAgICAgIE1hcEludDMyRmxvYXREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTEpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRG91YmxlKCksCiAgICAgICAgICBNYXBJbnQzMkRvdWJsZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUJvb2xlYW5NYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwQm9vbEJvb2woKSwKICAgICAgICAgIE1hcEJvb2xCb29sRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEzKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplU3RyaW5nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcFN0cmluZ1N0cmluZygpLAogICAgICAgICAgTWFwU3RyaW5nU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE0KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCksCiAgICAgICAgICBNYXBJbnQzMkJ5dGVzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDE1KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKSwKICAgICAgICAgIE1hcEludDMyRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNik7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLAogICAgICAgICAgTWFwSW50MzJGb3JlaWduTWVzc2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpLAogICAgICAgICAgTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyQWxsVHlwZXMoKSwKICAgICAgICAgIE1hcEludDMyQWxsVHlwZXNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTkpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBtYXBJbnQzMkludDMyX18gPSBNYXBJbnQzMkludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBtYXBJbnQzMkludDMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgbWFwSW50NjRJbnQ2NF9fID0gTWFwSW50NjRJbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgbWFwSW50NjRJbnQ2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgbWFwVWludDMyVWludDMyX18gPSBNYXBVaW50MzJVaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIG1hcFVpbnQzMlVpbnQzMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgbWFwVWludDY0VWludDY0X18gPSBNYXBVaW50NjRVaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQsIG1hcFVpbnQ2NFVpbnQ2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgbWFwU2ludDMyU2ludDMyX18gPSBNYXBTaW50MzJTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIG1hcFNpbnQzMlNpbnQzMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgbWFwU2ludDY0U2ludDY0X18gPSBNYXBTaW50NjRTaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYsIG1hcFNpbnQ2NFNpbnQ2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBtYXBGaXhlZDMyRml4ZWQzMl9fID0gTWFwRml4ZWQzMkZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcsIG1hcEZpeGVkMzJGaXhlZDMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIG1hcEZpeGVkNjRGaXhlZDY0X18gPSBNYXBGaXhlZDY0Rml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOCwgbWFwRml4ZWQ2NEZpeGVkNjRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBtYXBTZml4ZWQzMlNmaXhlZDMyX18gPSBNYXBTZml4ZWQzMlNmaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5LCBtYXBTZml4ZWQzMlNmaXhlZDMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgbWFwU2ZpeGVkNjRTZml4ZWQ2NF9fID0gTWFwU2ZpeGVkNjRTZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTAsIG1hcFNmaXhlZDY0U2ZpeGVkNjRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIG1hcEludDMyRmxvYXRfXyA9IE1hcEludDMyRmxvYXREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExLCBtYXBJbnQzMkZsb2F0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBtYXBJbnQzMkRvdWJsZV9fID0gTWFwSW50MzJEb3VibGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyLCBtYXBJbnQzMkRvdWJsZV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBtYXBCb29sQm9vbF9fID0gTWFwQm9vbEJvb2xEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzLCBtYXBCb29sQm9vbF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwU3RyaW5nU3RyaW5nKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBtYXBTdHJpbmdTdHJpbmdfXyA9IE1hcFN0cmluZ1N0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQsIG1hcFN0cmluZ1N0cmluZ19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwSW50MzJCeXRlcygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgbWFwSW50MzJCeXRlc19fID0gTWFwSW50MzJCeXRlc0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTUsIG1hcEludDMyQnl0ZXNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwSW50MzJFbnVtKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIG1hcEludDMyRW51bV9fID0gTWFwSW50MzJFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNiwgbWFwSW50MzJFbnVtX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPgogICAgICAgIG1hcEludDMyRm9yZWlnbk1lc3NhZ2VfXyA9IE1hcEludDMyRm9yZWlnbk1lc3NhZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3LCBtYXBJbnQzMkZvcmVpZ25NZXNzYWdlX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+CiAgICAgICAgbWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VfXyA9IE1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOCwgbWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwSW50MzJBbGxUeXBlcygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4KICAgICAgICBtYXBJbnQzMkFsbFR5cGVzX18gPSBNYXBJbnQzMkFsbFR5cGVzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxOSwgbWFwSW50MzJBbGxUeXBlc19fKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXApIG9iajsKCiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcFVpbnQzMlVpbnQzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwVWludDY0VWludDY0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcFNpbnQzMlNpbnQzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEZpeGVkMzJGaXhlZDMyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcFNmaXhlZDMyU2ZpeGVkMzIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcEludDMyRG91YmxlKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwQm9vbEJvb2woKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEJvb2xCb29sKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcFN0cmluZ1N0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwSW50MzJCeXRlcygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwSW50MzJCeXRlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwSW50MzJFbnVtKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwSW50MzJBbGxUeXBlcygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwSW50MzJBbGxUeXBlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX0lOVDMyX0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcEludDMySW50MzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX0lOVDY0X0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfVUlOVDMyX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfVUlOVDY0X1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfU0lOVDMyX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfU0lOVDY0X1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1BUF9GSVhFRDMyX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1BUF9GSVhFRDY0X0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX1NGSVhFRDMyX1NGSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX1NGSVhFRDY0X1NGSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX0lOVDMyX0ZMT0FUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1BUF9JTlQzMl9ET1VCTEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1BUF9CT09MX0JPT0xfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TWFwQm9vbEJvb2woKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfU1RSSU5HX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX0lOVDMyX0JZVEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcEludDMyQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfSU5UMzJfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX0lOVDMyX0ZPUkVJR05fTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfU1RSSU5HX0ZPUkVJR05fTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcEludDMyQWxsVHlwZXMoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfSU5UMzJfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcEludDMyQWxsVHlwZXMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRlc3RzIG1hcHMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcCkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFVpbnQzMlVpbnQzMigpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpOwogICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpOwogICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpOwogICAgICAgICAgY2FzZSA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCk7CiAgICAgICAgICBjYXNlIDEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCk7CiAgICAgICAgICBjYXNlIDExOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCk7CiAgICAgICAgICBjYXNlIDEyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpOwogICAgICAgICAgY2FzZSAxMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwQm9vbEJvb2woKTsKICAgICAgICAgIGNhc2UgMTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFN0cmluZ1N0cmluZygpOwogICAgICAgICAgY2FzZSAxNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJCeXRlcygpOwogICAgICAgICAgY2FzZSAxNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCk7CiAgICAgICAgICBjYXNlIDE3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCk7CiAgICAgICAgICBjYXNlIDE4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpOwogICAgICAgICAgY2FzZSAxOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJBbGxUeXBlcygpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMySW50MzIoKTsKICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDY0SW50NjQoKTsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcFVpbnQzMlVpbnQzMigpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDY0VWludDY0KCk7CiAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50MzJTaW50MzIoKTsKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcFNpbnQ2NFNpbnQ2NCgpOwogICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQzMkZpeGVkMzIoKTsKICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEZpeGVkNjRGaXhlZDY0KCk7CiAgICAgICAgICBjYXNlIDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBTZml4ZWQzMlNmaXhlZDMyKCk7CiAgICAgICAgICBjYXNlIDEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ZpeGVkNjRTZml4ZWQ2NCgpOwogICAgICAgICAgY2FzZSAxMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRmxvYXQoKTsKICAgICAgICAgIGNhc2UgMTI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkRvdWJsZSgpOwogICAgICAgICAgY2FzZSAxMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEJvb2xCb29sKCk7CiAgICAgICAgICBjYXNlIDE0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nU3RyaW5nKCk7CiAgICAgICAgICBjYXNlIDE1OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJCeXRlcygpOwogICAgICAgICAgY2FzZSAxNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRW51bSgpOwogICAgICAgICAgY2FzZSAxNzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKTsKICAgICAgICAgIGNhc2UgMTg6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpOwogICAgICAgICAgY2FzZSAxOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyQWxsVHlwZXMoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkludDMyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQ2NEludDY0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50MzJVaW50MzIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFVpbnQ2NFVpbnQ2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDMyU2ludDMyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50NjRTaW50NjQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpeGVkMzJGaXhlZDMyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaXhlZDY0Rml4ZWQ2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ZpeGVkMzJTZml4ZWQzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ZpeGVkNjRTZml4ZWQ2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGbG9hdCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJEb3VibGUoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEJvb2xCb29sKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdTdHJpbmcoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyQnl0ZXMoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRW51bSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyQWxsVHlwZXMoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMySW50MzJfID0gaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCk7CiAgICAgICAgICByZXN1bHQubWFwSW50MzJJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDY0SW50NjRfID0gaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCk7CiAgICAgICAgICByZXN1bHQubWFwSW50NjRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFVpbnQzMlVpbnQzMl8gPSBpbnRlcm5hbEdldE1hcFVpbnQzMlVpbnQzMigpOwogICAgICAgICAgcmVzdWx0Lm1hcFVpbnQzMlVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFVpbnQ2NFVpbnQ2NF8gPSBpbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpOwogICAgICAgICAgcmVzdWx0Lm1hcFVpbnQ2NFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFNpbnQzMlNpbnQzMl8gPSBpbnRlcm5hbEdldE1hcFNpbnQzMlNpbnQzMigpOwogICAgICAgICAgcmVzdWx0Lm1hcFNpbnQzMlNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFNpbnQ2NFNpbnQ2NF8gPSBpbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpOwogICAgICAgICAgcmVzdWx0Lm1hcFNpbnQ2NFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEZpeGVkMzJGaXhlZDMyXyA9IGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKTsKICAgICAgICAgIHJlc3VsdC5tYXBGaXhlZDMyRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEZpeGVkNjRGaXhlZDY0XyA9IGludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKTsKICAgICAgICAgIHJlc3VsdC5tYXBGaXhlZDY0Rml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFNmaXhlZDMyU2ZpeGVkMzJfID0gaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCk7CiAgICAgICAgICByZXN1bHQubWFwU2ZpeGVkMzJTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFNmaXhlZDY0U2ZpeGVkNjRfID0gaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCk7CiAgICAgICAgICByZXN1bHQubWFwU2ZpeGVkNjRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMyRmxvYXRfID0gaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCk7CiAgICAgICAgICByZXN1bHQubWFwSW50MzJGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMyRG91YmxlXyA9IGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKTsKICAgICAgICAgIHJlc3VsdC5tYXBJbnQzMkRvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEJvb2xCb29sXyA9IGludGVybmFsR2V0TWFwQm9vbEJvb2woKTsKICAgICAgICAgIHJlc3VsdC5tYXBCb29sQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFN0cmluZ1N0cmluZ18gPSBpbnRlcm5hbEdldE1hcFN0cmluZ1N0cmluZygpOwogICAgICAgICAgcmVzdWx0Lm1hcFN0cmluZ1N0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMyQnl0ZXNfID0gaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCk7CiAgICAgICAgICByZXN1bHQubWFwSW50MzJCeXRlc18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMyRW51bV8gPSBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpOwogICAgICAgICAgcmVzdWx0Lm1hcEludDMyRW51bV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMyRm9yZWlnbk1lc3NhZ2VfID0gaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuYnVpbGQoTWFwSW50MzJGb3JlaWduTWVzc2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlXyA9IGludGVybmFsR2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoKS5idWlsZChNYXBTdHJpbmdGb3JlaWduTWVzc2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMyQWxsVHlwZXNfID0gaW50ZXJuYWxHZXRNYXBJbnQzMkFsbFR5cGVzKCkuYnVpbGQoTWFwSW50MzJBbGxUeXBlc0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXApIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXApb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkludDMyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEludDMySW50MzIoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDY0SW50NjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwSW50NjRJbnQ2NCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDMyVWludDMyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcFVpbnQzMlVpbnQzMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDY0VWludDY0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDMyU2ludDMyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcFNpbnQzMlNpbnQzMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDY0U2ludDY0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQzMkZpeGVkMzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpeGVkNjRGaXhlZDY0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTZml4ZWQzMlNmaXhlZDMyKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcFNmaXhlZDMyU2ZpeGVkMzIoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGbG9hdCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkRvdWJsZSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwQm9vbEJvb2woKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwQm9vbEJvb2woKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFN0cmluZ1N0cmluZygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyQnl0ZXMoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwSW50MzJCeXRlcygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJFbnVtKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEludDMyRW51bSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJBbGxUeXBlcygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBJbnQzMkFsbFR5cGVzKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIG1hcEludDMySW50MzJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcEludDMySW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJJbnQzMigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwSW50MzJJbnQzMl9fLmdldEtleSgpLCBtYXBJbnQzMkludDMyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIG1hcEludDY0SW50NjRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcEludDY0SW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50NjRJbnQ2NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwSW50NjRJbnQ2NF9fLmdldEtleSgpLCBtYXBJbnQ2NEludDY0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIG1hcFVpbnQzMlVpbnQzMl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwVWludDMyVWludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFVpbnQzMlVpbnQzMigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwVWludDMyVWludDMyX18uZ2V0S2V5KCksIG1hcFVpbnQzMlVpbnQzMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBtYXBVaW50NjRVaW50NjRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcFVpbnQ2NFVpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50NjRVaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcFVpbnQ2NFVpbnQ2NF9fLmdldEtleSgpLCBtYXBVaW50NjRVaW50NjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgbWFwU2ludDMyU2ludDMyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXBTaW50MzJTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDMyU2ludDMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBTaW50MzJTaW50MzJfXy5nZXRLZXkoKSwgbWFwU2ludDMyU2ludDMyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIG1hcFNpbnQ2NFNpbnQ2NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwU2ludDY0U2ludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNpbnQ2NFNpbnQ2NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwU2ludDY0U2ludDY0X18uZ2V0S2V5KCksIG1hcFNpbnQ2NFNpbnQ2NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA1ODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBtYXBGaXhlZDMyRml4ZWQzMl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwRml4ZWQzMkZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQzMkZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcEZpeGVkMzJGaXhlZDMyX18uZ2V0S2V5KCksIG1hcEZpeGVkMzJGaXhlZDMyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgICBjYXNlIDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIG1hcEZpeGVkNjRGaXhlZDY0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXBGaXhlZDY0Rml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaXhlZDY0Rml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwRml4ZWQ2NEZpeGVkNjRfXy5nZXRLZXkoKSwgbWFwRml4ZWQ2NEZpeGVkNjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NgogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgbWFwU2ZpeGVkMzJTZml4ZWQzMl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwU2ZpeGVkMzJTZml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTZml4ZWQzMlNmaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBTZml4ZWQzMlNmaXhlZDMyX18uZ2V0S2V5KCksIG1hcFNmaXhlZDMyU2ZpeGVkMzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NAogICAgICAgICAgICAgIGNhc2UgODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgbWFwU2ZpeGVkNjRTZml4ZWQ2NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwU2ZpeGVkNjRTZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTZml4ZWQ2NFNmaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBTZml4ZWQ2NFNmaXhlZDY0X18uZ2V0S2V5KCksIG1hcFNmaXhlZDY0U2ZpeGVkNjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgICAgICAgIG1hcEludDMyRmxvYXRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcEludDMyRmxvYXREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGbG9hdCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwSW50MzJGbG9hdF9fLmdldEtleSgpLCBtYXBJbnQzMkZsb2F0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTAKICAgICAgICAgICAgICBjYXNlIDk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgICAgICAgbWFwSW50MzJEb3VibGVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcEludDMyRG91YmxlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRG91YmxlKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBJbnQzMkRvdWJsZV9fLmdldEtleSgpLCBtYXBJbnQzMkRvdWJsZV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk4CiAgICAgICAgICAgICAgY2FzZSAxMDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgICAgICAgbWFwQm9vbEJvb2xfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcEJvb2xCb29sRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEJvb2xCb29sKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBCb29sQm9vbF9fLmdldEtleSgpLCBtYXBCb29sQm9vbF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNgogICAgICAgICAgICAgIGNhc2UgMTE0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBtYXBTdHJpbmdTdHJpbmdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcFN0cmluZ1N0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcFN0cmluZ1N0cmluZ19fLmdldEtleSgpLCBtYXBTdHJpbmdTdHJpbmdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTQKICAgICAgICAgICAgICBjYXNlIDEyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgICAgICAgbWFwSW50MzJCeXRlc19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwSW50MzJCeXRlc0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkJ5dGVzKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBJbnQzMkJ5dGVzX18uZ2V0S2V5KCksIG1hcEludDMyQnl0ZXNfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjIKICAgICAgICAgICAgICBjYXNlIDEzMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBtYXBJbnQzMkVudW1fXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcEludDMyRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkVudW0oKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcEludDMyRW51bV9fLmdldEtleSgpLCBtYXBJbnQzMkVudW1fXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzAKICAgICAgICAgICAgICBjYXNlIDEzODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4KICAgICAgICAgICAgICAgIG1hcEludDMyRm9yZWlnbk1lc3NhZ2VfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcEludDMyRm9yZWlnbk1lc3NhZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwSW50MzJGb3JlaWduTWVzc2FnZV9fLmdldEtleSgpLCBtYXBJbnQzMkZvcmVpZ25NZXNzYWdlX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM4CiAgICAgICAgICAgICAgY2FzZSAxNDY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4KICAgICAgICAgICAgICAgIG1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXBTdHJpbmdGb3JlaWduTWVzc2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VfXy5nZXRLZXkoKSwgbWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDYKICAgICAgICAgICAgICBjYXNlIDE1NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+CiAgICAgICAgICAgICAgICBtYXBJbnQzMkFsbFR5cGVzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXBJbnQzMkFsbFR5cGVzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyQWxsVHlwZXMoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcEludDMyQWxsVHlwZXNfXy5nZXRLZXkoKSwgbWFwSW50MzJBbGxUeXBlc19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1NAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcEludDMySW50MzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCkgewogICAgICAgIGlmIChtYXBJbnQzMkludDMyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEludDMySW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEludDMySW50MzJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkludDMyKCkgewogICAgICAgIGlmIChtYXBJbnQzMkludDMyXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBJbnQzMkludDMyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwSW50MzJJbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW1hcEludDMySW50MzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBJbnQzMkludDMyXyA9IG1hcEludDMySW50MzJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtYXBJbnQzMkludDMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcEludDMySW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXBfaW50MzJfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBJbnQzMkludDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJJbnQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBJbnQzMkludDMyKCkgewogICAgICAgIHJldHVybiBnZXRNYXBJbnQzMkludDMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9pbnQzMl9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1hcEludDMySW50MzJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXBfaW50MzJfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRNYXBJbnQzMkludDMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ludDMyX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJJbnQzMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMySW50MzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwSW50MzJJbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJJbnQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ludDMyX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBJbnQzMkludDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwSW50MzJJbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMySW50MzIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9pbnQzMl9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwSW50MzJJbnQzMigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMySW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9pbnQzMl9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwSW50MzJJbnQzMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwSW50NjRJbnQ2NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKSB7CiAgICAgICAgaWYgKG1hcEludDY0SW50NjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwSW50NjRJbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwSW50NjRJbnQ2NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDY0SW50NjQoKSB7CiAgICAgICAgaWYgKG1hcEludDY0SW50NjRfID09IG51bGwpIHsKICAgICAgICAgIG1hcEludDY0SW50NjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBJbnQ2NEludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwSW50NjRJbnQ2NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG1hcEludDY0SW50NjRfID0gbWFwSW50NjRJbnQ2NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcEludDY0SW50NjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50NjRJbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IG1hcF9pbnQ2NF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEludDY0SW50NjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50NjRJbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRNYXBJbnQ2NEludDY0KCkgewogICAgICAgIHJldHVybiBnZXRNYXBJbnQ2NEludDY0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IG1hcF9pbnQ2NF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcEludDY0SW50NjRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50NjRJbnQ2NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBtYXBfaW50NjRfaW50NjQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0TWFwSW50NjRJbnQ2NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwSW50NjRJbnQ2NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgbWFwX2ludDY0X2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE1hcEludDY0SW50NjRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwSW50NjRJbnQ2NCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNYXBJbnQ2NEludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQ2NEludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBtYXBfaW50NjRfaW50NjQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcEludDY0SW50NjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQ2NEludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwSW50NjRJbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDY0SW50NjQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IG1hcF9pbnQ2NF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwSW50NjRJbnQ2NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50NjRJbnQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgbWFwX2ludDY0X2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBJbnQ2NEludDY0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDY0SW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXBVaW50MzJVaW50MzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKSB7CiAgICAgICAgaWYgKG1hcFVpbnQzMlVpbnQzMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBVaW50MzJVaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcFVpbnQzMlVpbnQzMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFVpbnQzMlVpbnQzMigpIHsKICAgICAgICBpZiAobWFwVWludDMyVWludDMyXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBVaW50MzJVaW50MzJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBVaW50MzJVaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtYXBVaW50MzJVaW50MzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBVaW50MzJVaW50MzJfID0gbWFwVWludDMyVWludDMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwVWludDMyVWludDMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcFVpbnQzMlVpbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFVpbnQzMlVpbnQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBtYXBfdWludDMyX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcFVpbnQzMlVpbnQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwVWludDMyVWludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1hcFVpbnQzMlVpbnQzMigpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwVWludDMyVWludDMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBVaW50MzJVaW50MzJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRNYXBVaW50MzJVaW50MzJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRNYXBVaW50MzJVaW50MzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwVWludDMyVWludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50MzJVaW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcFVpbnQzMlVpbnQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDMyVWludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwVWludDMyVWludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDMyVWludDMyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IG1hcF91aW50MzJfdWludDMyID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBVaW50MzJVaW50MzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50MzJVaW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcFVpbnQzMlVpbnQzMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50MzJVaW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXBVaW50NjRVaW50NjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKSB7CiAgICAgICAgaWYgKG1hcFVpbnQ2NFVpbnQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBVaW50NjRVaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcFVpbnQ2NFVpbnQ2NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFVpbnQ2NFVpbnQ2NCgpIHsKICAgICAgICBpZiAobWFwVWludDY0VWludDY0XyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBVaW50NjRVaW50NjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBVaW50NjRVaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtYXBVaW50NjRVaW50NjRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBVaW50NjRVaW50NjRfID0gbWFwVWludDY0VWludDY0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwVWludDY0VWludDY0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcFVpbnQ2NFVpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBtYXBfdWludDY0X3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcFVpbnQ2NFVpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFVpbnQ2NFVpbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRNYXBVaW50NjRVaW50NjQoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcFVpbnQ2NFVpbnQ2NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IG1hcF91aW50NjRfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwVWludDY0VWludDY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IG1hcF91aW50NjRfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE1hcFVpbnQ2NFVpbnQ2NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwVWludDY0VWludDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IG1hcF91aW50NjRfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE1hcFVpbnQ2NFVpbnQ2NE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwVWludDY0VWludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50NjRVaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcFVpbnQ2NFVpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFVpbnQ2NFVpbnQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcFVpbnQ2NFVpbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcFVpbnQ2NFVpbnQ2NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBtYXBfdWludDY0X3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwVWludDY0VWludDY0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50NjRVaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcFVpbnQ2NFVpbnQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50NjRVaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXBTaW50MzJTaW50MzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKSB7CiAgICAgICAgaWYgKG1hcFNpbnQzMlNpbnQzMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBTaW50MzJTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcFNpbnQzMlNpbnQzMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNpbnQzMlNpbnQzMigpIHsKICAgICAgICBpZiAobWFwU2ludDMyU2ludDMyXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBTaW50MzJTaW50MzJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBTaW50MzJTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtYXBTaW50MzJTaW50MzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBTaW50MzJTaW50MzJfID0gbWFwU2ludDMyU2ludDMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwU2ludDMyU2ludDMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcFNpbnQzMlNpbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNpbnQzMlNpbnQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBtYXBfc2ludDMyX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcFNpbnQzMlNpbnQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwU2ludDMyU2ludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1hcFNpbnQzMlNpbnQzMigpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwU2ludDMyU2ludDMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgbWFwX3NpbnQzMl9zaW50MzIgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBTaW50MzJTaW50MzJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgbWFwX3NpbnQzMl9zaW50MzIgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRNYXBTaW50MzJTaW50MzJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgbWFwX3NpbnQzMl9zaW50MzIgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRNYXBTaW50MzJTaW50MzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwU2ludDMyU2ludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50MzJTaW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgbWFwX3NpbnQzMl9zaW50MzIgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcFNpbnQzMlNpbnQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDMyU2ludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwU2ludDMyU2ludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDMyU2ludDMyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IG1hcF9zaW50MzJfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBTaW50MzJTaW50MzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50MzJTaW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgbWFwX3NpbnQzMl9zaW50MzIgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcFNpbnQzMlNpbnQzMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50MzJTaW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXBTaW50NjRTaW50NjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKSB7CiAgICAgICAgaWYgKG1hcFNpbnQ2NFNpbnQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBTaW50NjRTaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcFNpbnQ2NFNpbnQ2NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNpbnQ2NFNpbnQ2NCgpIHsKICAgICAgICBpZiAobWFwU2ludDY0U2ludDY0XyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBTaW50NjRTaW50NjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBTaW50NjRTaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtYXBTaW50NjRTaW50NjRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBTaW50NjRTaW50NjRfID0gbWFwU2ludDY0U2ludDY0Xy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwU2ludDY0U2ludDY0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcFNpbnQ2NFNpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBtYXBfc2ludDY0X3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcFNpbnQ2NFNpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFNpbnQ2NFNpbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRNYXBTaW50NjRTaW50NjQoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcFNpbnQ2NFNpbnQ2NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IG1hcF9zaW50NjRfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwU2ludDY0U2ludDY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IG1hcF9zaW50NjRfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE1hcFNpbnQ2NFNpbnQ2NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwU2ludDY0U2ludDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IG1hcF9zaW50NjRfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE1hcFNpbnQ2NFNpbnQ2NE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwU2ludDY0U2ludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50NjRTaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgbWFwX3NpbnQ2NF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcFNpbnQ2NFNpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNpbnQ2NFNpbnQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcFNpbnQ2NFNpbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcFNpbnQ2NFNpbnQ2NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBtYXBfc2ludDY0X3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwU2ludDY0U2ludDY0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50NjRTaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgbWFwX3NpbnQ2NF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcFNpbnQ2NFNpbnQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50NjRTaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXBGaXhlZDMyRml4ZWQzMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpeGVkMzJGaXhlZDMyKCkgewogICAgICAgIGlmIChtYXBGaXhlZDMyRml4ZWQzMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBGaXhlZDMyRml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwRml4ZWQzMkZpeGVkMzJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaXhlZDMyRml4ZWQzMigpIHsKICAgICAgICBpZiAobWFwRml4ZWQzMkZpeGVkMzJfID09IG51bGwpIHsKICAgICAgICAgIG1hcEZpeGVkMzJGaXhlZDMyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwRml4ZWQzMkZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtYXBGaXhlZDMyRml4ZWQzMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG1hcEZpeGVkMzJGaXhlZDMyXyA9IG1hcEZpeGVkMzJGaXhlZDMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwRml4ZWQzMkZpeGVkMzJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwRml4ZWQzMkZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IG1hcF9maXhlZDMyX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBGaXhlZDMyRml4ZWQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBGaXhlZDMyRml4ZWQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBGaXhlZDMyRml4ZWQzMigpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwRml4ZWQzMkZpeGVkMzJNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IG1hcF9maXhlZDMyX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBGaXhlZDMyRml4ZWQzMk1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgbWFwX2ZpeGVkMzJfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE1hcEZpeGVkMzJGaXhlZDMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwRml4ZWQzMkZpeGVkMzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNYXBGaXhlZDMyRml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQzMkZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBGaXhlZDMyRml4ZWQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQzMkZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE11dGFibGVNYXBGaXhlZDMyRml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEZpeGVkMzJGaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgbWFwX2ZpeGVkMzJfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwRml4ZWQzMkZpeGVkMzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaXhlZDMyRml4ZWQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IG1hcF9maXhlZDMyX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcEZpeGVkMzJGaXhlZDMyKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpeGVkMzJGaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwRml4ZWQ2NEZpeGVkNjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpIHsKICAgICAgICBpZiAobWFwRml4ZWQ2NEZpeGVkNjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwRml4ZWQ2NEZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEZpeGVkNjRGaXhlZDY0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQ2NEZpeGVkNjQoKSB7CiAgICAgICAgaWYgKG1hcEZpeGVkNjRGaXhlZDY0XyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBGaXhlZDY0Rml4ZWQ2NF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEZpeGVkNjRGaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwRml4ZWQ2NEZpeGVkNjRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBGaXhlZDY0Rml4ZWQ2NF8gPSBtYXBGaXhlZDY0Rml4ZWQ2NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcEZpeGVkNjRGaXhlZDY0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcEZpeGVkNjRGaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBtYXBfZml4ZWQ2NF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwRml4ZWQ2NEZpeGVkNjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEZpeGVkNjRGaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcEZpeGVkNjRGaXhlZDY0KCkgewogICAgICAgIHJldHVybiBnZXRNYXBGaXhlZDY0Rml4ZWQ2NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcEZpeGVkNjRGaXhlZDY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBtYXBfZml4ZWQ2NF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE1hcEZpeGVkNjRGaXhlZDY0T3JEZWZhdWx0KAogICAgICAgICAgbG9uZyBrZXksCiAgICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IG1hcF9maXhlZDY0X2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0TWFwRml4ZWQ2NEZpeGVkNjRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwRml4ZWQ2NEZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpeGVkNjRGaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwRml4ZWQ2NEZpeGVkNjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaXhlZDY0Rml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcEZpeGVkNjRGaXhlZDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQ2NEZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBtYXBfZml4ZWQ2NF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBGaXhlZDY0Rml4ZWQ2NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQ2NEZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBtYXBfZml4ZWQ2NF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBGaXhlZDY0Rml4ZWQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaXhlZDY0Rml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcFNmaXhlZDMyU2ZpeGVkMzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCkgewogICAgICAgIGlmIChtYXBTZml4ZWQzMlNmaXhlZDMyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIE1hcFNmaXhlZDMyU2ZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcFNmaXhlZDMyU2ZpeGVkMzJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTZml4ZWQzMlNmaXhlZDMyKCkgewogICAgICAgIGlmIChtYXBTZml4ZWQzMlNmaXhlZDMyXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBTZml4ZWQzMlNmaXhlZDMyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwU2ZpeGVkMzJTZml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW1hcFNmaXhlZDMyU2ZpeGVkMzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBTZml4ZWQzMlNmaXhlZDMyXyA9IG1hcFNmaXhlZDMyU2ZpeGVkMzJfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtYXBTZml4ZWQzMlNmaXhlZDMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcFNmaXhlZDMyU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBTZml4ZWQzMlNmaXhlZDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwU2ZpeGVkMzJTZml4ZWQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCkgewogICAgICAgIHJldHVybiBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IG1hcF9zZml4ZWQzMl9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1hcFNmaXhlZDMyU2ZpeGVkMzJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwU2ZpeGVkMzJTZml4ZWQzMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwU2ZpeGVkMzJTZml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBTZml4ZWQzMlNmaXhlZDMyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTZml4ZWQzMlNmaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwU2ZpeGVkMzJTZml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IG1hcF9zZml4ZWQzMl9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwU2ZpeGVkMzJTZml4ZWQzMigKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IG1hcF9zZml4ZWQzMl9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwU2ZpeGVkMzJTZml4ZWQzMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTZml4ZWQzMlNmaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwU2ZpeGVkNjRTZml4ZWQ2NF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKSB7CiAgICAgICAgaWYgKG1hcFNmaXhlZDY0U2ZpeGVkNjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwU2ZpeGVkNjRTZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwU2ZpeGVkNjRTZml4ZWQ2NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDY0U2ZpeGVkNjQoKSB7CiAgICAgICAgaWYgKG1hcFNmaXhlZDY0U2ZpeGVkNjRfID09IG51bGwpIHsKICAgICAgICAgIG1hcFNmaXhlZDY0U2ZpeGVkNjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBTZml4ZWQ2NFNmaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwU2ZpeGVkNjRTZml4ZWQ2NF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG1hcFNmaXhlZDY0U2ZpeGVkNjRfID0gbWFwU2ZpeGVkNjRTZml4ZWQ2NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcFNmaXhlZDY0U2ZpeGVkNjRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBTZml4ZWQ2NFNmaXhlZDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFNmaXhlZDY0U2ZpeGVkNjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRNYXBTZml4ZWQ2NFNmaXhlZDY0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwU2ZpeGVkNjRTZml4ZWQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ZpeGVkNjRTZml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwU2ZpeGVkNjRTZml4ZWQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVNYXBTZml4ZWQ2NFNmaXhlZDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ZpeGVkNjRTZml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ZpeGVkNjRTZml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwU2ZpeGVkNjRTZml4ZWQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTZml4ZWQ2NFNmaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcEludDMyRmxvYXRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJGbG9hdCgpIHsKICAgICAgICBpZiAobWFwSW50MzJGbG9hdF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBJbnQzMkZsb2F0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBJbnQzMkZsb2F0XzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRmxvYXQoKSB7CiAgICAgICAgaWYgKG1hcEludDMyRmxvYXRfID09IG51bGwpIHsKICAgICAgICAgIG1hcEludDMyRmxvYXRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBJbnQzMkZsb2F0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwSW50MzJGbG9hdF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG1hcEludDMyRmxvYXRfID0gbWFwSW50MzJGbG9hdF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcEludDMyRmxvYXRfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJGbG9hdENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IG1hcF9pbnQzMl9mbG9hdCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBJbnQzMkZsb2F0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJGbG9hdE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0TWFwSW50MzJGbG9hdCgpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwSW50MzJGbG9hdE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBtYXBfaW50MzJfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldE1hcEludDMyRmxvYXRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJGbG9hdCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBtYXBfaW50MzJfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRNYXBJbnQzMkZsb2F0T3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJGbG9hdCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgbWFwX2ludDMyX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0TWFwSW50MzJGbG9hdE9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcEludDMyRmxvYXQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRmxvYXQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IG1hcF9pbnQzMl9mbG9hdCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcEludDMyRmxvYXQoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRmxvYXQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwSW50MzJGbG9hdCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRmxvYXQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IG1hcF9pbnQzMl9mbG9hdCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1hcEludDMyRmxvYXQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZmxvYXQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRmxvYXQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IG1hcF9pbnQzMl9mbG9hdCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcEludDMyRmxvYXQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRmxvYXQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcEludDMyRG91YmxlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpIHsKICAgICAgICBpZiAobWFwSW50MzJEb3VibGVfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwSW50MzJEb3VibGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEludDMyRG91YmxlXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkRvdWJsZSgpIHsKICAgICAgICBpZiAobWFwSW50MzJEb3VibGVfID09IG51bGwpIHsKICAgICAgICAgIG1hcEludDMyRG91YmxlXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwSW50MzJEb3VibGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtYXBJbnQzMkRvdWJsZV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG1hcEludDMyRG91YmxlXyA9IG1hcEludDMyRG91YmxlXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwSW50MzJEb3VibGVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJEb3VibGVDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IG1hcF9pbnQzMl9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJEb3VibGUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRG91YmxlKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJEb3VibGVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRNYXBJbnQzMkRvdWJsZSgpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwSW50MzJEb3VibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IG1hcF9pbnQzMl9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRNYXBJbnQzMkRvdWJsZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgbWFwX2ludDMyX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRNYXBJbnQzMkRvdWJsZU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBkb3VibGUgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBtYXBfaW50MzJfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldE1hcEludDMyRG91YmxlT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNYXBJbnQzMkRvdWJsZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJEb3VibGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBtYXBfaW50MzJfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwSW50MzJEb3VibGUoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRG91YmxlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldE11dGFibGVNYXBJbnQzMkRvdWJsZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRG91YmxlKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgbWFwX2ludDMyX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1hcEludDMyRG91YmxlKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGRvdWJsZSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJEb3VibGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBtYXBfaW50MzJfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwSW50MzJEb3VibGUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkRvdWJsZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcEJvb2xCb29sXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TWFwQm9vbEJvb2woKSB7CiAgICAgICAgaWYgKG1hcEJvb2xCb29sXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEJvb2xCb29sRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBCb29sQm9vbF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEJvb2xCb29sKCkgewogICAgICAgIGlmIChtYXBCb29sQm9vbF8gPT0gbnVsbCkgewogICAgICAgICAgbWFwQm9vbEJvb2xfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBCb29sQm9vbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW1hcEJvb2xCb29sXy5pc011dGFibGUoKSkgewogICAgICAgICAgbWFwQm9vbEJvb2xfID0gbWFwQm9vbEJvb2xfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtYXBCb29sQm9vbF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBCb29sQm9vbENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEJvb2xCb29sKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgbWFwX2Jvb2xfYm9vbCA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBCb29sQm9vbCgKICAgICAgICAgIGJvb2xlYW4ga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEJvb2xCb29sKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwQm9vbEJvb2xNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0TWFwQm9vbEJvb2woKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcEJvb2xCb29sTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IGdldE1hcEJvb2xCb29sTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEJvb2xCb29sKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRNYXBCb29sQm9vbE9yRGVmYXVsdCgKICAgICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgICAgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwQm9vbEJvb2woKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRNYXBCb29sQm9vbE9yVGhyb3coCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNYXBCb29sQm9vbCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwQm9vbEJvb2woKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwQm9vbEJvb2woCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBCb29sQm9vbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcEJvb2xCb29sKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwQm9vbEJvb2woKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwQm9vbEJvb2woCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGJvb2xlYW4gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEJvb2xCb29sKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgbWFwX2Jvb2xfYm9vbCA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcEJvb2xCb29sKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEJvb2xCb29sKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcFN0cmluZ1N0cmluZ187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKSB7CiAgICAgICAgaWYgKG1hcFN0cmluZ1N0cmluZ18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBTdHJpbmdTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcFN0cmluZ1N0cmluZ187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdTdHJpbmcoKSB7CiAgICAgICAgaWYgKG1hcFN0cmluZ1N0cmluZ18gPT0gbnVsbCkgewogICAgICAgICAgbWFwU3RyaW5nU3RyaW5nXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwU3RyaW5nU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwU3RyaW5nU3RyaW5nXy5pc011dGFibGUoKSkgewogICAgICAgICAgbWFwU3RyaW5nU3RyaW5nXyA9IG1hcFN0cmluZ1N0cmluZ18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcFN0cmluZ1N0cmluZ187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBTdHJpbmdTdHJpbmdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwU3RyaW5nU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBTdHJpbmdTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldE1hcFN0cmluZ1N0cmluZygpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwU3RyaW5nU3RyaW5nTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldE1hcFN0cmluZ1N0cmluZ01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfc3RyaW5nX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0TWFwU3RyaW5nU3RyaW5nT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE1hcFN0cmluZ1N0cmluZ09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwU3RyaW5nU3RyaW5nKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBTdHJpbmdTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFN0cmluZ1N0cmluZygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVNYXBTdHJpbmdTdHJpbmcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBTdHJpbmdTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmdfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwU3RyaW5nU3RyaW5nKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwSW50MzJCeXRlc187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkgewogICAgICAgIGlmIChtYXBJbnQzMkJ5dGVzXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEludDMyQnl0ZXNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEludDMyQnl0ZXNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJCeXRlcygpIHsKICAgICAgICBpZiAobWFwSW50MzJCeXRlc18gPT0gbnVsbCkgewogICAgICAgICAgbWFwSW50MzJCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEludDMyQnl0ZXNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtYXBJbnQzMkJ5dGVzXy5pc011dGFibGUoKSkgewogICAgICAgICAgbWFwSW50MzJCeXRlc18gPSBtYXBJbnQzMkJ5dGVzXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwSW50MzJCeXRlc187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBJbnQzMkJ5dGVzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJCeXRlcygpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2ludDMyX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEludDMyQnl0ZXMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyQnl0ZXMoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkJ5dGVzTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRNYXBJbnQzMkJ5dGVzKCkgewogICAgICAgIHJldHVybiBnZXRNYXBJbnQzMkJ5dGVzTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9pbnQzMl9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0TWFwSW50MzJCeXRlc01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9pbnQzMl9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRNYXBJbnQzMkJ5dGVzT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCmNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyQnl0ZXMoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9pbnQzMl9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRNYXBJbnQzMkJ5dGVzT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyQnl0ZXMoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwSW50MzJCeXRlcygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJCeXRlcygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2ludDMyX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwSW50MzJCeXRlcygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJCeXRlcygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVNYXBJbnQzMkJ5dGVzKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJCeXRlcygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2ludDMyX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwSW50MzJCeXRlcygKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKCiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyQnl0ZXMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9pbnQzMl9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcEludDMyQnl0ZXMoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyQnl0ZXMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXBJbnQzMkVudW1fOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKSB7CiAgICAgICAgaWYgKG1hcEludDMyRW51bV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBJbnQzMkVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEludDMyRW51bV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRW51bSgpIHsKICAgICAgICBpZiAobWFwSW50MzJFbnVtXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBJbnQzMkVudW1fID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBJbnQzMkVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtYXBJbnQzMkVudW1fLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBJbnQzMkVudW1fID0gbWFwSW50MzJFbnVtXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwSW50MzJFbnVtXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcEludDMyRW51bUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJFbnVtKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkVudW1NYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtPgogICAgICBnZXRNYXBJbnQzMkVudW0oKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcEludDMyRW51bU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0+CiAgICAgIGdldE1hcEludDMyRW51bU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkTWFwSW50MzJFbnVtTWFwKAogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpLmdldE1hcCgpKTt9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0gZ2V0TWFwSW50MzJFbnVtT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KQogICAgICAgICAgICAgICA/IG1hcEludDMyRW51bVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpCiAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0gZ2V0TWFwSW50MzJFbnVtT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEludDMyRW51bVZhbHVlQ29udmVydGVyLmRvRm9yd2FyZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkVudW1WYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNYXBJbnQzMkVudW1WYWx1ZSgpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwSW50MzJFbnVtVmFsdWVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TWFwSW50MzJFbnVtVmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE1hcEludDMyRW51bVZhbHVlT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRNYXBJbnQzMkVudW1WYWx1ZU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNYXBJbnQzMkVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDgwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBJbnQzMkVudW0oCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwSW50MzJFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBZGFwdGVkTWFwSW50MzJFbnVtTWFwKAogICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBJbnQzMkVudW0oCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWFwRW51bSB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCBtYXBJbnQzMkVudW1WYWx1ZUNvbnZlcnRlci5kb0JhY2t3YXJkKHZhbHVlKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcEludDMyRW51bSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0QWRhcHRlZE1hcEludDMyRW51bU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpKQogICAgICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE11dGFibGVNYXBJbnQzMkVudW1WYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRW51bSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBJbnQzMkVudW1WYWx1ZSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBJbnQzMkVudW1WYWx1ZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwSW50MzJGb3JlaWduTWVzc2FnZUNvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBidWlsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UpIHsgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gTWFwSW50MzJGb3JlaWduTWVzc2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXBJbnQzMkZvcmVpZ25NZXNzYWdlQ29udmVydGVyIG1hcEludDMyRm9yZWlnbk1lc3NhZ2VDb252ZXJ0ZXIgPSBuZXcgTWFwSW50MzJGb3JlaWduTWVzc2FnZUNvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXI+IG1hcEludDMyRm9yZWlnbk1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG1hcEludDMyRm9yZWlnbk1lc3NhZ2VfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihtYXBJbnQzMkZvcmVpZ25NZXNzYWdlQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEludDMyRm9yZWlnbk1lc3NhZ2VfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG1hcEludDMyRm9yZWlnbk1lc3NhZ2VfID09IG51bGwpIHsKICAgICAgICAgIG1hcEludDMyRm9yZWlnbk1lc3NhZ2VfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obWFwSW50MzJGb3JlaWduTWVzc2FnZUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwSW50MzJGb3JlaWduTWVzc2FnZV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEludDMyRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IGdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UmZ3Q7IG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UmZ3Q7IG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIGdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2VPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXBJbnQzMkZvcmVpZ25NZXNzYWdlQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwSW50MzJGb3JlaWduTWVzc2FnZUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwSW50MzJGb3JlaWduTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwSW50MzJGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwSW50MzJGb3JlaWduTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwSW50MzJGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgcHV0TWFwSW50MzJGb3JlaWduTWVzc2FnZUJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlKSB7CiAgICAgICAgICBlbnRyeSA9ICgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBidWlsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UpIHsgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlKSB2YWw7IH0KICAgICAgICAgIHJldHVybiAoKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBNYXBTdHJpbmdGb3JlaWduTWVzc2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXBTdHJpbmdGb3JlaWduTWVzc2FnZUNvbnZlcnRlciBtYXBTdHJpbmdGb3JlaWduTWVzc2FnZUNvbnZlcnRlciA9IG5ldyBNYXBTdHJpbmdGb3JlaWduTWVzc2FnZUNvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlcj4gbWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBTdHJpbmdGb3JlaWduTWVzc2FnZV8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihtYXBTdHJpbmdGb3JlaWduTWVzc2FnZUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX3N0cmluZ19mb3JlaWduX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBnZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfc3RyaW5nX2ZvcmVpZ25fbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gZ2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfc3RyaW5nX2ZvcmVpZ25fbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXBTdHJpbmdGb3JlaWduTWVzc2FnZUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UmZ3Q7IG1hcF9zdHJpbmdfZm9yZWlnbl9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZU9yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UmZ3Q7IG1hcF9zdHJpbmdfZm9yZWlnbl9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX3N0cmluZ19mb3JlaWduX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfc3RyaW5nX2ZvcmVpZ25fbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdGb3JlaWduTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UmZ3Q7IG1hcF9zdHJpbmdfZm9yZWlnbl9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBwdXRNYXBTdHJpbmdGb3JlaWduTWVzc2FnZUJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSkgewogICAgICAgICAgZW50cnkgPSAoKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcEludDMyQWxsVHlwZXNDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgYnVpbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMpIHsgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcykgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gTWFwSW50MzJBbGxUeXBlc0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnk7CiAgICAgICAgfQogICAgICB9OwogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNYXBJbnQzMkFsbFR5cGVzQ29udmVydGVyIG1hcEludDMyQWxsVHlwZXNDb252ZXJ0ZXIgPSBuZXcgTWFwSW50MzJBbGxUeXBlc0NvbnZlcnRlcigpOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXI+IG1hcEludDMyQWxsVHlwZXNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyQWxsVHlwZXMoKSB7CiAgICAgICAgaWYgKG1hcEludDMyQWxsVHlwZXNfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihtYXBJbnQzMkFsbFR5cGVzQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEludDMyQWxsVHlwZXNfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyQWxsVHlwZXMoKSB7CiAgICAgICAgaWYgKG1hcEludDMyQWxsVHlwZXNfID09IG51bGwpIHsKICAgICAgICAgIG1hcEludDMyQWxsVHlwZXNfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obWFwSW50MzJBbGxUeXBlc0NvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwSW50MzJBbGxUeXBlc187CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBJbnQzMkFsbFR5cGVzQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJBbGxUeXBlcygpLmVuc3VyZUJ1aWxkZXJNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyZndDsgbWFwX2ludDMyX2FsbF90eXBlcyA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBJbnQzMkFsbFR5cGVzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkFsbFR5cGVzKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyQWxsVHlwZXNNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0TWFwSW50MzJBbGxUeXBlcygpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwSW50MzJBbGxUeXBlc01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMmZ3Q7IG1hcF9pbnQzMl9hbGxfdHlwZXMgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0TWFwSW50MzJBbGxUeXBlc01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkFsbFR5cGVzKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyZndDsgbWFwX2ludDMyX2FsbF90eXBlcyA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE1hcEludDMyQWxsVHlwZXNPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkFsbFR5cGVzKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcEludDMyQWxsVHlwZXNDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzJmd0OyBtYXBfaW50MzJfYWxsX3R5cGVzID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0TWFwSW50MzJBbGxUeXBlc09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkFsbFR5cGVzKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBJbnQzMkFsbFR5cGVzQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNYXBJbnQzMkFsbFR5cGVzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDQwMDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkFsbFR5cGVzKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzJmd0OyBtYXBfaW50MzJfYWxsX3R5cGVzID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwSW50MzJBbGxUeXBlcygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJBbGxUeXBlcygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcEludDMyQWxsVHlwZXMoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkFsbFR5cGVzKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMmZ3Q7IG1hcF9pbnQzMl9hbGxfdHlwZXMgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBJbnQzMkFsbFR5cGVzKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkFsbFR5cGVzKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMmZ3Q7IG1hcF9pbnQzMl9hbGxfdHlwZXMgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBJbnQzMkFsbFR5cGVzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IHZhbHVlcykgewogICAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJBbGxUeXBlcygpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMmZ3Q7IG1hcF9pbnQzMl9hbGxfdHlwZXMgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBwdXRNYXBJbnQzMkFsbFR5cGVzQnVpbGRlcklmQWJzZW50KAogICAgICAgICAgaW50IGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBidWlsZGVyTWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJBbGxUeXBlcygpLmVuc3VyZUJ1aWxkZXJNYXAoKTsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMubmV3QnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmIChlbnRyeSBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzKSB7CiAgICAgICAgICBlbnRyeSA9ICgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIpIGVudHJ5OwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXApCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXApCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWFwPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RNYXA+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TWFwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1hcD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWFwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE1hcFN1Ym1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcCB0ZXN0X21hcCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB0ZXN0TWFwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNUZXN0TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwIHRlc3RfbWFwID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSB0ZXN0TWFwLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwIGdldFRlc3RNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAgdGVzdF9tYXAgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcE9yQnVpbGRlciBnZXRUZXN0TWFwT3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE1hcFN1Ym1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UpCiAgICAgIFRlc3RNYXBTdWJtZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TWFwU3VibWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TWFwU3VibWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RNYXBTdWJtZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNYXBTdWJtZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBTdWJtZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBTdWJtZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBURVNUX01BUF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwIHRlc3RNYXBfOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcCB0ZXN0X21hcCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB0ZXN0TWFwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzVGVzdE1hcCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcCB0ZXN0X21hcCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdGVzdE1hcC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgZ2V0VGVzdE1hcCgpIHsKICAgICAgcmV0dXJuIHRlc3RNYXBfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogdGVzdE1hcF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwIHRlc3RfbWFwID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwT3JCdWlsZGVyIGdldFRlc3RNYXBPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0ZXN0TWFwXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHRlc3RNYXBfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRUZXN0TWFwKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0VGVzdE1hcCgpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwU3VibWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UpIG9iajsKCiAgICAgIGlmIChoYXNUZXN0TWFwKCkgIT0gb3RoZXIuaGFzVGVzdE1hcCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNUZXN0TWFwKCkpIHsKICAgICAgICBpZiAoIWdldFRlc3RNYXAoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFRlc3RNYXAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNUZXN0TWFwKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBURVNUX01BUF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VGVzdE1hcCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwU3VibWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwU3VibWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwU3VibWVzc2FnZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwU3VibWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcFN1Ym1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBTdWJtZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwU3VibWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldFRlc3RNYXBGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHRlc3RNYXBfID0gbnVsbDsKICAgICAgICBpZiAodGVzdE1hcEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHRlc3RNYXBCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICB0ZXN0TWFwQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBTdWJtZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwU3VibWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwU3VibWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwU3VibWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQudGVzdE1hcF8gPSB0ZXN0TWFwQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gdGVzdE1hcF8KICAgICAgICAgICAgICA6IHRlc3RNYXBCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzVGVzdE1hcCgpKSB7CiAgICAgICAgICBtZXJnZVRlc3RNYXAob3RoZXIuZ2V0VGVzdE1hcCgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0VGVzdE1hcEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwIHRlc3RNYXBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBPckJ1aWxkZXI+IHRlc3RNYXBCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwIHRlc3RfbWFwID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdGVzdE1hcCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNUZXN0TWFwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAgdGVzdF9tYXAgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgdGVzdE1hcC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwIGdldFRlc3RNYXAoKSB7CiAgICAgICAgaWYgKHRlc3RNYXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gdGVzdE1hcF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiB0ZXN0TWFwXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHRlc3RNYXBCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcCB0ZXN0X21hcCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VGVzdE1hcChwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwIHZhbHVlKSB7CiAgICAgICAgaWYgKHRlc3RNYXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRlc3RNYXBfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHRlc3RNYXBCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcCB0ZXN0X21hcCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VGVzdE1hcCgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAodGVzdE1hcEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHRlc3RNYXBfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHRlc3RNYXBCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcCB0ZXN0X21hcCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VUZXN0TWFwKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAgdmFsdWUpIHsKICAgICAgICBpZiAodGVzdE1hcEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICB0ZXN0TWFwXyAhPSBudWxsICYmCiAgICAgICAgICAgIHRlc3RNYXBfICE9IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0VGVzdE1hcEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGVzdE1hcF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgdGVzdE1hcEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmICh0ZXN0TWFwXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwIHRlc3RfbWFwID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclRlc3RNYXAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHRlc3RNYXBfID0gbnVsbDsKICAgICAgICBpZiAodGVzdE1hcEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHRlc3RNYXBCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICB0ZXN0TWFwQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAgdGVzdF9tYXAgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwLkJ1aWxkZXIgZ2V0VGVzdE1hcEJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRUZXN0TWFwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcCB0ZXN0X21hcCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBPckJ1aWxkZXIgZ2V0VGVzdE1hcE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAodGVzdE1hcEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiB0ZXN0TWFwQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gdGVzdE1hcF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHRlc3RNYXBfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAgdGVzdF9tYXAgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRUZXN0TWFwRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmICh0ZXN0TWFwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgdGVzdE1hcEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcCwgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0VGVzdE1hcCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgdGVzdE1hcF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGVzdE1hcEJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwU3VibWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNYXBTdWJtZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWFwU3VibWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNYXBTdWJtZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RNYXBTdWJtZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE1hcFN1Ym1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWFwU3VibWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWFwU3VibWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1hcFN1Ym1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0TWVzc2FnZU1hcE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZU1hcCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyZndDsgbWFwX2ludDMyX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcEludDMyTWVzc2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyZndDsgbWFwX2ludDMyX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcEludDMyTWVzc2FnZSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJNZXNzYWdlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+CiAgICBnZXRNYXBJbnQzMk1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzJmd0OyBtYXBfaW50MzJfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4KICAgIGdldE1hcEludDMyTWVzc2FnZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMmZ3Q7IG1hcF9pbnQzMl9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE1hcEludDMyTWVzc2FnZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyZndDsgbWFwX2ludDMyX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0TWFwSW50MzJNZXNzYWdlT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VNYXB9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0TWVzc2FnZU1hcCBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZU1hcCkKICAgICAgVGVzdE1lc3NhZ2VNYXBPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RNZXNzYWdlTWFwLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNZXNzYWdlTWFwKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE1lc3NhZ2VNYXAoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdE1lc3NhZ2VNYXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VNYXBfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJNZXNzYWdlKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VNYXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1lc3NhZ2VNYXAuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0lOVDMyX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcEludDMyTWVzc2FnZURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZU1hcF9NYXBJbnQzMk1lc3NhZ2VFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IG1hcEludDMyTWVzc2FnZV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPgogICAgaW50ZXJuYWxHZXRNYXBJbnQzMk1lc3NhZ2UoKSB7CiAgICAgIGlmIChtYXBJbnQzMk1lc3NhZ2VfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNYXBJbnQzMk1lc3NhZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwSW50MzJNZXNzYWdlXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJNZXNzYWdlQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyTWVzc2FnZSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzJmd0OyBtYXBfaW50MzJfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEludDMyTWVzc2FnZSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMk1lc3NhZ2UoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMk1lc3NhZ2VNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGdldE1hcEludDMyTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIGdldE1hcEludDMyTWVzc2FnZU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMmZ3Q7IG1hcF9pbnQzMl9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0TWFwSW50MzJNZXNzYWdlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMk1lc3NhZ2UoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzJmd0OyBtYXBfaW50MzJfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0TWFwSW50MzJNZXNzYWdlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJNZXNzYWdlKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzJmd0OyBtYXBfaW50MzJfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0TWFwSW50MzJNZXNzYWdlT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJNZXNzYWdlKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyTWVzc2FnZSgpLAogICAgICAgICAgTWFwSW50MzJNZXNzYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwSW50MzJNZXNzYWdlKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPgogICAgICAgIG1hcEludDMyTWVzc2FnZV9fID0gTWFwSW50MzJNZXNzYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBtYXBJbnQzMk1lc3NhZ2VfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1lc3NhZ2VNYXApKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNZXNzYWdlTWFwIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNZXNzYWdlTWFwKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0TWFwSW50MzJNZXNzYWdlKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBJbnQzMk1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwSW50MzJNZXNzYWdlKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX0lOVDMyX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TWFwSW50MzJNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1lc3NhZ2VNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1lc3NhZ2VNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNZXNzYWdlTWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1lc3NhZ2VNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1lc3NhZ2VNYXAgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcCBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNZXNzYWdlTWFwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1lc3NhZ2VNYXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZU1hcH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlTWFwKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNZXNzYWdlTWFwT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZU1hcF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyTWVzc2FnZSgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyTWVzc2FnZSgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlTWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNZXNzYWdlTWFwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNZXNzYWdlTWFwLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMk1lc3NhZ2UoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1lc3NhZ2VNYXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1lc3NhZ2VNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNZXNzYWdlTWFwIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNZXNzYWdlTWFwIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1lc3NhZ2VNYXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNZXNzYWdlTWFwIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcCh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMyTWVzc2FnZV8gPSBpbnRlcm5hbEdldE1hcEludDMyTWVzc2FnZSgpLmJ1aWxkKE1hcEludDMyTWVzc2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNZXNzYWdlTWFwKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJNZXNzYWdlKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEludDMyTWVzc2FnZSgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+CiAgICAgICAgICAgICAgICBtYXBJbnQzMk1lc3NhZ2VfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcEludDMyTWVzc2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcEludDMyTWVzc2FnZV9fLmdldEtleSgpLCBtYXBJbnQzMk1lc3NhZ2VfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBJbnQzMk1lc3NhZ2VDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgYnVpbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMpIHsgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcykgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBkZWZhdWx0RW50cnkoKSB7CiAgICAgICAgICByZXR1cm4gTWFwSW50MzJNZXNzYWdlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcEludDMyTWVzc2FnZUNvbnZlcnRlciBtYXBJbnQzMk1lc3NhZ2VDb252ZXJ0ZXIgPSBuZXcgTWFwSW50MzJNZXNzYWdlQ29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlcj4gbWFwSW50MzJNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG1hcEludDMyTWVzc2FnZV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KG1hcEludDMyTWVzc2FnZUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBJbnQzMk1lc3NhZ2VfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyTWVzc2FnZSgpIHsKICAgICAgICBpZiAobWFwSW50MzJNZXNzYWdlXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBJbnQzMk1lc3NhZ2VfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obWFwSW50MzJNZXNzYWdlQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtYXBJbnQzMk1lc3NhZ2VfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJNZXNzYWdlQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJNZXNzYWdlKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzJmd0OyBtYXBfaW50MzJfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEludDMyTWVzc2FnZSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJNZXNzYWdlKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyTWVzc2FnZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBnZXRNYXBJbnQzMk1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcEludDMyTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMmZ3Q7IG1hcF9pbnQzMl9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0TWFwSW50MzJNZXNzYWdlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyTWVzc2FnZSgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMmZ3Q7IG1hcF9pbnQzMl9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRNYXBJbnQzMk1lc3NhZ2VPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwSW50MzJNZXNzYWdlQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyZndDsgbWFwX2ludDMyX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE1hcEludDMyTWVzc2FnZU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEludDMyTWVzc2FnZUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwSW50MzJNZXNzYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMk1lc3NhZ2UoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMmZ3Q7IG1hcF9pbnQzMl9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBJbnQzMk1lc3NhZ2UoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcEludDMyTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyTWVzc2FnZSgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzJmd0OyBtYXBfaW50MzJfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwSW50MzJNZXNzYWdlKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyZndDsgbWFwX2ludDMyX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcEludDMyTWVzc2FnZSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMmZ3Q7IG1hcF9pbnQzMl9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBwdXRNYXBJbnQzMk1lc3NhZ2VCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBpbnQga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZW50cnkgPSBidWlsZGVyTWFwLmdldChrZXkpOwogICAgICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICBlbnRyeSA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoZW50cnkgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcykgewogICAgICAgICAgZW50cnkgPSAoKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzKSBlbnRyeSkudG9CdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyKSBlbnRyeTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZU1hcCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VNYXApCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0TWVzc2FnZU1hcCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdE1lc3NhZ2VNYXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZU1hcD4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0TWVzc2FnZU1hcD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RNZXNzYWdlTWFwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2VNYXA+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2VNYXA+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RNZXNzYWdlTWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFNhbWVUeXBlTWFwT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTYW1lVHlwZU1hcCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcDEgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcDFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXAxID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNNYXAxKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXAxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRNYXAxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcDEgPSAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRNYXAxTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcDEgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcDFPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwMU9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXAyID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXAyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwMiA9IDI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TWFwMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXAyID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TWFwMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXAyID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXAyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcDIgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcDJPclRocm93KAogICAgICAgIGludCBrZXkpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFR3byBtYXAgZmllbGRzIHNoYXJlIHRoZSBzYW1lIGVudHJ5IGRlZmF1bHQgaW5zdGFuY2UuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0U2FtZVR5cGVNYXB9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0U2FtZVR5cGVNYXAgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwKQogICAgICBUZXN0U2FtZVR5cGVNYXBPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RTYW1lVHlwZU1hcC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0U2FtZVR5cGVNYXAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0U2FtZVR5cGVNYXAoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFNhbWVUeXBlTWFwKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RTYW1lVHlwZU1hcF9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXAxKCk7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwMigpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RTYW1lVHlwZU1hcF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RTYW1lVHlwZU1hcC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUDFfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcDFEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFNhbWVUeXBlTWFwX01hcDFFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcDFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0TWFwMSgpIHsKICAgICAgaWYgKG1hcDFfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNYXAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcDFfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXAxQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcDEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcDEgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXAxKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcDEoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXAxTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXAxKCkgewogICAgICByZXR1cm4gZ2V0TWFwMU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXAxID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwMU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwMSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXAxID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TWFwMU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXAxKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1hcDFPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXAxKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQMl9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0U2FtZVR5cGVNYXBfTWFwMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRNYXAyKCkgewogICAgICBpZiAobWFwMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcDJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwMl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcDJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwMiA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcDIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcDJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1hcDIoKSB7CiAgICAgIHJldHVybiBnZXRNYXAyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcDIgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXAyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXAyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcDIgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRNYXAyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcDIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXAyID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TWFwMk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcDIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwMSgpLAogICAgICAgICAgTWFwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXAyKCksCiAgICAgICAgICBNYXAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwMSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBtYXAxX18gPSBNYXAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBtYXAxX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1hcDIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgbWFwMl9fID0gTWFwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgbWFwMl9fKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0U2FtZVR5cGVNYXApKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RTYW1lVHlwZU1hcCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0U2FtZVR5cGVNYXApIG9iajsKCiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXAxKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXAxKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXAyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXAyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcDEoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVAxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcDEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXAyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXAyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RTYW1lVHlwZU1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RTYW1lVHlwZU1hcCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RTYW1lVHlwZU1hcCBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0U2FtZVR5cGVNYXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0U2FtZVR5cGVNYXAgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RTYW1lVHlwZU1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RTYW1lVHlwZU1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0U2FtZVR5cGVNYXAgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFR3byBtYXAgZmllbGRzIHNoYXJlIHRoZSBzYW1lIGVudHJ5IGRlZmF1bHQgaW5zdGFuY2UuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0U2FtZVR5cGVNYXB9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0U2FtZVR5cGVNYXApCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0U2FtZVR5cGVNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXAxKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcDIoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXAxKCk7CiAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXAyKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFNhbWVUeXBlTWFwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RTYW1lVHlwZU1hcC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXAxKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXAyKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RTYW1lVHlwZU1hcF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0U2FtZVR5cGVNYXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0U2FtZVR5cGVNYXAgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0U2FtZVR5cGVNYXAgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RTYW1lVHlwZU1hcCh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0U2FtZVR5cGVNYXAgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5tYXAxXyA9IGludGVybmFsR2V0TWFwMSgpOwogICAgICAgICAgcmVzdWx0Lm1hcDFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5tYXAyXyA9IGludGVybmFsR2V0TWFwMigpOwogICAgICAgICAgcmVzdWx0Lm1hcDJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0U2FtZVR5cGVNYXApIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RTYW1lVHlwZU1hcClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0U2FtZVR5cGVNYXAgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXAxKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcDEoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcDIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBtYXAxX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcDEoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcDFfXy5nZXRLZXkoKSwgbWFwMV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBtYXAyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcDIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcDJfXy5nZXRLZXkoKSwgbWFwMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwMV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE1hcDEoKSB7CiAgICAgICAgaWYgKG1hcDFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwMURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwMV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcDEoKSB7CiAgICAgICAgaWYgKG1hcDFfID09IG51bGwpIHsKICAgICAgICAgIG1hcDFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXAxRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwMV8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG1hcDFfID0gbWFwMV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcDFfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwMUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcDEoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcDEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXAxKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXAxKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwMU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXAxKCkgewogICAgICAgIHJldHVybiBnZXRNYXAxTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcDEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXAxTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcDEoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE1hcDFPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXAxKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXAxID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwMU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcDEoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwMSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwMSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcDEoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXAxKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXAxID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXAxKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwMSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwMSgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXAxKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwMl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE1hcDIoKSB7CiAgICAgICAgaWYgKG1hcDJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwMl87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcDIoKSB7CiAgICAgICAgaWYgKG1hcDJfID09IG51bGwpIHsKICAgICAgICAgIG1hcDJfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXAyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwMl8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG1hcDJfID0gbWFwMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcDJfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwMkNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcDIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcDIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXAyKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXAyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXAyKCkgewogICAgICAgIHJldHVybiBnZXRNYXAyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcDIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXAyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcDIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE1hcDJPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXAyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXAyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwMk9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcDIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcDIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXAyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXAyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXAyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXAyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0U2FtZVR5cGVNYXApCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0U2FtZVR5cGVNYXAgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0U2FtZVR5cGVNYXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0U2FtZVR5cGVNYXA+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFNhbWVUeXBlTWFwPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdFNhbWVUeXBlTWFwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFNhbWVUeXBlTWFwPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RTYW1lVHlwZU1hcD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFNhbWVUeXBlTWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFJlcXVpcmVkTWVzc2FnZU1hcE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcEZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcEZpZWxkKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPgogICAgZ2V0TWFwRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ+CiAgICBnZXRNYXBGaWVsZE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQmZ3Q7IG1hcF9maWVsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBnZXRNYXBGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldE1hcEZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUZXN0IGVtYmVkZGVkIG1lc3NhZ2Ugd2l0aCByZXF1aXJlZCBmaWVsZHMKICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXB9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0UmVxdWlyZWRNZXNzYWdlTWFwIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXApCiAgICAgIFRlc3RSZXF1aXJlZE1lc3NhZ2VNYXBPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFJlcXVpcmVkTWVzc2FnZU1hcChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRNZXNzYWdlTWFwX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpZWxkKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkTWVzc2FnZU1hcF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRNZXNzYWdlTWFwX01hcEZpZWxkRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiBtYXBGaWVsZF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPgogICAgaW50ZXJuYWxHZXRNYXBGaWVsZCgpIHsKICAgICAgaWYgKG1hcEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwRmllbGRfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBGaWVsZENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBGaWVsZCgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiBnZXRNYXBGaWVsZCgpIHsKICAgICAgcmV0dXJuIGdldE1hcEZpZWxkTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4gZ2V0TWFwRmllbGRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBnZXRNYXBGaWVsZE9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldE1hcEZpZWxkT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGl0ZW0gOiBnZXRNYXBGaWVsZE1hcCgpLnZhbHVlcygpKSB7CiAgICAgICAgaWYgKCFpdGVtLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpZWxkKCksCiAgICAgICAgICBNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPgogICAgICAgIG1hcEZpZWxkX18gPSBNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgbWFwRmllbGRfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0TWFwRmllbGQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcEZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0IGVtYmVkZGVkIG1lc3NhZ2Ugd2l0aCByZXF1aXJlZCBmaWVsZHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXB9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXBPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE1lc3NhZ2VNYXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaWVsZCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkTWVzc2FnZU1hcF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcC5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkTWVzc2FnZU1hcF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEZpZWxkXyA9IGludGVybmFsR2V0TWFwRmllbGQoKS5idWlsZChNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXApIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXApb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlTWFwLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGZvciAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgaXRlbSA6IGdldE1hcEZpZWxkTWFwKCkudmFsdWVzKCkpIHsKICAgICAgICAgIGlmICghaXRlbS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPgogICAgICAgICAgICAgICAgbWFwRmllbGRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBGaWVsZF9fLmdldEtleSgpLCBtYXBGaWVsZF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcEZpZWxkQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGJ1aWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyIHZhbCkgewogICAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkKSB7IHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlcikgdmFsKS5idWlsZCgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIE1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE1hcEZpZWxkQ29udmVydGVyIG1hcEZpZWxkQ29udmVydGVyID0gbmV3IE1hcEZpZWxkQ29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlcj4gbWFwRmllbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpZWxkKCkgewogICAgICAgIGlmIChtYXBGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KG1hcEZpZWxkQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEZpZWxkXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZCgpIHsKICAgICAgICBpZiAobWFwRmllbGRfID09IG51bGwpIHsKICAgICAgICAgIG1hcEZpZWxkXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KG1hcEZpZWxkQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtYXBGaWVsZF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBGaWVsZCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4gZ2V0TWFwRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcEZpZWxkTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4gZ2V0TWFwRmllbGRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRmllbGQoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldE1hcEZpZWxkT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gbWFwID0gaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwRmllbGRDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldE1hcEZpZWxkT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBGaWVsZENvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkJmd0OyBtYXBfZmllbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcEZpZWxkKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZCgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcEZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBGaWVsZCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCZndDsgbWFwX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciBwdXRNYXBGaWVsZEJ1aWxkZXJJZkFic2VudCgKICAgICAgICAgIGludCBrZXkpIHsKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQpIHsKICAgICAgICAgIGVudHJ5ID0gKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXF1aXJlZE1lc3NhZ2VNYXA+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFJlcXVpcmVkTWVzc2FnZU1hcD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVxdWlyZWRNZXNzYWdlTWFwPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXF1aXJlZE1lc3NhZ2VNYXA+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2VNYXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0QXJlbmFNYXBPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFyZW5hTWFwKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ludDMyX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBJbnQzMkludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ludDMyX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNNYXBJbnQzMkludDMyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRNYXBJbnQzMkludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9pbnQzMl9pbnQzMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE1hcEludDMySW50MzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ludDMyX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBJbnQzMkludDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9pbnQzMl9pbnQzMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwSW50MzJJbnQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBtYXBfaW50NjRfaW50NjQgPSAyOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcEludDY0SW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBtYXBfaW50NjRfaW50NjQgPSAyOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcEludDY0SW50NjQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQ2NEludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRNYXBJbnQ2NEludDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IG1hcF9pbnQ2NF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldE1hcEludDY0SW50NjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgbWFwX2ludDY0X2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0TWFwSW50NjRJbnQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IG1hcF9pbnQ2NF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldE1hcEludDY0SW50NjRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcFVpbnQzMlVpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcFVpbnQzMlVpbnQzMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwVWludDMyVWludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRNYXBVaW50MzJVaW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBtYXBfdWludDMyX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE1hcFVpbnQzMlVpbnQzMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IG1hcF91aW50MzJfdWludDMyID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBVaW50MzJVaW50MzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBtYXBfdWludDMyX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwVWludDMyVWludDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcFVpbnQ2NFVpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcFVpbnQ2NFVpbnQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFVpbnQ2NFVpbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0TWFwVWludDY0VWludDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRNYXBVaW50NjRVaW50NjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBtYXBfdWludDY0X3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldE1hcFVpbnQ2NFVpbnQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRNYXBVaW50NjRVaW50NjRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgbWFwX3NpbnQzMl9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcFNpbnQzMlNpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgbWFwX3NpbnQzMl9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcFNpbnQzMlNpbnQzMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwU2ludDMyU2ludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRNYXBTaW50MzJTaW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBtYXBfc2ludDMyX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE1hcFNpbnQzMlNpbnQzMk1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IG1hcF9zaW50MzJfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBTaW50MzJTaW50MzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBtYXBfc2ludDMyX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwU2ludDMyU2ludDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgbWFwX3NpbnQ2NF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcFNpbnQ2NFNpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgbWFwX3NpbnQ2NF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcFNpbnQ2NFNpbnQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFNpbnQ2NFNpbnQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0TWFwU2ludDY0U2ludDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgbWFwX3NpbnQ2NF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRNYXBTaW50NjRTaW50NjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBtYXBfc2ludDY0X3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldE1hcFNpbnQ2NFNpbnQ2NE9yRGVmYXVsdCgKICAgICAgICBsb25nIGtleSwKICAgICAgICBsb25nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgbWFwX3NpbnQ2NF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRNYXBTaW50NjRTaW50NjRPclRocm93KAogICAgICAgIGxvbmcga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBGaXhlZDMyRml4ZWQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNNYXBGaXhlZDMyRml4ZWQzMigKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwRml4ZWQzMkZpeGVkMzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE1hcEZpeGVkMzJGaXhlZDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TWFwRml4ZWQzMkZpeGVkMzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IG1hcF9maXhlZDMyX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcEZpeGVkMzJGaXhlZDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBGaXhlZDMyRml4ZWQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwRml4ZWQ2NEZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwRml4ZWQ2NEZpeGVkNjQoCiAgICAgICAgbG9uZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBGaXhlZDY0Rml4ZWQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgZ2V0TWFwRml4ZWQ2NEZpeGVkNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IG1hcF9maXhlZDY0X2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBnZXRNYXBGaXhlZDY0Rml4ZWQ2NE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldE1hcEZpeGVkNjRGaXhlZDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IG1hcF9maXhlZDY0X2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAqLwogICAgbG9uZyBnZXRNYXBGaXhlZDY0Rml4ZWQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNNYXBTZml4ZWQzMlNmaXhlZDMyKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBTZml4ZWQzMlNmaXhlZDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IG1hcF9zZml4ZWQzMl9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldE1hcFNmaXhlZDMyU2ZpeGVkMzJNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IG1hcF9zZml4ZWQzMl9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwU2ZpeGVkMzJTZml4ZWQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBTZml4ZWQ2NFNmaXhlZDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwU2ZpeGVkNjRTZml4ZWQ2NCgKICAgICAgICBsb25nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFNmaXhlZDY0U2ZpeGVkNjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgIGdldE1hcFNmaXhlZDY0U2ZpeGVkNjRNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBsb25nIGdldE1hcFNmaXhlZDY0U2ZpeGVkNjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGxvbmcgZ2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgbWFwX2ludDMyX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwSW50MzJGbG9hdENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IG1hcF9pbnQzMl9mbG9hdCA9IDExOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcEludDMyRmxvYXQoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyRmxvYXRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICBnZXRNYXBJbnQzMkZsb2F0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IG1hcF9pbnQzMl9mbG9hdCA9IDExOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgZ2V0TWFwSW50MzJGbG9hdE1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBtYXBfaW50MzJfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldE1hcEludDMyRmxvYXRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBtYXBfaW50MzJfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgKi8KICAgIGZsb2F0IGdldE1hcEludDMyRmxvYXRPclRocm93KAogICAgICAgIGludCBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IG1hcF9pbnQzMl9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBJbnQzMkRvdWJsZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBtYXBfaW50MzJfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJEb3VibGUoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyRG91YmxlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgIGdldE1hcEludDMyRG91YmxlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBtYXBfaW50MzJfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgZ2V0TWFwSW50MzJEb3VibGVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IG1hcF9pbnQzMl9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIGRvdWJsZSBnZXRNYXBJbnQzMkRvdWJsZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGRvdWJsZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgbWFwX2ludDMyX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAqLwogICAgZG91YmxlIGdldE1hcEludDMyRG91YmxlT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwQm9vbEJvb2xDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgbWFwX2Jvb2xfYm9vbCA9IDEzOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcEJvb2xCb29sKAogICAgICAgIGJvb2xlYW4ga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwQm9vbEJvb2xNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldE1hcEJvb2xCb29sKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgIGdldE1hcEJvb2xCb29sTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGdldE1hcEJvb2xCb29sT3JEZWZhdWx0KAogICAgICAgIGJvb2xlYW4ga2V5LAogICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IG1hcF9ib29sX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0TWFwQm9vbEJvb2xPclRocm93KAogICAgICAgIGJvb2xlYW4ga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBTdHJpbmdTdHJpbmdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmdfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwU3RyaW5nU3RyaW5nKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwU3RyaW5nU3RyaW5nTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0TWFwU3RyaW5nU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldE1hcFN0cmluZ1N0cmluZ01hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmdfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldE1hcFN0cmluZ1N0cmluZ09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TWFwU3RyaW5nU3RyaW5nT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfaW50MzJfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBJbnQzMkJ5dGVzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2ludDMyX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJCeXRlcygKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJCeXRlc01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgIGdldE1hcEludDMyQnl0ZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2ludDMyX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICBnZXRNYXBJbnQzMkJ5dGVzTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9pbnQzMl9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE1hcEludDMyQnl0ZXNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2ludDMyX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0TWFwSW50MzJCeXRlc09yVGhyb3coCiAgICAgICAgaW50IGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcEludDMyRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJFbnVtKAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkVudW1NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtPgogICAgZ2V0TWFwSW50MzJFbnVtKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtPgogICAgZ2V0TWFwSW50MzJFbnVtTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICovCiAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtIGdldE1hcEludDMyRW51bU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0gICAgICAgICBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWFwRW51bSBnZXRNYXBJbnQzMkVudW1PclRocm93KAogICAgICAgIGludCBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkVudW1WYWx1ZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TWFwSW50MzJFbnVtVmFsdWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgZ2V0TWFwSW50MzJFbnVtVmFsdWVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBJbnQzMkVudW1WYWx1ZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldE1hcEludDMyRW51bVZhbHVlT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJGb3JlaWduTWVzc2FnZSgKICAgICAgICBpbnQga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+CiAgICBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPgogICAgZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlT3JUaHJvdygKICAgICAgICBpbnQga2V5KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFyZW5hTWFwfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEFyZW5hTWFwIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBcmVuYU1hcCkKICAgICAgVGVzdEFyZW5hTWFwT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0QXJlbmFNYXAubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdEFyZW5hTWFwKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdEFyZW5hTWFwKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RBcmVuYU1hcCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKTsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKTsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKTsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKTsKICAgICAgICBjYXNlIDY6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKTsKICAgICAgICBjYXNlIDc6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpOwogICAgICAgIGNhc2UgODoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCk7CiAgICAgICAgY2FzZSA5OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpOwogICAgICAgIGNhc2UgMTA6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCk7CiAgICAgICAgY2FzZSAxMToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKTsKICAgICAgICBjYXNlIDEyOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKTsKICAgICAgICBjYXNlIDEzOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwQm9vbEJvb2woKTsKICAgICAgICBjYXNlIDE0OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU3RyaW5nU3RyaW5nKCk7CiAgICAgICAgY2FzZSAxNToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyQnl0ZXMoKTsKICAgICAgICBjYXNlIDE2OgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCk7CiAgICAgICAgY2FzZSAxNzoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0QXJlbmFNYXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfSU5UMzJfSU5UMzJfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcEludDMySW50MzJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMySW50MzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcEludDMySW50MzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpIHsKICAgICAgaWYgKG1hcEludDMySW50MzJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNYXBJbnQzMkludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcEludDMySW50MzJfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBJbnQzMkludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMySW50MzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9pbnQzMl9pbnQzMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEludDMySW50MzIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMySW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1hcEludDMySW50MzIoKSB7CiAgICAgIHJldHVybiBnZXRNYXBJbnQzMkludDMyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9pbnQzMl9pbnQzMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1hcEludDMySW50MzJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMySW50MzIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ludDMyX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJJbnQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ludDMyX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJJbnQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMySW50MzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfSU5UNjRfSU5UNjRfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcEludDY0SW50NjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDY0SW50NjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwSW50NjRJbnQ2NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCkgewogICAgICBpZiAobWFwSW50NjRJbnQ2NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcEludDY0SW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwSW50NjRJbnQ2NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcEludDY0SW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50NjRJbnQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgbWFwX2ludDY0X2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwSW50NjRJbnQ2NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50NjRJbnQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDY0SW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcEludDY0SW50NjQoKSB7CiAgICAgIHJldHVybiBnZXRNYXBJbnQ2NEludDY0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IG1hcF9pbnQ2NF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcEludDY0SW50NjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgbWFwX2ludDY0X2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE1hcEludDY0SW50NjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgbWFwX2ludDY0X2ludDY0ID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE1hcEludDY0SW50NjRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50NjRJbnQ2NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9VSU5UMzJfVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBVaW50MzJVaW50MzJEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFVpbnQzMlVpbnQzMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5VSU5UMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXBVaW50MzJVaW50MzJfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkgewogICAgICBpZiAobWFwVWludDMyVWludDMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwVWludDMyVWludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcFVpbnQzMlVpbnQzMl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcFVpbnQzMlVpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBVaW50MzJVaW50MzIoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwVWludDMyVWludDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBVaW50MzJVaW50MzIoKSB7CiAgICAgIHJldHVybiBnZXRNYXBVaW50MzJVaW50MzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBtYXBfdWludDMyX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1hcFVpbnQzMlVpbnQzMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRNYXBVaW50MzJVaW50MzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBtYXBfdWludDMyX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1hcFVpbnQzMlVpbnQzMk9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFVpbnQzMlVpbnQzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9VSU5UNjRfVUlOVDY0X0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBVaW50NjRVaW50NjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFVpbnQ2NFVpbnQ2NEVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlVJTlQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuVUlOVDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcFVpbnQ2NFVpbnQ2NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKSB7CiAgICAgIGlmIChtYXBVaW50NjRVaW50NjRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNYXBVaW50NjRVaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwVWludDY0VWludDY0XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TWFwVWludDY0VWludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBtYXBfdWludDY0X3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcFVpbnQ2NFVpbnQ2NCgKICAgICAgICBsb25nIGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwVWludDY0VWludDY0KCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwVWludDY0VWludDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRNYXBVaW50NjRVaW50NjQoKSB7CiAgICAgIHJldHVybiBnZXRNYXBVaW50NjRVaW50NjRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBtYXBfdWludDY0X3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcFVpbnQ2NFVpbnQ2NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwVWludDY0VWludDY0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0TWFwVWludDY0VWludDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwVWludDY0VWludDY0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBtYXBfdWludDY0X3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRNYXBVaW50NjRVaW50NjRPclRocm93KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwVWludDY0VWludDY0KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX1NJTlQzMl9TSU5UMzJfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcFNpbnQzMlNpbnQzMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwU2ludDMyU2ludDMyRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNJTlQzMiwKICAgICAgICAgICAgICAgICAgMCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcFNpbnQzMlNpbnQzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKSB7CiAgICAgIGlmIChtYXBTaW50MzJTaW50MzJfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNYXBTaW50MzJTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwU2ludDMyU2ludDMyXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TWFwU2ludDMyU2ludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNpbnQzMlNpbnQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBtYXBfc2ludDMyX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcFNpbnQzMlNpbnQzMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBTaW50MzJTaW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldE1hcFNpbnQzMlNpbnQzMigpIHsKICAgICAgcmV0dXJuIGdldE1hcFNpbnQzMlNpbnQzMk1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IG1hcF9zaW50MzJfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwU2ludDMyU2ludDMyTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBtYXBfc2ludDMyX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1hcFNpbnQzMlNpbnQzMk9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IG1hcF9zaW50MzJfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TWFwU2ludDMyU2ludDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX1NJTlQ2NF9TSU5UNjRfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcFNpbnQ2NFNpbnQ2NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwU2ludDY0U2ludDY0RW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0lOVDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TSU5UNjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwU2ludDY0U2ludDY0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpIHsKICAgICAgaWYgKG1hcFNpbnQ2NFNpbnQ2NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcFNpbnQ2NFNpbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtYXBTaW50NjRTaW50NjRfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBTaW50NjRTaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ludDY0U2ludDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IG1hcF9zaW50NjRfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwU2ludDY0U2ludDY0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBTaW50NjRTaW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcFNpbnQ2NFNpbnQ2NCgpIHsKICAgICAgcmV0dXJuIGdldE1hcFNpbnQ2NFNpbnQ2NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IG1hcF9zaW50NjRfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwU2ludDY0U2ludDY0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBtYXBfc2ludDY0X3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRNYXBTaW50NjRTaW50NjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IG1hcF9zaW50NjRfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE1hcFNpbnQ2NFNpbnQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfRklYRUQzMl9GSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBGaXhlZDMyRml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwRml4ZWQzMkZpeGVkMzJFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkZJWEVEMzIsCiAgICAgICAgICAgICAgICAgIDApOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXBGaXhlZDMyRml4ZWQzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpIHsKICAgICAgaWYgKG1hcEZpeGVkMzJGaXhlZDMyXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwRml4ZWQzMkZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwRml4ZWQzMkZpeGVkMzJfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBGaXhlZDMyRml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IG1hcF9maXhlZDMyX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBGaXhlZDMyRml4ZWQzMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEZpeGVkMzJGaXhlZDMyTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBGaXhlZDMyRml4ZWQzMigpIHsKICAgICAgcmV0dXJuIGdldE1hcEZpeGVkMzJGaXhlZDMyTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwRml4ZWQzMkZpeGVkMzJNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpeGVkMzJGaXhlZDMyKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TWFwRml4ZWQzMkZpeGVkMzJPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgbWFwX2ZpeGVkMzJfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1hcEZpeGVkMzJGaXhlZDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfRklYRUQ2NF9GSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDg7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBGaXhlZDY0Rml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwRml4ZWQ2NEZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GSVhFRDY0LAogICAgICAgICAgICAgICAgICAwTCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcEZpeGVkNjRGaXhlZDY0XzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICBpbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCkgewogICAgICBpZiAobWFwRml4ZWQ2NEZpeGVkNjRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNYXBGaXhlZDY0Rml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtYXBGaXhlZDY0Rml4ZWQ2NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcEZpeGVkNjRGaXhlZDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEZpeGVkNjRGaXhlZDY0KAogICAgICAgIGxvbmcga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEZpeGVkNjRGaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuIGdldE1hcEZpeGVkNjRGaXhlZDY0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBtYXBfZml4ZWQ2NF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwRml4ZWQ2NEZpeGVkNjRNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBtYXBfZml4ZWQ2NF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE1hcEZpeGVkNjRGaXhlZDY0T3JEZWZhdWx0KAogICAgICAgIGxvbmcga2V5LAogICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRNYXBGaXhlZDY0Rml4ZWQ2NE9yVGhyb3coCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9TRklYRUQzMl9TRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwU2ZpeGVkMzJTZml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwU2ZpeGVkMzJTZml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNGSVhFRDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwU2ZpeGVkMzJTZml4ZWQzMl87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCkgewogICAgICBpZiAobWFwU2ZpeGVkMzJTZml4ZWQzMl8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcFNmaXhlZDMyU2ZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwU2ZpeGVkMzJTZml4ZWQzMl87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcFNmaXhlZDMyU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwU2ZpeGVkMzJTZml4ZWQzMigKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwU2ZpeGVkMzJTZml4ZWQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpIHsKICAgICAgcmV0dXJuIGdldE1hcFNmaXhlZDMyU2ZpeGVkMzJNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwU2ZpeGVkMzJTZml4ZWQzMk1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9TRklYRUQ2NF9TRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSAxMDsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcFNmaXhlZDY0U2ZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFNmaXhlZDY0U2ZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TRklYRUQ2NCwKICAgICAgICAgICAgICAgICAgMEwsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU0ZJWEVENjQsCiAgICAgICAgICAgICAgICAgIDBMKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwU2ZpeGVkNjRTZml4ZWQ2NF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCkgewogICAgICBpZiAobWFwU2ZpeGVkNjRTZml4ZWQ2NF8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcFNmaXhlZDY0U2ZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwU2ZpeGVkNjRTZml4ZWQ2NF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcFNmaXhlZDY0U2ZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcFNmaXhlZDY0U2ZpeGVkNjQoCiAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBTZml4ZWQ2NFNmaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCkgewogICAgICByZXR1cm4gZ2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE1hcFNmaXhlZDY0U2ZpeGVkNjRPckRlZmF1bHQoCiAgICAgICAgbG9uZyBrZXksCiAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRNYXBTZml4ZWQ2NFNmaXhlZDY0T3JUaHJvdygKICAgICAgICBsb25nIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfSU5UMzJfRkxPQVRfRklFTERfTlVNQkVSID0gMTE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBJbnQzMkZsb2F0RGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMyRmxvYXRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5JTlQzMiwKICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5GTE9BVCwKICAgICAgICAgICAgICAgICAgMEYpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwSW50MzJGbG9hdF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4KICAgIGludGVybmFsR2V0TWFwSW50MzJGbG9hdCgpIHsKICAgICAgaWYgKG1hcEludDMyRmxvYXRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNYXBJbnQzMkZsb2F0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcEludDMyRmxvYXRfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBJbnQzMkZsb2F0Q291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IG1hcF9pbnQzMl9mbG9hdCA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBJbnQzMkZsb2F0KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkZsb2F0TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gZ2V0TWFwSW50MzJGbG9hdCgpIHsKICAgICAgcmV0dXJuIGdldE1hcEludDMyRmxvYXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgbWFwX2ludDMyX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRNYXBJbnQzMkZsb2F0TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IG1hcF9pbnQzMl9mbG9hdCA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldE1hcEludDMyRmxvYXRPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJGbG9hdCgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IG1hcF9pbnQzMl9mbG9hdCA9IDExOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldE1hcEludDMyRmxvYXRPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5GbG9hdD4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJGbG9hdCgpLmdldE1hcCgpOwogICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgfQogICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9JTlQzMl9ET1VCTEVfRklFTERfTlVNQkVSID0gMTI7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBJbnQzMkRvdWJsZURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMyRG91YmxlRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuRE9VQkxFLAogICAgICAgICAgICAgICAgICAwRCk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwSW50MzJEb3VibGVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpIHsKICAgICAgaWYgKG1hcEludDMyRG91YmxlXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwSW50MzJEb3VibGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwSW50MzJEb3VibGVfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBJbnQzMkRvdWJsZUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IG1hcF9pbnQzMl9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJEb3VibGUoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkRvdWJsZU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBnZXRNYXBJbnQzMkRvdWJsZSgpIHsKICAgICAgcmV0dXJuIGdldE1hcEludDMyRG91YmxlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBtYXBfaW50MzJfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0TWFwSW50MzJEb3VibGVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRG91YmxlKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBtYXBfaW50MzJfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldE1hcEludDMyRG91YmxlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgbWFwX2ludDMyX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXRNYXBJbnQzMkRvdWJsZU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfQk9PTF9CT09MX0ZJRUxEX05VTUJFUiA9IDEzOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwQm9vbEJvb2xEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEJvb2xCb29sRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQk9PTCwKICAgICAgICAgICAgICAgICAgZmFsc2UpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXBCb29sQm9vbF87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPgogICAgaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpIHsKICAgICAgaWYgKG1hcEJvb2xCb29sXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwQm9vbEJvb2xEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwQm9vbEJvb2xfOwogICAgfQogICAgcHVibGljIGludCBnZXRNYXBCb29sQm9vbENvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IG1hcF9ib29sX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwQm9vbEJvb2woCiAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEJvb2xCb29sKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwQm9vbEJvb2xNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IGdldE1hcEJvb2xCb29sKCkgewogICAgICByZXR1cm4gZ2V0TWFwQm9vbEJvb2xNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IG1hcF9ib29sX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0TWFwQm9vbEJvb2xNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEJvb2xCb29sKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtib29sLCBib29sJmd0OyBtYXBfYm9vbF9ib29sID0gMTM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRNYXBCb29sQm9vbE9yRGVmYXVsdCgKICAgICAgICBib29sZWFuIGtleSwKICAgICAgICBib29sZWFuIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEJvb2xCb29sKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IG1hcF9ib29sX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldE1hcEJvb2xCb29sT3JUaHJvdygKICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEJvb2xCb29sKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX1NUUklOR19TVFJJTkdfRklFTERfTlVNQkVSID0gMTQ7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBTdHJpbmdTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz5uZXdEZWZhdWx0SW5zdGFuY2UoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwU3RyaW5nU3RyaW5nRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcFN0cmluZ1N0cmluZ187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0TWFwU3RyaW5nU3RyaW5nKCkgewogICAgICBpZiAobWFwU3RyaW5nU3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwU3RyaW5nU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcFN0cmluZ1N0cmluZ187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcFN0cmluZ1N0cmluZ0NvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwU3RyaW5nU3RyaW5nKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBTdHJpbmdTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNYXBTdHJpbmdTdHJpbmcoKSB7CiAgICAgIHJldHVybiBnZXRNYXBTdHJpbmdTdHJpbmdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfc3RyaW5nX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0TWFwU3RyaW5nU3RyaW5nTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfc3RyaW5nX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0TWFwU3RyaW5nU3RyaW5nT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFN0cmluZ1N0cmluZygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE1hcFN0cmluZ1N0cmluZ09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwU3RyaW5nU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0lOVDMyX0JZVEVTX0ZJRUxEX05VTUJFUiA9IDE1OwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwSW50MzJCeXRlc0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkJ5dGVzRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuQllURVMsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXBJbnQzMkJ5dGVzXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkgewogICAgICBpZiAobWFwSW50MzJCeXRlc18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcEludDMyQnl0ZXNEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwSW50MzJCeXRlc187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcEludDMyQnl0ZXNDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJCeXRlcygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2ludDMyX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEludDMyQnl0ZXMoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJCeXRlcygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyQnl0ZXNNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRNYXBJbnQzMkJ5dGVzKCkgewogICAgICByZXR1cm4gZ2V0TWFwSW50MzJCeXRlc01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfaW50MzJfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldE1hcEludDMyQnl0ZXNNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyQnl0ZXMoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBieXRlcyZndDsgbWFwX2ludDMyX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE1hcEludDMyQnl0ZXNPckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyQnl0ZXMoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfaW50MzJfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0TWFwSW50MzJCeXRlc09yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0lOVDMyX0VOVU1fRklFTERfTlVNQkVSID0gMTY7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBNYXBJbnQzMkVudW1EZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMyRW51bUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLkVOVU0sCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0uTUFQX0VOVU1fRk9PLmdldE51bWJlcigpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwSW50MzJFbnVtXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpIHsKICAgICAgaWYgKG1hcEludDMyRW51bV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcEludDMyRW51bURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtYXBJbnQzMkVudW1fOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0+IG1hcEludDMyRW51bVZhbHVlQ29udmVydGVyID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5NYXBBZGFwdGVyLm5ld0VudW1Db252ZXJ0ZXIoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtLmludGVybmFsR2V0VmFsdWVNYXAoKSwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0uVU5SRUNPR05JWkVEKTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0+CiAgICBpbnRlcm5hbEdldEFkYXB0ZWRNYXBJbnQzMkVudW1NYXAoCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTWFwQWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtLCBqYXZhLmxhbmcuSW50ZWdlcj4oCiAgICAgICAgICAgICAgbWFwLCBtYXBJbnQzMkVudW1WYWx1ZUNvbnZlcnRlcik7CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcEludDMyRW51bUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEludDMyRW51bSgKICAgICAgICBpbnQga2V5KSB7CgogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkVudW1NYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWFwRW51bT4KICAgIGdldE1hcEludDMyRW51bSgpIHsKICAgICAgcmV0dXJuIGdldE1hcEludDMyRW51bU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0+CiAgICBnZXRNYXBJbnQzMkVudW1NYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldEFkYXB0ZWRNYXBJbnQzMkVudW1NYXAoCiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpLmdldE1hcCgpKTt9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWFwRW51bSBnZXRNYXBJbnQzMkVudW1PckRlZmF1bHQoCiAgICAgICAgaW50IGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgID8gbWFwSW50MzJFbnVtVmFsdWVDb252ZXJ0ZXIuZG9Gb3J3YXJkKG1hcC5nZXQoa2V5KSkKICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0gZ2V0TWFwSW50MzJFbnVtT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXBJbnQzMkVudW1WYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgIH0KICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJFbnVtVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRNYXBJbnQzMkVudW1WYWx1ZSgpIHsKICAgICAgcmV0dXJuIGdldE1hcEludDMyRW51bVZhbHVlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRNYXBJbnQzMkVudW1WYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1hcEludDMyRW51bVZhbHVlT3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1hcEludDMyRW51bVZhbHVlT3JUaHJvdygKICAgICAgICBpbnQga2V5KSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX0lOVDMyX0ZPUkVJR05fTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAxNzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcEludDMyRm9yZWlnbk1lc3NhZ2VEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkZvcmVpZ25NZXNzYWdlRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuSU5UMzIsCiAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gbWFwSW50MzJGb3JlaWduTWVzc2FnZV87CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+CiAgICBpbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgIGlmIChtYXBJbnQzMkZvcmVpZ25NZXNzYWdlXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgTWFwSW50MzJGb3JlaWduTWVzc2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtYXBJbnQzMkZvcmVpZ25NZXNzYWdlXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IGdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlTWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UmZ3Q7IG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UgPSAxNzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIGdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2VPclRocm93KAogICAgICAgIGludCBrZXkpIHsKCiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpLAogICAgICAgICAgTWFwSW50MzJJbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCksCiAgICAgICAgICBNYXBJbnQ2NEludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcFVpbnQzMlVpbnQzMigpLAogICAgICAgICAgTWFwVWludDMyVWludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpLAogICAgICAgICAgTWFwVWludDY0VWludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDQpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcFNpbnQzMlNpbnQzMigpLAogICAgICAgICAgTWFwU2ludDMyU2ludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDUpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVMb25nTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpLAogICAgICAgICAgTWFwU2ludDY0U2ludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpeGVkMzJGaXhlZDMyKCksCiAgICAgICAgICBNYXBGaXhlZDMyRml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA3KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpLAogICAgICAgICAgTWFwRml4ZWQ2NEZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgOCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLAogICAgICAgICAgTWFwU2ZpeGVkMzJTZml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA5KTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplTG9uZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCksCiAgICAgICAgICBNYXBTZml4ZWQ2NFNmaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDEwKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCksCiAgICAgICAgICBNYXBJbnQzMkZsb2F0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDExKTsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuc2VyaWFsaXplSW50ZWdlck1hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpLAogICAgICAgICAgTWFwSW50MzJEb3VibGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTIpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVCb29sZWFuTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcEJvb2xCb29sKCksCiAgICAgICAgICBNYXBCb29sQm9vbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMyk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKSwKICAgICAgICAgIE1hcFN0cmluZ1N0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJCeXRlcygpLAogICAgICAgICAgTWFwSW50MzJCeXRlc0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxNSk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZUludGVnZXJNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCksCiAgICAgICAgICBNYXBJbnQzMkVudW1EZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTYpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKSwKICAgICAgICAgIE1hcEludDMyRm9yZWlnbk1lc3NhZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LAogICAgICAgICAgMTcpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBtYXBJbnQzMkludDMyX18gPSBNYXBJbnQzMkludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBtYXBJbnQzMkludDMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgbWFwSW50NjRJbnQ2NF9fID0gTWFwSW50NjRJbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgbWFwSW50NjRJbnQ2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgbWFwVWludDMyVWludDMyX18gPSBNYXBVaW50MzJVaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIG1hcFVpbnQzMlVpbnQzMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgbWFwVWludDY0VWludDY0X18gPSBNYXBVaW50NjRVaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQsIG1hcFVpbnQ2NFVpbnQ2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgbWFwU2ludDMyU2ludDMyX18gPSBNYXBTaW50MzJTaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIG1hcFNpbnQzMlNpbnQzMl9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgbWFwU2ludDY0U2ludDY0X18gPSBNYXBTaW50NjRTaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDYsIG1hcFNpbnQ2NFNpbnQ2NF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBtYXBGaXhlZDMyRml4ZWQzMl9fID0gTWFwRml4ZWQzMkZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcsIG1hcEZpeGVkMzJGaXhlZDMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgIG1hcEZpeGVkNjRGaXhlZDY0X18gPSBNYXBGaXhlZDY0Rml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOCwgbWFwRml4ZWQ2NEZpeGVkNjRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBtYXBTZml4ZWQzMlNmaXhlZDMyX18gPSBNYXBTZml4ZWQzMlNmaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5LCBtYXBTZml4ZWQzMlNmaXhlZDMyX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgbWFwU2ZpeGVkNjRTZml4ZWQ2NF9fID0gTWFwU2ZpeGVkNjRTZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTAsIG1hcFNmaXhlZDY0U2ZpeGVkNjRfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgIG1hcEludDMyRmxvYXRfXyA9IE1hcEludDMyRmxvYXREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExLCBtYXBJbnQzMkZsb2F0X18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBtYXBJbnQzMkRvdWJsZV9fID0gTWFwSW50MzJEb3VibGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEyLCBtYXBJbnQzMkRvdWJsZV9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBtYXBCb29sQm9vbF9fID0gTWFwQm9vbEJvb2xEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEzLCBtYXBCb29sQm9vbF9fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwU3RyaW5nU3RyaW5nKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICBtYXBTdHJpbmdTdHJpbmdfXyA9IE1hcFN0cmluZ1N0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTQsIG1hcFN0cmluZ1N0cmluZ19fKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwSW50MzJCeXRlcygpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgbWFwSW50MzJCeXRlc19fID0gTWFwSW50MzJCeXRlc0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTUsIG1hcEludDMyQnl0ZXNfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwSW50MzJFbnVtKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIG1hcEludDMyRW51bV9fID0gTWFwSW50MzJFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNiwgbWFwSW50MzJFbnVtX18pOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPgogICAgICAgIG1hcEludDMyRm9yZWlnbk1lc3NhZ2VfXyA9IE1hcEludDMyRm9yZWlnbk1lc3NhZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE3LCBtYXBJbnQzMkZvcmVpZ25NZXNzYWdlX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdEFyZW5hTWFwIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcCkgb2JqOwoKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcEludDMySW50MzIoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEludDMySW50MzIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEludDY0SW50NjQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcFVpbnQzMlVpbnQzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwU2ludDY0U2ludDY0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwSW50MzJGbG9hdCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwSW50MzJGbG9hdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEludDMyRG91YmxlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwQm9vbEJvb2woKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFpbnRlcm5hbEdldE1hcFN0cmluZ1N0cmluZygpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwU3RyaW5nU3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEludDMyRW51bSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX0lOVDMyX0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcEludDMySW50MzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX0lOVDY0X0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfVUlOVDMyX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfVUlOVDY0X1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfU0lOVDMyX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfU0lOVDY0X1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1BUF9GSVhFRDMyX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1BUF9GSVhFRDY0X0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX1NGSVhFRDMyX1NGSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX1NGSVhFRDY0X1NGSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX0lOVDMyX0ZMT0FUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1BUF9JTlQzMl9ET1VCTEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1BUF9CT09MX0JPT0xfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TWFwQm9vbEJvb2woKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfU1RSSU5HX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBTdHJpbmdTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX0lOVDMyX0JZVEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcEludDMyQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5nZXRNYXAoKS5pc0VtcHR5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNQVBfSU5UMzJfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX0lOVDMyX0ZPUkVJR05fTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdEFyZW5hTWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdEFyZW5hTWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdEFyZW5hTWFwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcCBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0QXJlbmFNYXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdEFyZW5hTWFwIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdEFyZW5hTWFwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0QXJlbmFNYXAgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0QXJlbmFNYXAgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFyZW5hTWFwfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFyZW5hTWFwKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCk7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFVpbnQzMlVpbnQzMigpOwogICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCk7CiAgICAgICAgICBjYXNlIDY6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpOwogICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpOwogICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpOwogICAgICAgICAgY2FzZSA5OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCk7CiAgICAgICAgICBjYXNlIDEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCk7CiAgICAgICAgICBjYXNlIDExOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCk7CiAgICAgICAgICBjYXNlIDEyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpOwogICAgICAgICAgY2FzZSAxMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwQm9vbEJvb2woKTsKICAgICAgICAgIGNhc2UgMTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFN0cmluZ1N0cmluZygpOwogICAgICAgICAgY2FzZSAxNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJCeXRlcygpOwogICAgICAgICAgY2FzZSAxNjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCk7CiAgICAgICAgICBjYXNlIDE3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJJbnQzMigpOwogICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50NjRJbnQ2NCgpOwogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDMyVWludDMyKCk7CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50NjRVaW50NjQoKTsKICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcFNpbnQzMlNpbnQzMigpOwogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDY0U2ludDY0KCk7CiAgICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBGaXhlZDMyRml4ZWQzMigpOwogICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQ2NEZpeGVkNjQoKTsKICAgICAgICAgIGNhc2UgOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDMyU2ZpeGVkMzIoKTsKICAgICAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBTZml4ZWQ2NFNmaXhlZDY0KCk7CiAgICAgICAgICBjYXNlIDExOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGbG9hdCgpOwogICAgICAgICAgY2FzZSAxMjoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRG91YmxlKCk7CiAgICAgICAgICBjYXNlIDEzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwQm9vbEJvb2woKTsKICAgICAgICAgIGNhc2UgMTQ6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdTdHJpbmcoKTsKICAgICAgICAgIGNhc2UgMTU6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkJ5dGVzKCk7CiAgICAgICAgICBjYXNlIDE2OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJFbnVtKCk7CiAgICAgICAgICBjYXNlIDE3OgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGb3JlaWduTWVzc2FnZSgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0QXJlbmFNYXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcC5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJJbnQzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50NjRJbnQ2NCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDMyVWludDMyKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50NjRVaW50NjQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNpbnQzMlNpbnQzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDY0U2ludDY0KCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaXhlZDMyRml4ZWQzMigpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQ2NEZpeGVkNjQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRmxvYXQoKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRG91YmxlKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBCb29sQm9vbCgpLmNsZWFyKCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nU3RyaW5nKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkJ5dGVzKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkVudW0oKS5jbGVhcigpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0QXJlbmFNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcCBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0QXJlbmFNYXAgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0QXJlbmFNYXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcCByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdEFyZW5hTWFwKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMySW50MzJfID0gaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCk7CiAgICAgICAgICByZXN1bHQubWFwSW50MzJJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDY0SW50NjRfID0gaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCk7CiAgICAgICAgICByZXN1bHQubWFwSW50NjRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFVpbnQzMlVpbnQzMl8gPSBpbnRlcm5hbEdldE1hcFVpbnQzMlVpbnQzMigpOwogICAgICAgICAgcmVzdWx0Lm1hcFVpbnQzMlVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFVpbnQ2NFVpbnQ2NF8gPSBpbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpOwogICAgICAgICAgcmVzdWx0Lm1hcFVpbnQ2NFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFNpbnQzMlNpbnQzMl8gPSBpbnRlcm5hbEdldE1hcFNpbnQzMlNpbnQzMigpOwogICAgICAgICAgcmVzdWx0Lm1hcFNpbnQzMlNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFNpbnQ2NFNpbnQ2NF8gPSBpbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpOwogICAgICAgICAgcmVzdWx0Lm1hcFNpbnQ2NFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEZpeGVkMzJGaXhlZDMyXyA9IGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKTsKICAgICAgICAgIHJlc3VsdC5tYXBGaXhlZDMyRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEZpeGVkNjRGaXhlZDY0XyA9IGludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKTsKICAgICAgICAgIHJlc3VsdC5tYXBGaXhlZDY0Rml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFNmaXhlZDMyU2ZpeGVkMzJfID0gaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCk7CiAgICAgICAgICByZXN1bHQubWFwU2ZpeGVkMzJTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFNmaXhlZDY0U2ZpeGVkNjRfID0gaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCk7CiAgICAgICAgICByZXN1bHQubWFwU2ZpeGVkNjRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMyRmxvYXRfID0gaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCk7CiAgICAgICAgICByZXN1bHQubWFwSW50MzJGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMyRG91YmxlXyA9IGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKTsKICAgICAgICAgIHJlc3VsdC5tYXBJbnQzMkRvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEJvb2xCb29sXyA9IGludGVybmFsR2V0TWFwQm9vbEJvb2woKTsKICAgICAgICAgIHJlc3VsdC5tYXBCb29sQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFN0cmluZ1N0cmluZ18gPSBpbnRlcm5hbEdldE1hcFN0cmluZ1N0cmluZygpOwogICAgICAgICAgcmVzdWx0Lm1hcFN0cmluZ1N0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMyQnl0ZXNfID0gaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCk7CiAgICAgICAgICByZXN1bHQubWFwSW50MzJCeXRlc18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMyRW51bV8gPSBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpOwogICAgICAgICAgcmVzdWx0Lm1hcEludDMyRW51bV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEludDMyRm9yZWlnbk1lc3NhZ2VfID0gaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuYnVpbGQoTWFwSW50MzJGb3JlaWduTWVzc2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcCkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdEFyZW5hTWFwKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RBcmVuYU1hcCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0QXJlbmFNYXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMySW50MzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwSW50MzJJbnQzMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50NjRJbnQ2NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50MzJVaW50MzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50NjRVaW50NjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwVWludDY0VWludDY0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50MzJTaW50MzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50NjRTaW50NjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwU2ludDY0U2ludDY0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaXhlZDMyRml4ZWQzMigpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQ2NEZpeGVkNjQoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ZpeGVkNjRTZml4ZWQ2NCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkZsb2F0KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRG91YmxlKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEludDMyRG91YmxlKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBCb29sQm9vbCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nU3RyaW5nKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcFN0cmluZ1N0cmluZygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJCeXRlcygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkVudW0oKS5tZXJnZUZyb20oCiAgICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwSW50MzJFbnVtKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgbWFwSW50MzJJbnQzMl9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwSW50MzJJbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkludDMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBJbnQzMkludDMyX18uZ2V0S2V5KCksIG1hcEludDMySW50MzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgbWFwSW50NjRJbnQ2NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwSW50NjRJbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQ2NEludDY0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBJbnQ2NEludDY0X18uZ2V0S2V5KCksIG1hcEludDY0SW50NjRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICAgICAgbWFwVWludDMyVWludDMyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXBVaW50MzJVaW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDMyVWludDMyKCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBVaW50MzJVaW50MzJfXy5nZXRLZXkoKSwgbWFwVWludDMyVWludDMyX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgICAgICAgIG1hcFVpbnQ2NFVpbnQ2NF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwVWludDY0VWludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFVpbnQ2NFVpbnQ2NCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwVWludDY0VWludDY0X18uZ2V0S2V5KCksIG1hcFVpbnQ2NFVpbnQ2NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBtYXBTaW50MzJTaW50MzJfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcFNpbnQzMlNpbnQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50MzJTaW50MzIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcFNpbnQzMlNpbnQzMl9fLmdldEtleSgpLCBtYXBTaW50MzJTaW50MzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MgogICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgbWFwU2ludDY0U2ludDY0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXBTaW50NjRTaW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDY0U2ludDY0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBTaW50NjRTaW50NjRfXy5nZXRLZXkoKSwgbWFwU2ludDY0U2ludDY0X18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIG1hcEZpeGVkMzJGaXhlZDMyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXBGaXhlZDMyRml4ZWQzMkRlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaXhlZDMyRml4ZWQzMigpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwRml4ZWQzMkZpeGVkMzJfXy5nZXRLZXkoKSwgbWFwRml4ZWQzMkZpeGVkMzJfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1OAogICAgICAgICAgICAgIGNhc2UgNjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgICAgICAgbWFwRml4ZWQ2NEZpeGVkNjRfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcEZpeGVkNjRGaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpeGVkNjRGaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBGaXhlZDY0Rml4ZWQ2NF9fLmdldEtleSgpLCBtYXBGaXhlZDY0Rml4ZWQ2NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY2CiAgICAgICAgICAgICAgY2FzZSA3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICAgICAgICBtYXBTZml4ZWQzMlNmaXhlZDMyX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXBTZml4ZWQzMlNmaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcFNmaXhlZDMyU2ZpeGVkMzJfXy5nZXRLZXkoKSwgbWFwU2ZpeGVkMzJTZml4ZWQzMl9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICAgICAgICBtYXBTZml4ZWQ2NFNmaXhlZDY0X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXBTZml4ZWQ2NFNmaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcFNmaXhlZDY0U2ZpeGVkNjRfXy5nZXRLZXkoKSwgbWFwU2ZpeGVkNjRTZml4ZWQ2NF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgyCiAgICAgICAgICAgICAgY2FzZSA5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgICAgICAgbWFwSW50MzJGbG9hdF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwSW50MzJGbG9hdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkZsb2F0KCkuZ2V0TXV0YWJsZU1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBJbnQzMkZsb2F0X18uZ2V0S2V5KCksIG1hcEludDMyRmxvYXRfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICAgIGNhc2UgOTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICAgICAgICBtYXBJbnQzMkRvdWJsZV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwSW50MzJEb3VibGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJEb3VibGUoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcEludDMyRG91YmxlX18uZ2V0S2V5KCksIG1hcEludDMyRG91YmxlX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTgKICAgICAgICAgICAgICBjYXNlIDEwNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICAgICAgICBtYXBCb29sQm9vbF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwQm9vbEJvb2xEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwQm9vbEJvb2woKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcEJvb2xCb29sX18uZ2V0S2V5KCksIG1hcEJvb2xCb29sX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA2CiAgICAgICAgICAgICAgY2FzZSAxMTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIG1hcFN0cmluZ1N0cmluZ19fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwU3RyaW5nU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFN0cmluZ1N0cmluZygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwU3RyaW5nU3RyaW5nX18uZ2V0S2V5KCksIG1hcFN0cmluZ1N0cmluZ19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExNAogICAgICAgICAgICAgIGNhc2UgMTIyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICAgICAgICBtYXBJbnQzMkJ5dGVzX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXBJbnQzMkJ5dGVzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyQnl0ZXMoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcEludDMyQnl0ZXNfXy5nZXRLZXkoKSwgbWFwSW50MzJCeXRlc19fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMgogICAgICAgICAgICAgIGNhc2UgMTMwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIG1hcEludDMyRW51bV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwSW50MzJFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRW51bSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwSW50MzJFbnVtX18uZ2V0S2V5KCksIG1hcEludDMyRW51bV9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzMAogICAgICAgICAgICAgIGNhc2UgMTM4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPgogICAgICAgICAgICAgICAgbWFwSW50MzJGb3JlaWduTWVzc2FnZV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwSW50MzJGb3JlaWduTWVzc2FnZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBtYXBJbnQzMkZvcmVpZ25NZXNzYWdlX18uZ2V0S2V5KCksIG1hcEludDMyRm9yZWlnbk1lc3NhZ2VfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXBJbnQzMkludDMyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpIHsKICAgICAgICBpZiAobWFwSW50MzJJbnQzMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBJbnQzMkludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBJbnQzMkludDMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJJbnQzMigpIHsKICAgICAgICBpZiAobWFwSW50MzJJbnQzMl8gPT0gbnVsbCkgewogICAgICAgICAgbWFwSW50MzJJbnQzMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEludDMySW50MzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtYXBJbnQzMkludDMyXy5pc011dGFibGUoKSkgewogICAgICAgICAgbWFwSW50MzJJbnQzMl8gPSBtYXBJbnQzMkludDMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwSW50MzJJbnQzMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBJbnQzMkludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ludDMyX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJJbnQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJJbnQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMySW50MzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwSW50MzJJbnQzMigpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwSW50MzJJbnQzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXBfaW50MzJfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBJbnQzMkludDMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMySW50MzIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgbWFwX2ludDMyX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJJbnQzMk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMySW50MzIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9pbnQzMl9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE1hcEludDMySW50MzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkludDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcEludDMySW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMySW50MzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IG1hcF9pbnQzMl9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwSW50MzJJbnQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJJbnQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcEludDMySW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkludDMyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXBfaW50MzJfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1hcEludDMySW50MzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBtYXBfaW50MzJfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcEludDMySW50MzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJJbnQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcEludDY0SW50NjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCkgewogICAgICAgIGlmIChtYXBJbnQ2NEludDY0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEludDY0SW50NjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEludDY0SW50NjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQ2NEludDY0KCkgewogICAgICAgIGlmIChtYXBJbnQ2NEludDY0XyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBJbnQ2NEludDY0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwSW50NjRJbnQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW1hcEludDY0SW50NjRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBJbnQ2NEludDY0XyA9IG1hcEludDY0SW50NjRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtYXBJbnQ2NEludDY0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcEludDY0SW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQ2NEludDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBtYXBfaW50NjRfaW50NjQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBJbnQ2NEludDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50NjRJbnQ2NCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDY0SW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwSW50NjRJbnQ2NCgpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwSW50NjRJbnQ2NE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBtYXBfaW50NjRfaW50NjQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRNYXBJbnQ2NEludDY0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgbWFwX2ludDY0X2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE1hcEludDY0SW50NjRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IG1hcF9pbnQ2NF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRNYXBJbnQ2NEludDY0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDY0SW50NjQoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwSW50NjRJbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50NjRJbnQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDY0LCBpbnQ2NCZndDsgbWFwX2ludDY0X2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBJbnQ2NEludDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50NjRJbnQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcEludDY0SW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQ2NEludDY0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50NjQsIGludDY0Jmd0OyBtYXBfaW50NjRfaW50NjQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1hcEludDY0SW50NjQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDY0SW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQ2NCwgaW50NjQmZ3Q7IG1hcF9pbnQ2NF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwSW50NjRJbnQ2NCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQ2NEludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwVWludDMyVWludDMyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkgewogICAgICAgIGlmIChtYXBVaW50MzJVaW50MzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwVWludDMyVWludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBVaW50MzJVaW50MzJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50MzJVaW50MzIoKSB7CiAgICAgICAgaWYgKG1hcFVpbnQzMlVpbnQzMl8gPT0gbnVsbCkgewogICAgICAgICAgbWFwVWludDMyVWludDMyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwVWludDMyVWludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwVWludDMyVWludDMyXy5pc011dGFibGUoKSkgewogICAgICAgICAgbWFwVWludDMyVWludDMyXyA9IG1hcFVpbnQzMlVpbnQzMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcFVpbnQzMlVpbnQzMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBVaW50MzJVaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVaW50MzJVaW50MzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50MzIsIHVpbnQzMiZndDsgbWFwX3VpbnQzMl91aW50MzIgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBVaW50MzJVaW50MzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFVpbnQzMlVpbnQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFVpbnQzMlVpbnQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBVaW50MzJVaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcFVpbnQzMlVpbnQzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IG1hcF91aW50MzJfdWludDMyID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwVWludDMyVWludDMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFVpbnQzMlVpbnQzMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IG1hcF91aW50MzJfdWludDMyID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwVWludDMyVWludDMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IG1hcF91aW50MzJfdWludDMyID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwVWludDMyVWludDMyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwVWludDMyVWludDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcFVpbnQzMlVpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDMyVWludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IG1hcF91aW50MzJfdWludDMyID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBVaW50MzJVaW50MzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFVpbnQzMlVpbnQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcFVpbnQzMlVpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcFVpbnQzMlVpbnQzMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQzMiwgdWludDMyJmd0OyBtYXBfdWludDMyX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwVWludDMyVWludDMyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDMyVWludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDMyLCB1aW50MzImZ3Q7IG1hcF91aW50MzJfdWludDMyID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBVaW50MzJVaW50MzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDMyVWludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwVWludDY0VWludDY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TWFwVWludDY0VWludDY0KCkgewogICAgICAgIGlmIChtYXBVaW50NjRVaW50NjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwVWludDY0VWludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBVaW50NjRVaW50NjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50NjRVaW50NjQoKSB7CiAgICAgICAgaWYgKG1hcFVpbnQ2NFVpbnQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgbWFwVWludDY0VWludDY0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwVWludDY0VWludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwVWludDY0VWludDY0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgbWFwVWludDY0VWludDY0XyA9IG1hcFVpbnQ2NFVpbnQ2NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcFVpbnQ2NFVpbnQ2NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBVaW50NjRVaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBVaW50NjRVaW50NjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBVaW50NjRVaW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwVWludDY0VWludDY0KCkgewogICAgICAgIHJldHVybiBnZXRNYXBVaW50NjRVaW50NjRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBtYXBfdWludDY0X3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcFVpbnQ2NFVpbnQ2NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVaW50NjRVaW50NjQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBtYXBfdWludDY0X3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRNYXBVaW50NjRVaW50NjRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcFVpbnQ2NFVpbnQ2NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3VpbnQ2NCwgdWludDY0Jmd0OyBtYXBfdWludDY0X3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRNYXBVaW50NjRVaW50NjRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwVWludDY0VWludDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcFVpbnQ2NFVpbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDY0VWludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IG1hcF91aW50NjRfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBVaW50NjRVaW50NjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50NjRVaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVNYXBVaW50NjRVaW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBVaW50NjRVaW50NjQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDt1aW50NjQsIHVpbnQ2NCZndDsgbWFwX3VpbnQ2NF91aW50NjQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1hcFVpbnQ2NFVpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDY0VWludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7dWludDY0LCB1aW50NjQmZ3Q7IG1hcF91aW50NjRfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBVaW50NjRVaW50NjQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVWludDY0VWludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwU2ludDMyU2ludDMyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCkgewogICAgICAgIGlmIChtYXBTaW50MzJTaW50MzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwU2ludDMyU2ludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBTaW50MzJTaW50MzJfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50MzJTaW50MzIoKSB7CiAgICAgICAgaWYgKG1hcFNpbnQzMlNpbnQzMl8gPT0gbnVsbCkgewogICAgICAgICAgbWFwU2ludDMyU2ludDMyXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwU2ludDMyU2ludDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwU2ludDMyU2ludDMyXy5pc011dGFibGUoKSkgewogICAgICAgICAgbWFwU2ludDMyU2ludDMyXyA9IG1hcFNpbnQzMlNpbnQzMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcFNpbnQzMlNpbnQzMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBTaW50MzJTaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTaW50MzJTaW50MzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50MzIsIHNpbnQzMiZndDsgbWFwX3NpbnQzMl9zaW50MzIgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBTaW50MzJTaW50MzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNpbnQzMlNpbnQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFNpbnQzMlNpbnQzMk1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBTaW50MzJTaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcFNpbnQzMlNpbnQzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IG1hcF9zaW50MzJfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwU2ludDMyU2ludDMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNpbnQzMlNpbnQzMigpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IG1hcF9zaW50MzJfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwU2ludDMyU2ludDMyT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IG1hcF9zaW50MzJfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwU2ludDMyU2ludDMyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwU2ludDMyU2ludDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcFNpbnQzMlNpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDMyU2ludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IG1hcF9zaW50MzJfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBTaW50MzJTaW50MzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNpbnQzMlNpbnQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcFNpbnQzMlNpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcFNpbnQzMlNpbnQzMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQzMiwgc2ludDMyJmd0OyBtYXBfc2ludDMyX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwU2ludDMyU2ludDMyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDMyU2ludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDMyLCBzaW50MzImZ3Q7IG1hcF9zaW50MzJfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBTaW50MzJTaW50MzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDMyU2ludDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwU2ludDY0U2ludDY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TWFwU2ludDY0U2ludDY0KCkgewogICAgICAgIGlmIChtYXBTaW50NjRTaW50NjRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwU2ludDY0U2ludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBTaW50NjRTaW50NjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50NjRTaW50NjQoKSB7CiAgICAgICAgaWYgKG1hcFNpbnQ2NFNpbnQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgbWFwU2ludDY0U2ludDY0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwU2ludDY0U2ludDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwU2ludDY0U2ludDY0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgbWFwU2ludDY0U2ludDY0XyA9IG1hcFNpbnQ2NFNpbnQ2NF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcFNpbnQ2NFNpbnQ2NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBTaW50NjRTaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgbWFwX3NpbnQ2NF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBTaW50NjRTaW50NjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBTaW50NjRTaW50NjRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gZ2V0TWFwU2ludDY0U2ludDY0KCkgewogICAgICAgIHJldHVybiBnZXRNYXBTaW50NjRTaW50NjRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBtYXBfc2ludDY0X3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcFNpbnQ2NFNpbnQ2NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTaW50NjRTaW50NjQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBtYXBfc2ludDY0X3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRNYXBTaW50NjRTaW50NjRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcFNpbnQ2NFNpbnQ2NCgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NpbnQ2NCwgc2ludDY0Jmd0OyBtYXBfc2ludDY0X3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRNYXBTaW50NjRTaW50NjRPclRocm93KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwU2ludDY0U2ludDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcFNpbnQ2NFNpbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDY0U2ludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IG1hcF9zaW50NjRfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBTaW50NjRTaW50NjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50NjRTaW50NjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVNYXBTaW50NjRTaW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBTaW50NjRTaW50NjQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzaW50NjQsIHNpbnQ2NCZndDsgbWFwX3NpbnQ2NF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1hcFNpbnQ2NFNpbnQ2NCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDY0U2ludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ludDY0LCBzaW50NjQmZ3Q7IG1hcF9zaW50NjRfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBTaW50NjRTaW50NjQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ludDY0U2ludDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwRml4ZWQzMkZpeGVkMzJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBGaXhlZDMyRml4ZWQzMigpIHsKICAgICAgICBpZiAobWFwRml4ZWQzMkZpeGVkMzJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwRml4ZWQzMkZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEZpeGVkMzJGaXhlZDMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQzMkZpeGVkMzIoKSB7CiAgICAgICAgaWYgKG1hcEZpeGVkMzJGaXhlZDMyXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBGaXhlZDMyRml4ZWQzMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEZpeGVkMzJGaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwRml4ZWQzMkZpeGVkMzJfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBGaXhlZDMyRml4ZWQzMl8gPSBtYXBGaXhlZDMyRml4ZWQzMl8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcEZpeGVkMzJGaXhlZDMyXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcEZpeGVkMzJGaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwRml4ZWQzMkZpeGVkMzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpeGVkMzJGaXhlZDMyKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwRml4ZWQzMkZpeGVkMzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwRml4ZWQzMkZpeGVkMzIoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcEZpeGVkMzJGaXhlZDMyTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwRml4ZWQzMkZpeGVkMzJNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IG1hcF9maXhlZDMyX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRNYXBGaXhlZDMyRml4ZWQzMk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpeGVkMzJGaXhlZDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgbWFwX2ZpeGVkMzJfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE1hcEZpeGVkMzJGaXhlZDMyT3JUaHJvdygKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwRml4ZWQzMkZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwRml4ZWQzMkZpeGVkMzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpeGVkMzJGaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQzMiwgZml4ZWQzMiZndDsgbWFwX2ZpeGVkMzJfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwRml4ZWQzMkZpeGVkMzIoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpeGVkMzJGaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwRml4ZWQzMkZpeGVkMzIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBGaXhlZDMyRml4ZWQzMigpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkMzIsIGZpeGVkMzImZ3Q7IG1hcF9maXhlZDMyX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1hcEZpeGVkMzJGaXhlZDMyKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGludCB2YWx1ZSkgewoKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQzMkZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDMyLCBmaXhlZDMyJmd0OyBtYXBfZml4ZWQzMl9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBGaXhlZDMyRml4ZWQzMigKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaXhlZDMyRml4ZWQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcEZpeGVkNjRGaXhlZDY0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKSB7CiAgICAgICAgaWYgKG1hcEZpeGVkNjRGaXhlZDY0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEZpeGVkNjRGaXhlZDY0RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBGaXhlZDY0Rml4ZWQ2NF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpeGVkNjRGaXhlZDY0KCkgewogICAgICAgIGlmIChtYXBGaXhlZDY0Rml4ZWQ2NF8gPT0gbnVsbCkgewogICAgICAgICAgbWFwRml4ZWQ2NEZpeGVkNjRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBGaXhlZDY0Rml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW1hcEZpeGVkNjRGaXhlZDY0Xy5pc011dGFibGUoKSkgewogICAgICAgICAgbWFwRml4ZWQ2NEZpeGVkNjRfID0gbWFwRml4ZWQ2NEZpeGVkNjRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtYXBGaXhlZDY0Rml4ZWQ2NF87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBGaXhlZDY0Rml4ZWQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEZpeGVkNjRGaXhlZDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBGaXhlZDY0Rml4ZWQ2NE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwRml4ZWQ2NEZpeGVkNjRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IG1hcF9maXhlZDY0X2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBnZXRNYXBGaXhlZDY0Rml4ZWQ2NE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaXhlZDY0Rml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRNYXBGaXhlZDY0Rml4ZWQ2NE9yRGVmYXVsdCgKICAgICAgICAgIGxvbmcga2V5LAogICAgICAgICAgbG9uZyBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwRml4ZWQ2NEZpeGVkNjQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtmaXhlZDY0LCBmaXhlZDY0Jmd0OyBtYXBfZml4ZWQ2NF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE1hcEZpeGVkNjRGaXhlZDY0T3JUaHJvdygKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpeGVkNjRGaXhlZDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcEZpeGVkNjRGaXhlZDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaXhlZDY0Rml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ZpeGVkNjQsIGZpeGVkNjQmZ3Q7IG1hcF9maXhlZDY0X2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcEZpeGVkNjRGaXhlZDY0KAogICAgICAgICAgbG9uZyBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQ2NEZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldE11dGFibGVNYXBGaXhlZDY0Rml4ZWQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEZpeGVkNjRGaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwRml4ZWQ2NEZpeGVkNjQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEZpeGVkNjRGaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Zml4ZWQ2NCwgZml4ZWQ2NCZndDsgbWFwX2ZpeGVkNjRfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwRml4ZWQ2NEZpeGVkNjQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRml4ZWQ2NEZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXBTZml4ZWQzMlNmaXhlZDMyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpIHsKICAgICAgICBpZiAobWFwU2ZpeGVkMzJTZml4ZWQzMl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBTZml4ZWQzMlNmaXhlZDMyRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBTZml4ZWQzMlNmaXhlZDMyXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ZpeGVkMzJTZml4ZWQzMigpIHsKICAgICAgICBpZiAobWFwU2ZpeGVkMzJTZml4ZWQzMl8gPT0gbnVsbCkgewogICAgICAgICAgbWFwU2ZpeGVkMzJTZml4ZWQzMl8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE1hcFNmaXhlZDMyU2ZpeGVkMzJEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtYXBTZml4ZWQzMlNmaXhlZDMyXy5pc011dGFibGUoKSkgewogICAgICAgICAgbWFwU2ZpeGVkMzJTZml4ZWQzMl8gPSBtYXBTZml4ZWQzMlNmaXhlZDMyXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwU2ZpeGVkMzJTZml4ZWQzMl87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwU2ZpeGVkMzJTZml4ZWQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFNmaXhlZDMyU2ZpeGVkMzJNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0TWFwU2ZpeGVkMzJTZml4ZWQzMigpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwU2ZpeGVkMzJTZml4ZWQzMk1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBnZXRNYXBTZml4ZWQzMlNmaXhlZDMyTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDMyLCBzZml4ZWQzMiZndDsgbWFwX3NmaXhlZDMyX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwU2ZpeGVkMzJTZml4ZWQzMk9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IG1hcF9zZml4ZWQzMl9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE1hcFNmaXhlZDMyU2ZpeGVkMzJPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBTZml4ZWQzMlNmaXhlZDMyKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcFNmaXhlZDMyU2ZpeGVkMzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDMyU2ZpeGVkMzIoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQzMiwgc2ZpeGVkMzImZ3Q7IG1hcF9zZml4ZWQzMl9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwU2ZpeGVkMzJTZml4ZWQzMigKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcFNmaXhlZDMyU2ZpeGVkMzIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBTZml4ZWQzMlNmaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1hcFNmaXhlZDMyU2ZpeGVkMzIoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTZml4ZWQzMlNmaXhlZDMyKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkMzIsIHNmaXhlZDMyJmd0OyBtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcFNmaXhlZDMyU2ZpeGVkMzIoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ZpeGVkMzJTZml4ZWQzMigpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IG1hcFNmaXhlZDY0U2ZpeGVkNjRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCkgewogICAgICAgIGlmIChtYXBTZml4ZWQ2NFNmaXhlZDY0XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIE1hcFNmaXhlZDY0U2ZpeGVkNjREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcFNmaXhlZDY0U2ZpeGVkNjRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTZml4ZWQ2NFNmaXhlZDY0KCkgewogICAgICAgIGlmIChtYXBTZml4ZWQ2NFNmaXhlZDY0XyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBTZml4ZWQ2NFNmaXhlZDY0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwU2ZpeGVkNjRTZml4ZWQ2NERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW1hcFNmaXhlZDY0U2ZpeGVkNjRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBTZml4ZWQ2NFNmaXhlZDY0XyA9IG1hcFNmaXhlZDY0U2ZpeGVkNjRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtYXBTZml4ZWQ2NFNmaXhlZDY0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcFNmaXhlZDY0U2ZpeGVkNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwU2ZpeGVkNjRTZml4ZWQ2NCgKICAgICAgICAgIGxvbmcga2V5KSB7CgogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBTZml4ZWQ2NFNmaXhlZDY0TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcFNmaXhlZDY0U2ZpeGVkNjRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3NmaXhlZDY0LCBzZml4ZWQ2NCZndDsgbWFwX3NmaXhlZDY0X3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+IGdldE1hcFNmaXhlZDY0U2ZpeGVkNjRNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c2ZpeGVkNjQsIHNmaXhlZDY0Jmd0OyBtYXBfc2ZpeGVkNjRfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE1hcFNmaXhlZDY0U2ZpeGVkNjRPckRlZmF1bHQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkxvbmcsIGphdmEubGFuZy5Mb25nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0TWFwU2ZpeGVkNjRTZml4ZWQ2NE9yVGhyb3coCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBTZml4ZWQ2NFNmaXhlZDY0KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcFNmaXhlZDY0U2ZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcFNmaXhlZDY0U2ZpeGVkNjQoCiAgICAgICAgICBsb25nIGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTZml4ZWQ2NFNmaXhlZDY0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuTG9uZywgamF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwU2ZpeGVkNjRTZml4ZWQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1hcFNmaXhlZDY0U2ZpeGVkNjQoCiAgICAgICAgICBsb25nIGtleSwKICAgICAgICAgIGxvbmcgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFNmaXhlZDY0U2ZpeGVkNjQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzZml4ZWQ2NCwgc2ZpeGVkNjQmZ3Q7IG1hcF9zZml4ZWQ2NF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcFNmaXhlZDY0U2ZpeGVkNjQoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Mb25nLCBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU2ZpeGVkNjRTZml4ZWQ2NCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXBJbnQzMkZsb2F0XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKSB7CiAgICAgICAgaWYgKG1hcEludDMyRmxvYXRfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwSW50MzJGbG9hdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwSW50MzJGbG9hdF87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkZsb2F0KCkgewogICAgICAgIGlmIChtYXBJbnQzMkZsb2F0XyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBJbnQzMkZsb2F0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwSW50MzJGbG9hdERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW1hcEludDMyRmxvYXRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBJbnQzMkZsb2F0XyA9IG1hcEludDMyRmxvYXRfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtYXBJbnQzMkZsb2F0XzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcEludDMyRmxvYXRDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkZsb2F0KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBtYXBfaW50MzJfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwSW50MzJGbG9hdCgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJGbG9hdCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyRmxvYXRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IGdldE1hcEludDMyRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcEludDMyRmxvYXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgbWFwX2ludDMyX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBnZXRNYXBJbnQzMkZsb2F0TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBmbG9hdCZndDsgbWFwX2ludDMyX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0TWFwSW50MzJGbG9hdE9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBmbG9hdCBkZWZhdWx0VmFsdWUpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRmxvYXQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZmxvYXQmZ3Q7IG1hcF9pbnQzMl9mbG9hdCA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldE1hcEludDMyRmxvYXRPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRmxvYXQ+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJGbG9hdCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNYXBJbnQzMkZsb2F0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkZsb2F0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBtYXBfaW50MzJfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBJbnQzMkZsb2F0KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkZsb2F0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PgogICAgICAgICAgZ2V0TXV0YWJsZU1hcEludDMyRmxvYXQoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkZsb2F0KCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBtYXBfaW50MzJfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBJbnQzMkZsb2F0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIGZsb2F0IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkZsb2F0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGZsb2F0Jmd0OyBtYXBfaW50MzJfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBJbnQzMkZsb2F0KAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkZsb2F0KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXBJbnQzMkRvdWJsZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKSB7CiAgICAgICAgaWYgKG1hcEludDMyRG91YmxlXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEludDMyRG91YmxlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBJbnQzMkRvdWJsZV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJEb3VibGUoKSB7CiAgICAgICAgaWYgKG1hcEludDMyRG91YmxlXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBJbnQzMkRvdWJsZV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEludDMyRG91YmxlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwSW50MzJEb3VibGVfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBJbnQzMkRvdWJsZV8gPSBtYXBJbnQzMkRvdWJsZV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcEludDMyRG91YmxlXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcEludDMyRG91YmxlQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBtYXBfaW50MzJfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEludDMyRG91YmxlKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkRvdWJsZSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyRG91YmxlTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0TWFwSW50MzJEb3VibGUoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcEludDMyRG91YmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgZG91YmxlJmd0OyBtYXBfaW50MzJfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gZ2V0TWFwSW50MzJEb3VibGVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IG1hcF9pbnQzMl9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0TWFwSW50MzJEb3VibGVPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgZG91YmxlIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuRG91YmxlPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRG91YmxlKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgbWFwX2ludDMyX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGRvdWJsZSBnZXRNYXBJbnQzMkRvdWJsZU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJEb3VibGUoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwSW50MzJEb3VibGUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRG91YmxlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgbWFwX2ludDMyX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcEludDMyRG91YmxlKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkRvdWJsZSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwSW50MzJEb3VibGUoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkRvdWJsZSgpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBkb3VibGUmZ3Q7IG1hcF9pbnQzMl9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBJbnQzMkRvdWJsZSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBkb3VibGUgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRG91YmxlKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGRvdWJsZSZndDsgbWFwX2ludDMyX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcEludDMyRG91YmxlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkRvdWJsZT4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJEb3VibGUoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXBCb29sQm9vbF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEJvb2xCb29sKCkgewogICAgICAgIGlmIChtYXBCb29sQm9vbF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBCb29sQm9vbERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwQm9vbEJvb2xfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBCb29sQm9vbCgpIHsKICAgICAgICBpZiAobWFwQm9vbEJvb2xfID09IG51bGwpIHsKICAgICAgICAgIG1hcEJvb2xCb29sXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwQm9vbEJvb2xEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKCFtYXBCb29sQm9vbF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG1hcEJvb2xCb29sXyA9IG1hcEJvb2xCb29sXy5jb3B5KCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gbWFwQm9vbEJvb2xfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwQm9vbEJvb2xDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmdldE1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IG1hcF9ib29sX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwQm9vbEJvb2woCiAgICAgICAgICBib29sZWFuIGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEJvb2xCb29sTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IGdldE1hcEJvb2xCb29sKCkgewogICAgICAgIHJldHVybiBnZXRNYXBCb29sQm9vbE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgbWFwX2Jvb2xfYm9vbCA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBnZXRNYXBCb29sQm9vbE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBCb29sQm9vbCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgbWFwX2Jvb2xfYm9vbCA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0TWFwQm9vbEJvb2xPckRlZmF1bHQoCiAgICAgICAgICBib29sZWFuIGtleSwKICAgICAgICAgIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEJvb2xCb29sKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgbWFwX2Jvb2xfYm9vbCA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0TWFwQm9vbEJvb2xPclRocm93KAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuQm9vbGVhbiwgamF2YS5sYW5nLkJvb2xlYW4+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwQm9vbEJvb2woKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwQm9vbEJvb2woKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEJvb2xCb29sKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgbWFwX2Jvb2xfYm9vbCA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcEJvb2xCb29sKAogICAgICAgICAgYm9vbGVhbiBrZXkpIHsKCiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwQm9vbEJvb2woKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5Cb29sZWFuLCBqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldE11dGFibGVNYXBCb29sQm9vbCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEJvb2xCb29sKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7Ym9vbCwgYm9vbCZndDsgbWFwX2Jvb2xfYm9vbCA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1hcEJvb2xCb29sKAogICAgICAgICAgYm9vbGVhbiBrZXksCiAgICAgICAgICBib29sZWFuIHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBCb29sQm9vbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2Jvb2wsIGJvb2wmZ3Q7IG1hcF9ib29sX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBCb29sQm9vbCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkJvb2xlYW4sIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBCb29sQm9vbCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXBTdHJpbmdTdHJpbmdfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TWFwU3RyaW5nU3RyaW5nKCkgewogICAgICAgIGlmIChtYXBTdHJpbmdTdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwU3RyaW5nU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBTdHJpbmdTdHJpbmdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nU3RyaW5nKCkgewogICAgICAgIGlmIChtYXBTdHJpbmdTdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIG1hcFN0cmluZ1N0cmluZ18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE1hcFN0cmluZ1N0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW1hcFN0cmluZ1N0cmluZ18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG1hcFN0cmluZ1N0cmluZ18gPSBtYXBTdHJpbmdTdHJpbmdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtYXBTdHJpbmdTdHJpbmdfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwU3RyaW5nU3RyaW5nQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU3RyaW5nU3RyaW5nKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmdfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcFN0cmluZ1N0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU3RyaW5nU3RyaW5nKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwU3RyaW5nU3RyaW5nTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNYXBTdHJpbmdTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcFN0cmluZ1N0cmluZ01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmdfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNYXBTdHJpbmdTdHJpbmdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwU3RyaW5nU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3N0cmluZ19zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldE1hcFN0cmluZ1N0cmluZ09yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwU3RyaW5nU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmdfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRNYXBTdHJpbmdTdHJpbmdPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwU3RyaW5nU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcFN0cmluZ1N0cmluZygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmdfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwU3RyaW5nU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBTdHJpbmdTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwU3RyaW5nU3RyaW5nKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9zdHJpbmdfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwU3RyaW5nU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFN0cmluZ1N0cmluZygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfc3RyaW5nX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcFN0cmluZ1N0cmluZygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwU3RyaW5nU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IG1hcEludDMyQnl0ZXNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJCeXRlcygpIHsKICAgICAgICBpZiAobWFwSW50MzJCeXRlc18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBJbnQzMkJ5dGVzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBJbnQzMkJ5dGVzXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyQnl0ZXMoKSB7CiAgICAgICAgaWYgKG1hcEludDMyQnl0ZXNfID09IG51bGwpIHsKICAgICAgICAgIG1hcEludDMyQnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBJbnQzMkJ5dGVzRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwSW50MzJCeXRlc18uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIG1hcEludDMyQnl0ZXNfID0gbWFwSW50MzJCeXRlc18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcEludDMyQnl0ZXNfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJCeXRlc0NvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyQnl0ZXMoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9pbnQzMl9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBJbnQzMkJ5dGVzKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJCeXRlc01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gZ2V0TWFwSW50MzJCeXRlcygpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwSW50MzJCeXRlc01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfaW50MzJfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldE1hcEludDMyQnl0ZXNNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJCeXRlcygpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfaW50MzJfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0TWFwSW50MzJCeXRlc09yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfaW50MzJfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0TWFwSW50MzJCeXRlc09yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkJ5dGVzKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcEludDMyQnl0ZXMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyQnl0ZXMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9pbnQzMl9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcEludDMyQnl0ZXMoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyQnl0ZXMoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwSW50MzJCeXRlcygpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyQnl0ZXMoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgYnl0ZXMmZ3Q7IG1hcF9pbnQzMl9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1hcEludDMyQnl0ZXMoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CgogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkJ5dGVzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGJ5dGVzJmd0OyBtYXBfaW50MzJfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBJbnQzMkJ5dGVzKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkJ5dGVzKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwSW50MzJFbnVtXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCkgewogICAgICAgIGlmIChtYXBJbnQzMkVudW1fID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwSW50MzJFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBJbnQzMkVudW1fOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkVudW0oKSB7CiAgICAgICAgaWYgKG1hcEludDMyRW51bV8gPT0gbnVsbCkgewogICAgICAgICAgbWFwSW50MzJFbnVtXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwSW50MzJFbnVtRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwSW50MzJFbnVtXy5pc011dGFibGUoKSkgewogICAgICAgICAgbWFwSW50MzJFbnVtXyA9IG1hcEludDMyRW51bV8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcEludDMyRW51bV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRNYXBJbnQzMkVudW1Db3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEludDMyRW51bSgKICAgICAgICAgIGludCBrZXkpIHsKCiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwSW50MzJFbnVtKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJFbnVtTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWFwRW51bT4KICAgICAgZ2V0TWFwSW50MzJFbnVtKCkgewogICAgICAgIHJldHVybiBnZXRNYXBJbnQzMkVudW1NYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtPgogICAgICBnZXRNYXBJbnQzMkVudW1NYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZE1hcEludDMyRW51bU1hcCgKICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5nZXRNYXAoKSk7fQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtIGdldE1hcEludDMyRW51bU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtIGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkKICAgICAgICAgICAgICAgPyBtYXBJbnQzMkVudW1WYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKQogICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtIGdldE1hcEludDMyRW51bU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBJbnQzMkVudW1WYWx1ZUNvbnZlcnRlci5kb0ZvcndhcmQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwSW50MzJFbnVtVmFsdWVNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgZ2V0TWFwSW50MzJFbnVtVmFsdWUoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcEludDMyRW51bVZhbHVlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICAgIGdldE1hcEludDMyRW51bVZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5NYXBFbnVtJmd0OyBtYXBfaW50MzJfZW51bSA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRNYXBJbnQzMkVudW1WYWx1ZU9yRGVmYXVsdCgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEludDMyRW51bSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJFbnVtVmFsdWVPclRocm93KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkVudW0oKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwSW50MzJFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwSW50MzJFbnVtKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcEludDMyRW51bSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QWRhcHRlZE1hcEludDMyRW51bU1hcCgKICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRW51bSgpLmdldE11dGFibGVNYXAoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwSW50MzJFbnVtKAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1hcEVudW0gdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRW51bSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgbWFwSW50MzJFbnVtVmFsdWVDb252ZXJ0ZXIuZG9CYWNrd2FyZCh2YWx1ZSkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuTWFwRW51bSZndDsgbWFwX2ludDMyX2VudW0gPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBJbnQzMkVudW0oCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NYXBFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldEFkYXB0ZWRNYXBJbnQzMkVudW1NYXAoCiAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRW51bSgpLmdldE11dGFibGVNYXAoKSkKICAgICAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICBnZXRNdXRhYmxlTWFwSW50MzJFbnVtVmFsdWUoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkVudW0oKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwSW50MzJFbnVtVmFsdWUoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IHZhbHVlKSB7CgoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkVudW0oKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0Lk1hcEVudW0mZ3Q7IG1hcF9pbnQzMl9lbnVtID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwSW50MzJFbnVtVmFsdWUoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJFbnVtKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcEludDMyRm9yZWlnbk1lc3NhZ2VDb252ZXJ0ZXIgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlci5Db252ZXJ0ZXI8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgYnVpbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciB2YWwpIHsKICAgICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlKSB7IHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIpIHZhbCkuYnVpbGQoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIE1hcEludDMyRm9yZWlnbk1lc3NhZ2VEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTWFwSW50MzJGb3JlaWduTWVzc2FnZUNvbnZlcnRlciBtYXBJbnQzMkZvcmVpZ25NZXNzYWdlQ29udmVydGVyID0gbmV3IE1hcEludDMyRm9yZWlnbk1lc3NhZ2VDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyPiBtYXBJbnQzMkZvcmVpZ25NZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkgewogICAgICAgIGlmIChtYXBJbnQzMkZvcmVpZ25NZXNzYWdlXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPD4obWFwSW50MzJGb3JlaWduTWVzc2FnZUNvbnZlcnRlcik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXBJbnQzMkZvcmVpZ25NZXNzYWdlXzsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkgewogICAgICAgIGlmIChtYXBJbnQzMkZvcmVpZ25NZXNzYWdlXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBJbnQzMkZvcmVpZ25NZXNzYWdlXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KG1hcEludDMyRm9yZWlnbk1lc3NhZ2VDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcEludDMyRm9yZWlnbk1lc3NhZ2VfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuZW5zdXJlQnVpbGRlck1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEludDMyRm9yZWlnbk1lc3NhZ2VNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkgewogICAgICAgIHJldHVybiBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuZ2V0SW1tdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlJmd0OyBtYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlID0gMTc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRNYXBJbnQzMkZvcmVpZ25NZXNzYWdlT3JEZWZhdWx0KAogICAgICAgICAgaW50IGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZGVmYXVsdFZhbHVlKSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwSW50MzJGb3JlaWduTWVzc2FnZUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0TWFwSW50MzJGb3JlaWduTWVzc2FnZU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcEludDMyRm9yZWlnbk1lc3NhZ2VDb252ZXJ0ZXIuYnVpbGQobWFwLmdldChrZXkpKTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcEludDMyRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPgogICAgICAgICAgZ2V0TXV0YWJsZU1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKCkuZW5zdXJlTWVzc2FnZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSZndDsgbWFwX2ludDMyX2ZvcmVpZ25fbWVzc2FnZSA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dE1hcEludDMyRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewoKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwSW50MzJGb3JlaWduTWVzc2FnZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UmZ3Q7IG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBJbnQzMkZvcmVpZ25NZXNzYWdlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBlIDogdmFsdWVzLmVudHJ5U2V0KCkpIHsKICAgICAgICAgIGlmIChlLmdldEtleSgpID09IG51bGwgfHwgZS5nZXRWYWx1ZSgpID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UmZ3Q7IG1hcF9pbnQzMl9mb3JlaWduX21lc3NhZ2UgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIHB1dE1hcEludDMyRm9yZWlnbk1lc3NhZ2VCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBpbnQga2V5KSB7CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZU1hcEludDMyRm9yZWlnbk1lc3NhZ2UoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSkgewogICAgICAgICAgZW50cnkgPSAoKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFyZW5hTWFwKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0QXJlbmFNYXApCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0QXJlbmFNYXAgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdEFyZW5hTWFwKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0QXJlbmFNYXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0QXJlbmFNYXA+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEFyZW5hTWFwPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdEFyZW5hTWFwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEFyZW5hTWFwPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RBcmVuYU1hcD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdEFyZW5hTWFwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUmZ3Q7IHR5cGUgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFR5cGVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSZndDsgdHlwZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zVHlwZSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldFR5cGVNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGU+CiAgICBnZXRUeXBlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlJmd0OyB0eXBlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZT4KICAgIGdldFR5cGVNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUmZ3Q7IHR5cGUgPSAxOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBnZXRUeXBlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUmZ3Q7IHR5cGUgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBnZXRUeXBlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogUHJldmlvdXNseSwgbWVzc2FnZSBjb250YWluaW5nIGVudW0gY2FsbGVkIFR5cGUgY2Fubm90IGJlIHVzZWQgYXMgdmFsdWUgb2YKICAgKiBtYXAgZmllbGQuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlKQogICAgICBNZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBNZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIE1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBNZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRUeXBlKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlLlR5cGV9CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIFR5cGUKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5UWVBFX0ZPTyA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgVFlQRV9GT08oMCksCiAgICAgIFVOUkVDT0dOSVpFRCgtMSksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5UWVBFX0ZPTyA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVFlQRV9GT09fVkFMVUUgPSAwOwoKCiAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgbnVtYmVyIG9mIGFuIHVua25vd24gZW51bSB2YWx1ZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBUeXBlIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBUeXBlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBUWVBFX0ZPTzsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFR5cGU+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBUeXBlPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8VHlwZT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIFR5cGUgZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIFR5cGUuZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIGlmICh0aGlzID09IFVOUkVDT0dOSVpFRCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsU3RhdGVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkNhbid0IGdldCB0aGUgZGVzY3JpcHRvciBvZiBhbiB1bnJlY29nbml6ZWQgZW51bSB2YWx1ZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVHlwZVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBUeXBlIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKGRlc2MuZ2V0SW5kZXgoKSA9PSAtMSkgewogICAgICAgICAgcmV0dXJuIFVOUkVDT0dOSVpFRDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgVHlwZShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUuVHlwZSkKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUWVBFX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBUeXBlRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGU+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZV9UeXBlRW50cnlfZGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5NRVNTQUdFLAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGU+IHR5cGVfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGU+CiAgICBpbnRlcm5hbEdldFR5cGUoKSB7CiAgICAgIGlmICh0eXBlXyA9PSBudWxsKSB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgVHlwZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiB0eXBlXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0VHlwZUNvdW50KCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRUeXBlKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSZndDsgdHlwZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1R5cGUoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFR5cGUoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRUeXBlTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZT4gZ2V0VHlwZSgpIHsKICAgICAgcmV0dXJuIGdldFR5cGVNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUmZ3Q7IHR5cGUgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZT4gZ2V0VHlwZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0VHlwZSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSZndDsgdHlwZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBnZXRUeXBlT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgZGVmYXVsdFZhbHVlKSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGU+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldFR5cGUoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSZndDsgdHlwZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBnZXRUeXBlT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRUeXBlKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0VHlwZSgpLAogICAgICAgICAgVHlwZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRUeXBlKCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZT4KICAgICAgICB0eXBlX18gPSBUeXBlRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCB0eXBlX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSkgb2JqOwoKICAgICAgaWYgKCFpbnRlcm5hbEdldFR5cGUoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFR5cGUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoIWludGVybmFsR2V0VHlwZSgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFRZUEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0VHlwZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUHJldmlvdXNseSwgbWVzc2FnZSBjb250YWluaW5nIGVudW0gY2FsbGVkIFR5cGUgY2Fubm90IGJlIHVzZWQgYXMgdmFsdWUgb2YKICAgICAqIG1hcCBmaWVsZC4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRUeXBlKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlVHlwZSgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVR5cGUoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnR5cGVfID0gaW50ZXJuYWxHZXRUeXBlKCkuYnVpbGQoVHlwZURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVUeXBlKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFR5cGUoKSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZT4KICAgICAgICAgICAgICAgIHR5cGVfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIFR5cGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlVHlwZSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgdHlwZV9fLmdldEtleSgpLCB0eXBlX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgVHlwZUNvbnZlcnRlciBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyLkNvbnZlcnRlcjxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlPiB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlIGJ1aWxkKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGVPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSkgeyByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUpIHZhbDsgfQogICAgICAgICAgcmV0dXJuICgocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZT4gZGVmYXVsdEVudHJ5KCkgewogICAgICAgICAgcmV0dXJuIFR5cGVEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5OwogICAgICAgIH0KICAgICAgfTsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVHlwZUNvbnZlcnRlciB0eXBlQ29udmVydGVyID0gbmV3IFR5cGVDb252ZXJ0ZXIoKTsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlLkJ1aWxkZXI+IHR5cGVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGVPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUuQnVpbGRlcj4KICAgICAgICAgIGludGVybmFsR2V0VHlwZSgpIHsKICAgICAgICBpZiAodHlwZV8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KHR5cGVDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHlwZV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVUeXBlKCkgewogICAgICAgIGlmICh0eXBlXyA9PSBudWxsKSB7CiAgICAgICAgICB0eXBlXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjw+KHR5cGVDb252ZXJ0ZXIpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHR5cGVfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0VHlwZUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFR5cGUoKS5lbnN1cmVCdWlsZGVyTWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSZndDsgdHlwZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc1R5cGUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFR5cGUoKS5lbnN1cmVCdWlsZGVyTWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0VHlwZU1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZT4gZ2V0VHlwZSgpIHsKICAgICAgICByZXR1cm4gZ2V0VHlwZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSZndDsgdHlwZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlPiBnZXRUeXBlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFR5cGUoKS5nZXRJbW11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUmZ3Q7IHR5cGUgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgZ2V0VHlwZU9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGVPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZVR5cGUoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gdHlwZUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSZndDsgdHlwZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBnZXRUeXBlT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVUeXBlKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0eXBlQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJUeXBlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVUeXBlKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUmZ3Q7IHR5cGUgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVR5cGUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVR5cGUoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGU+CiAgICAgICAgICBnZXRNdXRhYmxlVHlwZSgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVR5cGUoKS5lbnN1cmVNZXNzYWdlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlJmd0OyB0eXBlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRUeXBlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVR5cGUoKS5lbnN1cmVCdWlsZGVyTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlJmd0OyB0eXBlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxUeXBlKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZT4gZSA6IHZhbHVlcy5lbnRyeVNldCgpKSB7CiAgICAgICAgICBpZiAoZS5nZXRLZXkoKSA9PSBudWxsIHx8IGUuZ2V0VmFsdWUoKSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVUeXBlKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXRBbGwodmFsdWVzKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlJmd0OyB0eXBlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZS5CdWlsZGVyIHB1dFR5cGVCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZU9yQnVpbGRlcj4gYnVpbGRlck1hcCA9IGludGVybmFsR2V0TXV0YWJsZVR5cGUoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZU9yQnVpbGRlciBlbnRyeSA9IGJ1aWxkZXJNYXAuZ2V0KGtleSk7CiAgICAgICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgICAgIGVudHJ5ID0gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSkgewogICAgICAgICAgZW50cnkgPSAoKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUpIGVudHJ5KS50b0J1aWxkZXIoKTsKICAgICAgICAgIGJ1aWxkZXJNYXAucHV0KGtleSwgZW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBNZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5T3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBlbnRyeSA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RW50cnlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBlbnRyeSA9IDE7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zRW50cnkoCiAgICAgICAgaW50IGtleSk7CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEVudHJ5TWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+CiAgICBnZXRFbnRyeSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBlbnRyeSA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGdldEVudHJ5TWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGVudHJ5ID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRFbnRyeU9yRGVmYXVsdCgKICAgICAgICBpbnQga2V5LAogICAgICAgIGludCBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBlbnRyeSA9IDE7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0RW50cnlPclRocm93KAogICAgICAgIGludCBrZXkpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFByZXZpb3VzbHksIG1lc3NhZ2UgY2Fubm90IGNvbnRhaW4gbWFwIGZpZWxkIGNhbGxlZCAiZW50cnkiLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSkKICAgICAgTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBNZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBNZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5KCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnlfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0RW50cnkoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlRSWV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgRW50cnlEZWZhdWx0RW50cnlIb2xkZXIgewogICAgICBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeV9FbnRyeUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLklOVDMyLAogICAgICAgICAgICAgICAgICAwKTsKICAgIH0KICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZW50cnlfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgIGludGVybmFsR2V0RW50cnkoKSB7CiAgICAgIGlmIChlbnRyeV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEVudHJ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIGVudHJ5XzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0RW50cnlDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0RW50cnkoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGVudHJ5ID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zRW50cnkoCiAgICAgICAgaW50IGtleSkgewoKICAgICAgcmV0dXJuIGludGVybmFsR2V0RW50cnkoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRFbnRyeU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0RW50cnkoKSB7CiAgICAgIHJldHVybiBnZXRFbnRyeU1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBlbnRyeSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEVudHJ5TWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnRyeSgpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBlbnRyeSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEVudHJ5T3JEZWZhdWx0KAogICAgICAgIGludCBrZXksCiAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEVudHJ5KCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZW50cnkgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRFbnRyeU9yVGhyb3coCiAgICAgICAgaW50IGtleSkgewoKICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEVudHJ5KCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVJbnRlZ2VyTWFwVG8oCiAgICAgICAgICBvdXRwdXQsCiAgICAgICAgICBpbnRlcm5hbEdldEVudHJ5KCksCiAgICAgICAgICBFbnRyeURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldEVudHJ5KCkuZ2V0TWFwKCkuZW50cnlTZXQoKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGVudHJ5X18gPSBFbnRyeURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZW50cnlfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5KSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0RW50cnkoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEVudHJ5KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKCFpbnRlcm5hbEdldEVudHJ5KCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRU5UUllfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0RW50cnkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5IHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFByZXZpb3VzbHksIG1lc3NhZ2UgY2Fubm90IGNvbnRhaW4gbWFwIGZpZWxkIGNhbGxlZCAiZW50cnkiLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudHJ5KCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRW50cnkoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5Lm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnRyeSgpLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5IHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5IHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZW50cnlfID0gaW50ZXJuYWxHZXRFbnRyeSgpOwogICAgICAgICAgcmVzdWx0LmVudHJ5Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5IG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0Lk1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudHJ5KCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldEVudHJ5KCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgICAgICAgIGVudHJ5X18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBFbnRyeURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnRyeSgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgZW50cnlfXy5nZXRLZXkoKSwgZW50cnlfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGVudHJ5XzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0RW50cnkoKSB7CiAgICAgICAgaWYgKGVudHJ5XyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICAgIEVudHJ5RGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBlbnRyeV87CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudHJ5KCkgewogICAgICAgIGlmIChlbnRyeV8gPT0gbnVsbCkgewogICAgICAgICAgZW50cnlfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5uZXdNYXBGaWVsZCgKICAgICAgICAgICAgICBFbnRyeURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIWVudHJ5Xy5pc011dGFibGUoKSkgewogICAgICAgICAgZW50cnlfID0gZW50cnlfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBlbnRyeV87CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXRFbnRyeUNvdW50KCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudHJ5KCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBlbnRyeSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc0VudHJ5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRFbnRyeSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldEVudHJ5TWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEVudHJ5KCkgewogICAgICAgIHJldHVybiBnZXRFbnRyeU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBlbnRyeSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuSW50ZWdlciwgamF2YS5sYW5nLkludGVnZXI+IGdldEVudHJ5TWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbEdldEVudHJ5KCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGVudHJ5ID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RW50cnlPckRlZmF1bHQoCiAgICAgICAgICBpbnQga2V5LAogICAgICAgICAgaW50IGRlZmF1bHRWYWx1ZSkgewoKICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRFbnRyeSgpLmdldE1hcCgpOwogICAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZW50cnkgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRFbnRyeU9yVGhyb3coCiAgICAgICAgICBpbnQga2V5KSB7CgogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldEVudHJ5KCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckVudHJ5KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnRyeSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O2ludDMyLCBpbnQzMiZndDsgZW50cnkgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUVudHJ5KAogICAgICAgICAgaW50IGtleSkgewoKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVFbnRyeSgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLkludGVnZXIsIGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0TXV0YWJsZUVudHJ5KCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlRW50cnkoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtpbnQzMiwgaW50MzImZ3Q7IGVudHJ5ID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRFbnRyeSgKICAgICAgICAgIGludCBrZXksCiAgICAgICAgICBpbnQgdmFsdWUpIHsKCgogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUVudHJ5KCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7aW50MzIsIGludDMyJmd0OyBlbnRyeSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsRW50cnkoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5JbnRlZ2VyLCBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlRW50cnkoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5KQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5KQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5KCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5IGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5PigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnk+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlJmd0OyBhID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRBQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlJmd0OyBhID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNBKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0QU1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2U+CiAgICBnZXRBKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSZndDsgYSA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlPgogICAgZ2V0QU1hcCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UmZ3Q7IGEgPSAxOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UgZ2V0QU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UmZ3Q7IGEgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UgZ2V0QU9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlKQogICAgICBUZXN0UmVjdXJzaXZlTWFwTWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgQURlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2U+IGRlZmF1bHRFbnRyeSA9CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeQogICAgICAgICAgICAgIC48amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2U+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2VfQUVudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuTUVTU0FHRSwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2U+IGFfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlPgogICAgaW50ZXJuYWxHZXRBKCkgewogICAgICBpZiAoYV8gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIEFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gYV87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldEFDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0QSgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlJmd0OyBhID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQSgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0QSgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldEFNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZT4gZ2V0QSgpIHsKICAgICAgcmV0dXJuIGdldEFNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlJmd0OyBhID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlPiBnZXRBTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxHZXRBKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSZndDsgYSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UgZ2V0QU9yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2U+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldEEoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UmZ3Q7IGEgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIGdldEFPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRBKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0QSgpLAogICAgICAgICAgQURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxKTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZT4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0QSgpLmdldE1hcCgpLmVudHJ5U2V0KCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlPgogICAgICAgIGFfXyA9IEFEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGFfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlKSBvYmo7CgogICAgICBpZiAoIWludGVybmFsR2V0QSgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0QSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmICghaW50ZXJuYWxHZXRBKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRBKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InJhd3R5cGVzIn0pCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldEEoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVBKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZUEoKS5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmFfID0gaW50ZXJuYWxHZXRBKCkuYnVpbGQoQURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQSgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRBKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlPgogICAgICAgICAgICAgICAgYV9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgQURlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVBKCkuZW5zdXJlQnVpbGRlck1hcCgpLnB1dCgKICAgICAgICAgICAgICAgICAgICBhX18uZ2V0S2V5KCksIGFfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBBQ29udmVydGVyIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXIuQ29udmVydGVyPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlT3JCdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZT4gewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UgYnVpbGQocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2VPckJ1aWxkZXIgdmFsKSB7CiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UpIHsgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSkgdmFsOyB9CiAgICAgICAgICByZXR1cm4gKChwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZS5CdWlsZGVyKSB2YWwpLmJ1aWxkKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2U+IGRlZmF1bHRFbnRyeSgpIHsKICAgICAgICAgIHJldHVybiBBRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFDb252ZXJ0ZXIgYUNvbnZlcnRlciA9IG5ldyBBQ29udmVydGVyKCk7CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRCdWlsZGVyPAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2VPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZS5CdWlsZGVyPiBhXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkQnVpbGRlcjxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZU9yQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlLkJ1aWxkZXI+CiAgICAgICAgICBpbnRlcm5hbEdldEEoKSB7CiAgICAgICAgaWYgKGFfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihhQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2VPckJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZS5CdWlsZGVyPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQSgpIHsKICAgICAgICBpZiAoYV8gPT0gbnVsbCkgewogICAgICAgICAgYV8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZEJ1aWxkZXI8PihhQ29udmVydGVyKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBhXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldEFDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRBKCkuZW5zdXJlQnVpbGRlck1hcCgpLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlJmd0OyBhID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zQSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QSgpLmVuc3VyZUJ1aWxkZXJNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRBTWFwKCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZT4gZ2V0QSgpIHsKICAgICAgICByZXR1cm4gZ2V0QU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UmZ3Q7IGEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2U+IGdldEFNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0QSgpLmdldEltbXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UmZ3Q7IGEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIGdldEFPckRlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIC8qIG51bGxhYmxlICovCnByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2VPckJ1aWxkZXI+IG1hcCA9IGludGVybmFsR2V0TXV0YWJsZUEoKS5lbnN1cmVCdWlsZGVyTWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gYUNvbnZlcnRlci5idWlsZChtYXAuZ2V0KGtleSkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UmZ3Q7IGEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIGdldEFPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlT3JCdWlsZGVyPiBtYXAgPSBpbnRlcm5hbEdldE11dGFibGVBKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBhQ29udmVydGVyLmJ1aWxkKG1hcC5nZXQoa2V5KSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVBKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlJmd0OyBhID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVBKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVBKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5yZW1vdmUoa2V5KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIGFsdGVybmF0ZSBtdXRhdGlvbiBhY2Nlc3NvcnMgaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZT4KICAgICAgICAgIGdldE11dGFibGVBKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlQSgpLmVuc3VyZU1lc3NhZ2VNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlJmd0OyBhID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIHZhbHVlIik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVBKCkuZW5zdXJlQnVpbGRlck1hcCgpCiAgICAgICAgICAgIC5wdXQoa2V5LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UmZ3Q7IGEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbEEoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2U+IGUgOiB2YWx1ZXMuZW50cnlTZXQoKSkgewogICAgICAgICAgaWYgKGUuZ2V0S2V5KCkgPT0gbnVsbCB8fCBlLmdldFZhbHVlKCkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlQSgpLmVuc3VyZUJ1aWxkZXJNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UmZ3Q7IGEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZS5CdWlsZGVyIHB1dEFCdWlsZGVySWZBYnNlbnQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2VPckJ1aWxkZXI+IGJ1aWxkZXJNYXAgPSBpbnRlcm5hbEdldE11dGFibGVBKCkuZW5zdXJlQnVpbGRlck1hcCgpOwogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlT3JCdWlsZGVyIGVudHJ5ID0gYnVpbGRlck1hcC5nZXQoa2V5KTsKICAgICAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgZW50cnkgPSBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZS5uZXdCdWlsZGVyKCk7CiAgICAgICAgICBidWlsZGVyTWFwLnB1dChrZXksIGVudHJ5KTsKICAgICAgICB9CiAgICAgICAgaWYgKGVudHJ5IGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UpIHsKICAgICAgICAgIGVudHJ5ID0gKChwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSkgZW50cnkpLnRvQnVpbGRlcigpOwogICAgICAgICAgYnVpbGRlck1hcC5wdXQoa2V5LCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UuQnVpbGRlcikgZW50cnk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuTWFwVW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lk1hcFVuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZWN1cnNpdmVNYXBNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5NYXBVbml0dGVzdC5UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJJbnQzMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJJbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDY0SW50NjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDY0SW50NjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBVaW50MzJVaW50MzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFVpbnQzMlVpbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFVpbnQ2NFVpbnQ2NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwVWludDY0VWludDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwU2ludDMyU2ludDMyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBTaW50MzJTaW50MzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBTaW50NjRTaW50NjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFNpbnQ2NFNpbnQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEZpeGVkMzJGaXhlZDMyRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBGaXhlZDMyRml4ZWQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEZpeGVkNjRGaXhlZDY0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBGaXhlZDY0Rml4ZWQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFNmaXhlZDMyU2ZpeGVkMzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFNmaXhlZDMyU2ZpeGVkMzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBTZml4ZWQ2NFNmaXhlZDY0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBTZml4ZWQ2NFNmaXhlZDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJGbG9hdEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJGbG9hdEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMyRG91YmxlRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBJbnQzMkRvdWJsZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEJvb2xCb29sRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBCb29sQm9vbEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFN0cmluZ1N0cmluZ0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwU3RyaW5nU3RyaW5nRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJCeXRlc0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJCeXRlc0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMyRW51bUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJFbnVtRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJGb3JlaWduTWVzc2FnZUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJGb3JlaWduTWVzc2FnZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBTdHJpbmdGb3JlaWduTWVzc2FnZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMyQWxsVHlwZXNFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMyQWxsVHlwZXNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcFN1Ym1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcFN1Ym1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlTWFwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlTWFwX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZU1hcF9NYXBJbnQzMk1lc3NhZ2VFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZU1hcF9NYXBJbnQzMk1lc3NhZ2VFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFNhbWVUeXBlTWFwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RTYW1lVHlwZU1hcF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFNhbWVUeXBlTWFwX01hcDFFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0U2FtZVR5cGVNYXBfTWFwMUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0U2FtZVR5cGVNYXBfTWFwMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RTYW1lVHlwZU1hcF9NYXAyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE1lc3NhZ2VNYXBfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkTWVzc2FnZU1hcF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkTWVzc2FnZU1hcF9NYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE1lc3NhZ2VNYXBfTWFwRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMySW50MzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwSW50MzJJbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwSW50NjRJbnQ2NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQ2NEludDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBVaW50MzJVaW50MzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwVWludDMyVWludDMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBVaW50NjRVaW50NjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwVWludDY0VWludDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBTaW50MzJTaW50MzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwU2ludDMyU2ludDMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBTaW50NjRTaW50NjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwU2ludDY0U2ludDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBGaXhlZDMyRml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBGaXhlZDMyRml4ZWQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwRml4ZWQ2NEZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwRml4ZWQ2NEZpeGVkNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFNmaXhlZDMyU2ZpeGVkMzJFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwU2ZpeGVkMzJTZml4ZWQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwU2ZpeGVkNjRTZml4ZWQ2NEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBTZml4ZWQ2NFNmaXhlZDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkZsb2F0RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMyRmxvYXRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMyRG91YmxlRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMyRG91YmxlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBCb29sQm9vbEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBCb29sQm9vbEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwU3RyaW5nU3RyaW5nRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFN0cmluZ1N0cmluZ0VudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwSW50MzJCeXRlc0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkJ5dGVzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkVudW1FbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwSW50MzJFbnVtRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkZvcmVpZ25NZXNzYWdlRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMyRm9yZWlnbk1lc3NhZ2VFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlX1R5cGVFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlX1R5cGVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5X0VudHJ5RW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeV9FbnRyeUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2VfQUVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZWN1cnNpdmVNYXBNZXNzYWdlX0FFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuXCJnb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0LnByb3RvXDAyMlwwMjFwciIgKwogICAgICAib3RvYnVmX3VuaXR0ZXN0XDAzMlwwMzZnb29nbGUvcHJvdG9idWYvdW5pdHRlcyIgKwogICAgICAidC5wcm90b1wiXDM3N1wwMjRcblwwMDdUZXN0TWFwXDAyMkZcblwwMTdtYXBfaW50MzJfaW50MzJcMDMwXDAwMSIgKwogICAgICAiIFwwMDMoXDAxMzItLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwSW50MyIgKwogICAgICAiMkludDMyRW50cnlcMDIyRlxuXDAxN21hcF9pbnQ2NF9pbnQ2NFwwMzBcMDAyIFwwMDMoXDAxMzItLnAiICsKICAgICAgInJvdG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBJbnQ2NEludDY0RW4iICsKICAgICAgInRyeVwwMjJKXG5cMDIxbWFwX3VpbnQzMl91aW50MzJcMDMwXDAwMyBcMDAzKFwwMTMyLy5wcm90b2J1IiArCiAgICAgICJmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwVWludDMyVWludDMyRW50cnlcMDIyIiArCiAgICAgICJKXG5cMDIxbWFwX3VpbnQ2NF91aW50NjRcMDMwXDAwNCBcMDAzKFwwMTMyLy5wcm90b2J1Zl91biIgKwogICAgICAiaXR0ZXN0LlRlc3RNYXAuTWFwVWludDY0VWludDY0RW50cnlcMDIySlxuXDAyMW0iICsKICAgICAgImFwX3NpbnQzMl9zaW50MzJcMDMwXDAwNSBcMDAzKFwwMTMyLy5wcm90b2J1Zl91bml0dGUiICsKICAgICAgInN0LlRlc3RNYXAuTWFwU2ludDMyU2ludDMyRW50cnlcMDIySlxuXDAyMW1hcF9zIiArCiAgICAgICJpbnQ2NF9zaW50NjRcMDMwXDAwNiBcMDAzKFwwMTMyLy5wcm90b2J1Zl91bml0dGVzdC5UIiArCiAgICAgICJlc3RNYXAuTWFwU2ludDY0U2ludDY0RW50cnlcMDIyTlxuXDAyM21hcF9maXhlZCIgKwogICAgICAiMzJfZml4ZWQzMlwwMzBcMDA3IFwwMDMoXDAxMzIxLnByb3RvYnVmX3VuaXR0ZXN0LlRlcyIgKwogICAgICAidE1hcC5NYXBGaXhlZDMyRml4ZWQzMkVudHJ5XDAyMk5cblwwMjNtYXBfZml4ZWQiICsKICAgICAgIjY0X2ZpeGVkNjRcMDMwXDAxMCBcMDAzKFwwMTMyMS5wcm90b2J1Zl91bml0dGVzdC5UZXMiICsKICAgICAgInRNYXAuTWFwRml4ZWQ2NEZpeGVkNjRFbnRyeVwwMjJSXG5cMDI1bWFwX3NmaXhlIiArCiAgICAgICJkMzJfc2ZpeGVkMzJcMDMwXHQgXDAwMyhcMDEzMjMucHJvdG9idWZfdW5pdHRlc3QuVCIgKwogICAgICAiZXN0TWFwLk1hcFNmaXhlZDMyU2ZpeGVkMzJFbnRyeVwwMjJSXG5cMDI1bWFwX3MiICsKICAgICAgImZpeGVkNjRfc2ZpeGVkNjRcMDMwXG4gXDAwMyhcMDEzMjMucHJvdG9idWZfdW5pdHRlIiArCiAgICAgICJzdC5UZXN0TWFwLk1hcFNmaXhlZDY0U2ZpeGVkNjRFbnRyeVwwMjJGXG5cMDE3bSIgKwogICAgICAiYXBfaW50MzJfZmxvYXRcMDMwXDAxMyBcMDAzKFwwMTMyLS5wcm90b2J1Zl91bml0dGVzdCIgKwogICAgICAiLlRlc3RNYXAuTWFwSW50MzJGbG9hdEVudHJ5XDAyMkhcblwwMjBtYXBfaW50MzIiICsKICAgICAgIl9kb3VibGVcMDMwXDAxNCBcMDAzKFwwMTMyLi5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWEiICsKICAgICAgInAuTWFwSW50MzJEb3VibGVFbnRyeVwwMjJCXG5ccm1hcF9ib29sX2Jvb2xcMDMwXHIiICsKICAgICAgIiBcMDAzKFwwMTMyKy5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWFwLk1hcEJvb2wiICsKICAgICAgIkJvb2xFbnRyeVwwMjJKXG5cMDIxbWFwX3N0cmluZ19zdHJpbmdcMDMwXDAxNiBcMDAzKFwwMTMyLy5wIiArCiAgICAgICJyb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwU3RyaW5nU3RyaW5nIiArCiAgICAgICJFbnRyeVwwMjJGXG5cMDE3bWFwX2ludDMyX2J5dGVzXDAzMFwwMTcgXDAwMyhcMDEzMi0ucHJvdG9idSIgKwogICAgICAiZl91bml0dGVzdC5UZXN0TWFwLk1hcEludDMyQnl0ZXNFbnRyeVwwMjJEXG4iICsKICAgICAgIlwwMTZtYXBfaW50MzJfZW51bVwwMzBcMDIwIFwwMDMoXDAxMzIsLnByb3RvYnVmX3VuaXR0ZXMiICsKICAgICAgInQuVGVzdE1hcC5NYXBJbnQzMkVudW1FbnRyeVwwMjJZXG5cMDMxbWFwX2ludDMyIiArCiAgICAgICJfZm9yZWlnbl9tZXNzYWdlXDAzMFwwMjEgXDAwMyhcMDEzMjYucHJvdG9idWZfdW5pdHRlIiArCiAgICAgICJzdC5UZXN0TWFwLk1hcEludDMyRm9yZWlnbk1lc3NhZ2VFbnRyeVwwMjJbIiArCiAgICAgICJcblwwMzJtYXBfc3RyaW5nX2ZvcmVpZ25fbWVzc2FnZVwwMzBcMDIyIFwwMDMoXDAxMzI3LnBybyIgKwogICAgICAidG9idWZfdW5pdHRlc3QuVGVzdE1hcC5NYXBTdHJpbmdGb3JlaWduTSIgKwogICAgICAiZXNzYWdlRW50cnlcMDIyTVxuXDAyM21hcF9pbnQzMl9hbGxfdHlwZXNcMDMwXDAyMyBcMDAzKFwwMTMiICsKICAgICAgIjIwLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNYXAuTWFwSW50MzJBbGwiICsKICAgICAgIlR5cGVzRW50cnlcMDMyNFxuXDAyMk1hcEludDMySW50MzJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMCIgKwogICAgICAiXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyNFxuXDAyMk1hcEludDY0SW50NiIgKwogICAgICAiNEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMzpcMDAyOFwwMDFcMDMyNiIgKwogICAgICAiXG5cMDI0TWFwVWludDMyVWludDMyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDV2IiArCiAgICAgICJhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyNlxuXDAyNE1hcFVpbnQ2NFVpbnQ2NEVudHJ5XDAyMlwwMTMiICsKICAgICAgIlxuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI2XG5cMDI0TWFwU2luIiArCiAgICAgICJ0MzJTaW50MzJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxIiArCiAgICAgICIoXDAyMTpcMDAyOFwwMDFcMDMyNlxuXDAyNE1hcFNpbnQ2NFNpbnQ2NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI4XG5cMDI2TWFwRml4ZWQzMkZpeGUiICsKICAgICAgImQzMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOFwwMDEiICsKICAgICAgIlwwMzI4XG5cMDI2TWFwRml4ZWQ2NEZpeGVkNjRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2XDAyMiIgKwogICAgICAiXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyOlxuXDAzME1hcFNmaXhlZDMyU2ZpeGVkMyIgKwogICAgICAiMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyOiIgKwogICAgICAiXG5cMDMwTWFwU2ZpeGVkNjRTZml4ZWQ2NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjBcMDIyIiArCiAgICAgICJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI0XG5cMDIyTWFwSW50MzJGbG9hdEVudHJ5IiArCiAgICAgICJcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI1XG5cMDIzTWFwSSIgKwogICAgICAibnQzMkRvdWJsZUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyICIgKwogICAgICAiXDAwMShcMDAxOlwwMDI4XDAwMVwwMzIyXG5cMDIwTWFwQm9vbEJvb2xFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDEwIiArCiAgICAgICJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyNlxuXDAyNE1hcFN0cmluZ1N0cmluZ0VuIiArCiAgICAgICJ0cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxXDAzMjRcblwwMjJNIiArCiAgICAgICJhcEludDMyQnl0ZXNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwIiArCiAgICAgICJcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyT1xuXDAyMU1hcEludDMyRW51bUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSAiICsKICAgICAgIlwwMDEoXDAwNVwwMjIpXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyXDAzMi5wcm90b2J1Zl91bml0dGVzdC5NIiArCiAgICAgICJhcEVudW06XDAwMjhcMDAxXDAzMmBcblwwMzNNYXBJbnQzMkZvcmVpZ25NZXNzYWdlRW50ciIgKwogICAgICAieVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMjBcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIhLnByb3RvYnVmIiArCiAgICAgICJfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2U6XDAwMjhcMDAxXDAzMmFcblwwMzRNYXBTdHJpbiIgKwogICAgICAiZ0ZvcmVpZ25NZXNzYWdlRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyMFxuXDAwNXZhbCIgKwogICAgICAidWVcMDMwXDAwMiBcMDAxKFwwMTMyIS5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzcyIgKwogICAgICAiYWdlOlwwMDI4XDAwMVwwMzJYXG5cMDI1TWFwSW50MzJBbGxUeXBlc0VudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwIiArCiAgICAgICJcMDAxIFwwMDEoXDAwNVwwMjIuXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyXDAzNy5wcm90b2J1Zl91bml0dGVzdCIgKwogICAgICAiLlRlc3RBbGxUeXBlczpcMDAyOFwwMDFcIkFcblwwMjFUZXN0TWFwU3VibWVzc2FnZVwwMjIsIiArCiAgICAgICJcblwwMTB0ZXN0X21hcFwwMzBcMDAxIFwwMDEoXDAxMzJcMDMyLnByb3RvYnVmX3VuaXR0ZXN0LlRlcyIgKwogICAgICAidE1hcFwiXDI3NFwwMDFcblwwMTZUZXN0TWVzc2FnZU1hcFwwMjJRXG5cMDIxbWFwX2ludDMyX21lcyIgKwogICAgICAic2FnZVwwMzBcMDAxIFwwMDMoXDAxMzI2LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYSIgKwogICAgICAiZ2VNYXAuTWFwSW50MzJNZXNzYWdlRW50cnlcMDMyV1xuXDAyNE1hcEludDMyTWUiICsKICAgICAgInNzYWdlRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjIuXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyXDAzNyIgKwogICAgICAiLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlczpcMDAyOFwwMDFcIlwzNDNcMDAxXG5cMDE3IiArCiAgICAgICJUZXN0U2FtZVR5cGVNYXBcMDIyOlxuXDAwNG1hcDFcMDMwXDAwMSBcMDAzKFwwMTMyLC5wcm90b2J1ZiIgKwogICAgICAiX3VuaXR0ZXN0LlRlc3RTYW1lVHlwZU1hcC5NYXAxRW50cnlcMDIyOlxuXDAwNG0iICsKICAgICAgImFwMlwwMzBcMDAyIFwwMDMoXDAxMzIsLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTYW1lVHkiICsKICAgICAgInBlTWFwLk1hcDJFbnRyeVwwMzIrXG5cdE1hcDFFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyK1xuXHRNYXAyRW50cnlcMDIyXDAxM1xuXDAwM2tleSIgKwogICAgICAiXDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMDU6XDAwMjhcMDAxXCJcMjY2XDAwMVxuXDAyNlRlc3RSZXF1aXIiICsKICAgICAgImVkTWVzc2FnZU1hcFwwMjJKXG5cdG1hcF9maWVsZFwwMzBcMDAxIFwwMDMoXDAxMzI3LnByb3RvYiIgKwogICAgICAidWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZU1hcC5NYXBGaSIgKwogICAgICAiZWxkRW50cnlcMDMyUFxuXHJNYXBGaWVsZEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyLiIgKwogICAgICAiXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTMyXDAzNy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmUiICsKICAgICAgInF1aXJlZDpcMDAyOFwwMDFcIlwzNjBcMDIyXG5cMDE0VGVzdEFyZW5hTWFwXDAyMktcblwwMTdtYXBfaW50MzIiICsKICAgICAgIl9pbnQzMlwwMzBcMDAxIFwwMDMoXDAxMzIyLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBcmUiICsKICAgICAgIm5hTWFwLk1hcEludDMySW50MzJFbnRyeVwwMjJLXG5cMDE3bWFwX2ludDY0X2luIiArCiAgICAgICJ0NjRcMDMwXDAwMiBcMDAzKFwwMTMyMi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QXJlbmFNIiArCiAgICAgICJhcC5NYXBJbnQ2NEludDY0RW50cnlcMDIyT1xuXDAyMW1hcF91aW50MzJfdWludCIgKwogICAgICAiMzJcMDMwXDAwMyBcMDAzKFwwMTMyNC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QXJlbmFNYSIgKwogICAgICAicC5NYXBVaW50MzJVaW50MzJFbnRyeVwwMjJPXG5cMDIxbWFwX3VpbnQ2NF91aW4iICsKICAgICAgInQ2NFwwMzBcMDA0IFwwMDMoXDAxMzI0LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBcmVuYU0iICsKICAgICAgImFwLk1hcFVpbnQ2NFVpbnQ2NEVudHJ5XDAyMk9cblwwMjFtYXBfc2ludDMyX3NpIiArCiAgICAgICJudDMyXDAzMFwwMDUgXDAwMyhcMDEzMjQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFyZW5hIiArCiAgICAgICJNYXAuTWFwU2ludDMyU2ludDMyRW50cnlcMDIyT1xuXDAyMW1hcF9zaW50NjRfcyIgKwogICAgICAiaW50NjRcMDMwXDAwNiBcMDAzKFwwMTMyNC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QXJlbiIgKwogICAgICAiYU1hcC5NYXBTaW50NjRTaW50NjRFbnRyeVwwMjJTXG5cMDIzbWFwX2ZpeGVkMzIiICsKICAgICAgIl9maXhlZDMyXDAzMFwwMDcgXDAwMyhcMDEzMjYucHJvdG9idWZfdW5pdHRlc3QuVGVzdEEiICsKICAgICAgInJlbmFNYXAuTWFwRml4ZWQzMkZpeGVkMzJFbnRyeVwwMjJTXG5cMDIzbWFwX2ZpIiArCiAgICAgICJ4ZWQ2NF9maXhlZDY0XDAzMFwwMTAgXDAwMyhcMDEzMjYucHJvdG9idWZfdW5pdHRlc3QuIiArCiAgICAgICJUZXN0QXJlbmFNYXAuTWFwRml4ZWQ2NEZpeGVkNjRFbnRyeVwwMjJXXG5cMDI1bSIgKwogICAgICAiYXBfc2ZpeGVkMzJfc2ZpeGVkMzJcMDMwXHQgXDAwMyhcMDEzMjgucHJvdG9idWZfdW4iICsKICAgICAgIml0dGVzdC5UZXN0QXJlbmFNYXAuTWFwU2ZpeGVkMzJTZml4ZWQzMkUiICsKICAgICAgIm50cnlcMDIyV1xuXDAyNW1hcF9zZml4ZWQ2NF9zZml4ZWQ2NFwwMzBcbiBcMDAzKFwwMTMyOC5wciIgKwogICAgICAib3RvYnVmX3VuaXR0ZXN0LlRlc3RBcmVuYU1hcC5NYXBTZml4ZWQ2NCIgKwogICAgICAiU2ZpeGVkNjRFbnRyeVwwMjJLXG5cMDE3bWFwX2ludDMyX2Zsb2F0XDAzMFwwMTMgXDAwMyhcMDEzMjIiICsKICAgICAgIi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QXJlbmFNYXAuTWFwSW50MzIiICsKICAgICAgIkZsb2F0RW50cnlcMDIyTVxuXDAyMG1hcF9pbnQzMl9kb3VibGVcMDMwXDAxNCBcMDAzKFwwMTMyMy5wIiArCiAgICAgICJyb3RvYnVmX3VuaXR0ZXN0LlRlc3RBcmVuYU1hcC5NYXBJbnQzMkRvIiArCiAgICAgICJ1YmxlRW50cnlcMDIyR1xuXHJtYXBfYm9vbF9ib29sXDAzMFxyIFwwMDMoXDAxMzIwLnByb3RvIiArCiAgICAgICJidWZfdW5pdHRlc3QuVGVzdEFyZW5hTWFwLk1hcEJvb2xCb29sRW50IiArCiAgICAgICJyeVwwMjJPXG5cMDIxbWFwX3N0cmluZ19zdHJpbmdcMDMwXDAxNiBcMDAzKFwwMTMyNC5wcm90b2J1ZiIgKwogICAgICAiX3VuaXR0ZXN0LlRlc3RBcmVuYU1hcC5NYXBTdHJpbmdTdHJpbmdFbiIgKwogICAgICAidHJ5XDAyMktcblwwMTdtYXBfaW50MzJfYnl0ZXNcMDMwXDAxNyBcMDAzKFwwMTMyMi5wcm90b2J1Zl8iICsKICAgICAgInVuaXR0ZXN0LlRlc3RBcmVuYU1hcC5NYXBJbnQzMkJ5dGVzRW50cnkiICsKICAgICAgIlwwMjJJXG5cMDE2bWFwX2ludDMyX2VudW1cMDMwXDAyMCBcMDAzKFwwMTMyMS5wcm90b2J1Zl91bml0IiArCiAgICAgICJ0ZXN0LlRlc3RBcmVuYU1hcC5NYXBJbnQzMkVudW1FbnRyeVwwMjJeXG5cMDMxbSIgKwogICAgICAiYXBfaW50MzJfZm9yZWlnbl9tZXNzYWdlXDAzMFwwMjEgXDAwMyhcMDEzMjsucHJvdG9idSIgKwogICAgICAiZl91bml0dGVzdC5UZXN0QXJlbmFNYXAuTWFwSW50MzJGb3JlaWduTSIgKwogICAgICAiZXNzYWdlRW50cnlcMDMyNFxuXDAyMk1hcEludDMySW50MzJFbnRyeVwwMjJcMDEzXG5cMDAza2V5IiArCiAgICAgICJcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNTpcMDAyOFwwMDFcMDMyNFxuXDAyMk1hcEludDY0SW50IiArCiAgICAgICI2NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDNcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwMzpcMDAyOFwwMDFcMDMyIiArCiAgICAgICI2XG5cMDI0TWFwVWludDMyVWludDMyRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHJcMDIyXHJcblwwMDUiICsKICAgICAgInZhbHVlXDAzMFwwMDIgXDAwMShccjpcMDAyOFwwMDFcMDMyNlxuXDAyNE1hcFVpbnQ2NFVpbnQ2NEVudHJ5XDAyMiIgKwogICAgICAiXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNFwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA0OlwwMDI4XDAwMVwwMzI2XG5cMDI0TWFwU2kiICsKICAgICAgIm50MzJTaW50MzJFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDIxXDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiAiICsKICAgICAgIlwwMDEoXDAyMTpcMDAyOFwwMDFcMDMyNlxuXDAyNE1hcFNpbnQ2NFNpbnQ2NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSIgKwogICAgICAiIFwwMDEoXDAyMlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIyOlwwMDI4XDAwMVwwMzI4XG5cMDI2TWFwRml4ZWQzMkZpeCIgKwogICAgICAiZWQzMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNzpcMDAyOCIgKwogICAgICAiXDAwMVwwMzI4XG5cMDI2TWFwRml4ZWQ2NEZpeGVkNjRFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA2IiArCiAgICAgICJcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAwNjpcMDAyOFwwMDFcMDMyOlxuXDAzME1hcFNmaXhlZDMyU2ZpeGVkIiArCiAgICAgICIzMkVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMTdcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxNzpcMDAyOFwwMDFcMDMyIiArCiAgICAgICI6XG5cMDMwTWFwU2ZpeGVkNjRTZml4ZWQ2NEVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMjAiICsKICAgICAgIlwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDIwOlwwMDI4XDAwMVwwMzI0XG5cMDIyTWFwSW50MzJGbG9hdEVudHIiICsKICAgICAgInlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDAyOlwwMDI4XDAwMVwwMzI1XG5cMDIzTWFwIiArCiAgICAgICJJbnQzMkRvdWJsZUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcMDAxOlwwMDI4XDAwMVwwMzIyXG5cMDIwTWFwQm9vbEJvb2xFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMTBcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMDpcMDAyOFwwMDFcMDMyNlxuXDAyNE1hcFN0cmluZ1N0cmluZ0UiICsKICAgICAgIm50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxXDAzMjRcblwwMjIiICsKICAgICAgIk1hcEludDMyQnl0ZXNFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMlxyXG5cMDA1dmFsdWUiICsKICAgICAgIlwwMzBcMDAyIFwwMDEoXDAxNDpcMDAyOFwwMDFcMDMyT1xuXDAyMU1hcEludDMyRW51bUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSIgKwogICAgICAiIFwwMDEoXDAwNVwwMjIpXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFwwMTYyXDAzMi5wcm90b2J1Zl91bml0dGVzdC4iICsKICAgICAgIk1hcEVudW06XDAwMjhcMDAxXDAzMmBcblwwMzNNYXBJbnQzMkZvcmVpZ25NZXNzYWdlRW50IiArCiAgICAgICJyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcMDA1XDAyMjBcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIhLnByb3RvYnUiICsKICAgICAgImZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2U6XDAwMjhcMDAxXCJcMzQ0XDAwMVxuXDAzN01lc3NhZyIgKwogICAgICAiZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZVwwMjJKXG5cMDA0dHlwZVwwMzBcMDAxIFwwMDMoXDAxMzIiICsKICAgICAgIjwucHJvdG9idWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdFbnUiICsKICAgICAgIm1DYWxsZWRUeXBlLlR5cGVFbnRyeVwwMzJfXG5cdFR5cGVFbnRyeVwwMjJcMDEzXG5cMDAza2UiICsKICAgICAgInlcMDMwXDAwMSBcMDAxKFx0XDAyMkFcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIyLnByb3RvYnVmX3VuaXR0ZSIgKwogICAgICAic3QuTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZTpcMDAyOFwwMDFcIlwwMjQiICsKICAgICAgIlxuXDAwNFR5cGVcMDIyXDAxNFxuXDAxMFRZUEVfRk9PXDAyMFwwMDBcIlwyMzVcMDAxXG5cMDM3TWVzc2FnZUNvbnRhaW5pIiArCiAgICAgICJuZ01hcENhbGxlZEVudHJ5XDAyMkxcblwwMDVlbnRyeVwwMzBcMDAxIFwwMDMoXDAxMzI9LnByb3RvYiIgKwogICAgICAidWZfdW5pdHRlc3QuTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbiIgKwogICAgICAidHJ5LkVudHJ5RW50cnlcMDMyLFxuXG5FbnRyeUVudHJ5XDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAwNVwwMjJcclxuXDAwNXZhbHVlXDAzMFwwMDIgXDAwMShcMDA1OlwwMDI4XDAwMVwiXDI1NVwwMDFcblwwMjdUZXN0UmVjdXJzaXZlTWEiICsKICAgICAgInBNZXNzYWdlXDAyMjxcblwwMDFhXDAzMFwwMDEgXDAwMyhcMDEzMjEucHJvdG9idWZfdW5pdHRlc3QuIiArCiAgICAgICJUZXN0UmVjdXJzaXZlTWFwTWVzc2FnZS5BRW50cnlcMDMyVFxuXDAwNkFFbnRyeSIgKwogICAgICAiXDAyMlwwMTNcblwwMDNrZXlcMDMwXDAwMSBcMDAxKFx0XDAyMjlcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXDAxMzIqLnByb3RvYnVmXyIgKwogICAgICAidW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2U6XDAwMjhcMDAxKj9cblwwMDciICsKICAgICAgIk1hcEVudW1cMDIyXDAyMFxuXDAxNE1BUF9FTlVNX0ZPT1wwMjBcMDAwXDAyMlwwMjBcblwwMTRNQVBfRU5VTV9CQSIgKwogICAgICAiUlwwMjBcMDAxXDAyMlwwMjBcblwwMTRNQVBfRU5VTV9CQVpcMDIwXDAwMkJcMDAzXDM3MFwwMDFcMDAxYlwwMDZwcm90bzMiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZ2V0RGVzY3JpcHRvcigpLAogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJNYXBJbnQzMkludDMyIiwgIk1hcEludDY0SW50NjQiLCAiTWFwVWludDMyVWludDMyIiwgIk1hcFVpbnQ2NFVpbnQ2NCIsICJNYXBTaW50MzJTaW50MzIiLCAiTWFwU2ludDY0U2ludDY0IiwgIk1hcEZpeGVkMzJGaXhlZDMyIiwgIk1hcEZpeGVkNjRGaXhlZDY0IiwgIk1hcFNmaXhlZDMyU2ZpeGVkMzIiLCAiTWFwU2ZpeGVkNjRTZml4ZWQ2NCIsICJNYXBJbnQzMkZsb2F0IiwgIk1hcEludDMyRG91YmxlIiwgIk1hcEJvb2xCb29sIiwgIk1hcFN0cmluZ1N0cmluZyIsICJNYXBJbnQzMkJ5dGVzIiwgIk1hcEludDMyRW51bSIsICJNYXBJbnQzMkZvcmVpZ25NZXNzYWdlIiwgIk1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlIiwgIk1hcEludDMyQWxsVHlwZXMiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMySW50MzJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMySW50MzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMySW50MzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBJbnQ2NEludDY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBJbnQ2NEludDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBJbnQ2NEludDY0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwVWludDMyVWludDMyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBVaW50MzJVaW50MzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFVpbnQzMlVpbnQzMkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFVpbnQ2NFVpbnQ2NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwVWludDY0VWludDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBVaW50NjRVaW50NjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBTaW50MzJTaW50MzJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFNpbnQzMlNpbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwU2ludDMyU2ludDMyRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwU2ludDY0U2ludDY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBTaW50NjRTaW50NjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFNpbnQ2NFNpbnQ2NEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEZpeGVkMzJGaXhlZDMyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBGaXhlZDMyRml4ZWQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwRml4ZWQzMkZpeGVkMzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBGaXhlZDY0Rml4ZWQ2NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwRml4ZWQ2NEZpeGVkNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEZpeGVkNjRGaXhlZDY0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwU2ZpeGVkMzJTZml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwU2ZpeGVkMzJTZml4ZWQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwU2ZpeGVkMzJTZml4ZWQzMkVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFNmaXhlZDY0U2ZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFNmaXhlZDY0U2ZpeGVkNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFNmaXhlZDY0U2ZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBJbnQzMkZsb2F0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJGbG9hdEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJGbG9hdEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMyRG91YmxlRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJEb3VibGVFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMyRG91YmxlRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwQm9vbEJvb2xFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBCb29sQm9vbEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwQm9vbEJvb2xFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBTdHJpbmdTdHJpbmdFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBTdHJpbmdTdHJpbmdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFN0cmluZ1N0cmluZ0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMyQnl0ZXNFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBJbnQzMkJ5dGVzRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBJbnQzMkJ5dGVzRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJFbnVtRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJFbnVtRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBJbnQzMkVudW1FbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9NYXBJbnQzMkZvcmVpZ25NZXNzYWdlRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJGb3JlaWduTWVzc2FnZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJGb3JlaWduTWVzc2FnZUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNYXBfTWFwSW50MzJBbGxUeXBlc0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMyQWxsVHlwZXNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWFwX01hcEludDMyQWxsVHlwZXNFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcFN1Ym1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcFN1Ym1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1hcFN1Ym1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlRlc3RNYXAiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZU1hcF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZU1hcF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZU1hcF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiTWFwSW50MzJNZXNzYWdlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VNYXBfTWFwSW50MzJNZXNzYWdlRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlTWFwX01hcEludDMyTWVzc2FnZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlTWFwX01hcEludDMyTWVzc2FnZUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0U2FtZVR5cGVNYXBfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFNhbWVUeXBlTWFwX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RTYW1lVHlwZU1hcF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiTWFwMSIsICJNYXAyIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFNhbWVUeXBlTWFwX01hcDFFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RTYW1lVHlwZU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RTYW1lVHlwZU1hcF9NYXAxRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFNhbWVUeXBlTWFwX01hcDFFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFNhbWVUeXBlTWFwX01hcDJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RTYW1lVHlwZU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RTYW1lVHlwZU1hcF9NYXAyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFNhbWVUeXBlTWFwX01hcDJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkTWVzc2FnZU1hcF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRNZXNzYWdlTWFwX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE1lc3NhZ2VNYXBfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk1hcEZpZWxkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkTWVzc2FnZU1hcF9NYXBGaWVsZEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkTWVzc2FnZU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE1lc3NhZ2VNYXBfTWFwRmllbGRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRNZXNzYWdlTWFwX01hcEZpZWxkRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJNYXBJbnQzMkludDMyIiwgIk1hcEludDY0SW50NjQiLCAiTWFwVWludDMyVWludDMyIiwgIk1hcFVpbnQ2NFVpbnQ2NCIsICJNYXBTaW50MzJTaW50MzIiLCAiTWFwU2ludDY0U2ludDY0IiwgIk1hcEZpeGVkMzJGaXhlZDMyIiwgIk1hcEZpeGVkNjRGaXhlZDY0IiwgIk1hcFNmaXhlZDMyU2ZpeGVkMzIiLCAiTWFwU2ZpeGVkNjRTZml4ZWQ2NCIsICJNYXBJbnQzMkZsb2F0IiwgIk1hcEludDMyRG91YmxlIiwgIk1hcEJvb2xCb29sIiwgIk1hcFN0cmluZ1N0cmluZyIsICJNYXBJbnQzMkJ5dGVzIiwgIk1hcEludDMyRW51bSIsICJNYXBJbnQzMkZvcmVpZ25NZXNzYWdlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMySW50MzJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkludDMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMySW50MzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDY0SW50NjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQ2NEludDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDY0SW50NjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFVpbnQzMlVpbnQzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFVpbnQzMlVpbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBVaW50MzJVaW50MzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFVpbnQ2NFVpbnQ2NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFVpbnQ2NFVpbnQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBVaW50NjRVaW50NjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFNpbnQzMlNpbnQzMkVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFNpbnQzMlNpbnQzMkVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBTaW50MzJTaW50MzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFNpbnQ2NFNpbnQ2NEVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFNpbnQ2NFNpbnQ2NEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBTaW50NjRTaW50NjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEZpeGVkMzJGaXhlZDMyRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwRml4ZWQzMkZpeGVkMzJFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwRml4ZWQzMkZpeGVkMzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEZpeGVkNjRGaXhlZDY0RW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCg3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwRml4ZWQ2NEZpeGVkNjRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwRml4ZWQ2NEZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFNmaXhlZDMyU2ZpeGVkMzJFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBTZml4ZWQzMlNmaXhlZDMyRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFNmaXhlZDMyU2ZpeGVkMzJFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFNmaXhlZDY0U2ZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBTZml4ZWQ2NFNmaXhlZDY0RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFNmaXhlZDY0U2ZpeGVkNjRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMyRmxvYXRFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwSW50MzJGbG9hdEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkZsb2F0RW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkRvdWJsZUVudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkRvdWJsZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkRvdWJsZUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwQm9vbEJvb2xFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwQm9vbEJvb2xFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwQm9vbEJvb2xFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcFN0cmluZ1N0cmluZ0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMTMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBTdHJpbmdTdHJpbmdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwU3RyaW5nU3RyaW5nRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkJ5dGVzRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMyQnl0ZXNFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwSW50MzJCeXRlc0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwSW50MzJFbnVtRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMyRW51bUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkVudW1FbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFyZW5hTWFwX01hcEludDMyRm9yZWlnbk1lc3NhZ2VFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDE2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QXJlbmFNYXBfTWFwSW50MzJGb3JlaWduTWVzc2FnZUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBcmVuYU1hcF9NYXBJbnQzMkZvcmVpZ25NZXNzYWdlRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VDb250YWluaW5nRW51bUNhbGxlZFR5cGVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJUeXBlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZV9UeXBlRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlQ29udGFpbmluZ0VudW1DYWxsZWRUeXBlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZV9UeXBlRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdFbnVtQ2FsbGVkVHlwZV9UeXBlRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJFbnRyeSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnlfRW50cnlFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01lc3NhZ2VDb250YWluaW5nTWFwQ2FsbGVkRW50cnlfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NZXNzYWdlQ29udGFpbmluZ01hcENhbGxlZEVudHJ5X0VudHJ5RW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWVzc2FnZUNvbnRhaW5pbmdNYXBDYWxsZWRFbnRyeV9FbnRyeUVudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVjdXJzaXZlTWFwTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZWN1cnNpdmVNYXBNZXNzYWdlX0FFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZWN1cnNpdmVNYXBNZXNzYWdlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlY3Vyc2l2ZU1hcE1lc3NhZ2VfQUVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZWN1cnNpdmVNYXBNZXNzYWdlX0FFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmdldERlc2NyaXB0b3IoKTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAI1UfFHDrgAAw64AACMAAABwcm90b2J1Zl91bml0dGVzdC9UZXN0QW55UHJvdG8uamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL2FueV90ZXN0LnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKCnB1YmxpYyBmaW5hbCBjbGFzcyBUZXN0QW55UHJvdG8gewogIHByaXZhdGUgVGVzdEFueVByb3RvKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RBbnlPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGludDMyX3ZhbHVlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbnQzMlZhbHVlLgogICAgICovCiAgICBpbnQgZ2V0SW50MzJWYWx1ZSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X3ZhbHVlID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGFueVZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNBbnlWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfdmFsdWUgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGFueVZhbHVlLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSBnZXRBbnlWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfdmFsdWUgPSAyOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIgZ2V0QW55VmFsdWVPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IHJlcGVhdGVkX2FueV92YWx1ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkFueT4gCiAgICAgICAgZ2V0UmVwZWF0ZWRBbnlWYWx1ZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGdldFJlcGVhdGVkQW55VmFsdWUoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEFueVZhbHVlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRBbnlWYWx1ZU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55T3JCdWlsZGVyIGdldFJlcGVhdGVkQW55VmFsdWVPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyB0ZXh0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSB0ZXh0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFRleHQoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIHRleHQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciB0ZXh0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRUZXh0Qnl0ZXMoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RBbnkgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueSkKICAgICAgVGVzdEFueU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdEFueS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0QW55KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdEFueSgpIHsKICAgICAgcmVwZWF0ZWRBbnlWYWx1ZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHRleHRfID0gIiI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdEFueSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFueV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFueV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5UZXN0QW55LmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5UZXN0QW55UHJvdG8uVGVzdEFueS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfVkFMVUVfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IGludDMyVmFsdWVfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgaW50MzJfdmFsdWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGludDMyVmFsdWUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0SW50MzJWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGludDMyVmFsdWVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFOWV9WQUxVRV9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlWYWx1ZV87CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV92YWx1ZSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhbnlWYWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0FueVZhbHVlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV92YWx1ZSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYW55VmFsdWUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSBnZXRBbnlWYWx1ZSgpIHsKICAgICAgcmV0dXJuIGFueVZhbHVlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBhbnlWYWx1ZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV92YWx1ZSA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIgZ2V0QW55VmFsdWVPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBhbnlWYWx1ZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYuQW55LmdldERlZmF1bHRJbnN0YW5jZSgpIDogYW55VmFsdWVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0FOWV9WQUxVRV9GSUVMRF9OVU1CRVIgPSAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQW55PiByZXBlYXRlZEFueVZhbHVlXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkFueT4gZ2V0UmVwZWF0ZWRBbnlWYWx1ZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFueVZhbHVlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkQW55VmFsdWVPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbnlWYWx1ZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IHJlcGVhdGVkX2FueV92YWx1ZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQW55VmFsdWVDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQW55VmFsdWVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSBnZXRSZXBlYXRlZEFueVZhbHVlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbnlWYWx1ZV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlciBnZXRSZXBlYXRlZEFueVZhbHVlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbnlWYWx1ZV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBURVhUX0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCB0ZXh0XyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgdGV4dCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdGV4dC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0VGV4dCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSB0ZXh0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIHRleHRfID0gczsKICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgdGV4dCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHRleHQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRUZXh0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gdGV4dF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIHRleHRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoaW50MzJWYWx1ZV8gIT0gMCkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGludDMyVmFsdWVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIsIGdldEFueVZhbHVlKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRBbnlWYWx1ZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDMsIHJlcGVhdGVkQW55VmFsdWVfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KHRleHRfKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNCwgdGV4dF8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoaW50MzJWYWx1ZV8gIT0gMCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgaW50MzJWYWx1ZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBnZXRBbnlWYWx1ZSgpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQW55VmFsdWVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIHJlcGVhdGVkQW55VmFsdWVfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKCFjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5pc1N0cmluZ0VtcHR5KHRleHRfKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoNCwgdGV4dF8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5UZXN0QW55KSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5UZXN0QW55UHJvdG8uVGVzdEFueSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5UZXN0QW55UHJvdG8uVGVzdEFueSkgb2JqOwoKICAgICAgaWYgKGdldEludDMyVmFsdWUoKQogICAgICAgICAgIT0gb3RoZXIuZ2V0SW50MzJWYWx1ZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNBbnlWYWx1ZSgpICE9IG90aGVyLmhhc0FueVZhbHVlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0FueVZhbHVlKCkpIHsKICAgICAgICBpZiAoIWdldEFueVZhbHVlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRBbnlWYWx1ZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRBbnlWYWx1ZUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEFueVZhbHVlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFRleHQoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRUZXh0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSU5UMzJfVkFMVUVfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRJbnQzMlZhbHVlKCk7CiAgICAgIGlmIChoYXNBbnlWYWx1ZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQU5ZX1ZBTFVFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBbnlWYWx1ZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQW55VmFsdWVDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0FOWV9WQUxVRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRBbnlWYWx1ZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFRFWFRfRklFTERfTlVNQkVSOwogICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRUZXh0KCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5UZXN0QW55IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5UZXN0QW55IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0QW55UHJvdG8uVGVzdEFueSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5UZXN0QW55IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5UZXN0QW55IHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0QW55UHJvdG8uVGVzdEFueSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5UZXN0QW55IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnkpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnlPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QW55X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFueV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5UZXN0QW55UHJvdG8uVGVzdEFueS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5UZXN0QW55UHJvdG8uVGVzdEFueS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRBbnlWYWx1ZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRBbnlWYWx1ZUZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaW50MzJWYWx1ZV8gPSAwOwogICAgICAgIGFueVZhbHVlXyA9IG51bGw7CiAgICAgICAgaWYgKGFueVZhbHVlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgYW55VmFsdWVCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBhbnlWYWx1ZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEFueVZhbHVlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbnlWYWx1ZV8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICB0ZXh0XyA9ICIiOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5UZXN0QW55UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbnlfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5UZXN0QW55IGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5UZXN0QW55IHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5UZXN0QW55IHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5UZXN0QW55UHJvdG8uVGVzdEFueSh0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhwcm90b2J1Zl91bml0dGVzdC5UZXN0QW55UHJvdG8uVGVzdEFueSByZXN1bHQpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZEFueVZhbHVlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkQW55VmFsdWVfKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQW55VmFsdWVfID0gcmVwZWF0ZWRBbnlWYWx1ZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEFueVZhbHVlXyA9IHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pbnQzMlZhbHVlXyA9IGludDMyVmFsdWVfOwogICAgICAgIH0KICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5hbnlWYWx1ZV8gPSBhbnlWYWx1ZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGFueVZhbHVlXwogICAgICAgICAgICAgIDogYW55VmFsdWVCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnRleHRfID0gdGV4dF87CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5UZXN0QW55UHJvdG8uVGVzdEFueSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueVByb3RvLlRlc3RBbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5nZXRJbnQzMlZhbHVlKCkgIT0gMCkgewogICAgICAgICAgc2V0SW50MzJWYWx1ZShvdGhlci5nZXRJbnQzMlZhbHVlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzQW55VmFsdWUoKSkgewogICAgICAgICAgbWVyZ2VBbnlWYWx1ZShvdGhlci5nZXRBbnlWYWx1ZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQW55VmFsdWVfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRBbnlWYWx1ZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbnlWYWx1ZV8gPSBvdGhlci5yZXBlYXRlZEFueVZhbHVlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbnlWYWx1ZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkQW55VmFsdWVfLmFkZEFsbChvdGhlci5yZXBlYXRlZEFueVZhbHVlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRBbnlWYWx1ZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkQW55VmFsdWVfID0gb3RoZXIucmVwZWF0ZWRBbnlWYWx1ZV87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgICAgICAgIHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZEFueVZhbHVlRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZEFueVZhbHVlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5nZXRUZXh0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICB0ZXh0XyA9IG90aGVyLnRleHRfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgaW50MzJWYWx1ZV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0QW55VmFsdWVGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LnBhcnNlcigpLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbnlWYWx1ZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEFueVZhbHVlXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIHRleHRfID0gaW5wdXQucmVhZFN0cmluZ1JlcXVpcmVVdGY4KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgaW50MzJWYWx1ZV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgaW50MzJfdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgaW50MzJWYWx1ZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJbnQzMlZhbHVlKCkgewogICAgICAgIHJldHVybiBpbnQzMlZhbHVlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgaW50MzJfdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBpbnQzMlZhbHVlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SW50MzJWYWx1ZShpbnQgdmFsdWUpIHsKCiAgICAgICAgaW50MzJWYWx1ZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGludDMyX3ZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50MzJWYWx1ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaW50MzJWYWx1ZV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGFueVZhbHVlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnksIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55T3JCdWlsZGVyPiBhbnlWYWx1ZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+Lmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55X3ZhbHVlID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYW55VmFsdWUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzQW55VmFsdWUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfdmFsdWUgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYW55VmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkgZ2V0QW55VmFsdWUoKSB7CiAgICAgICAgaWYgKGFueVZhbHVlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGFueVZhbHVlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBhbnlWYWx1ZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBhbnlWYWx1ZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV92YWx1ZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QW55VmFsdWUoY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkgdmFsdWUpIHsKICAgICAgICBpZiAoYW55VmFsdWVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGFueVZhbHVlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhbnlWYWx1ZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV92YWx1ZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QW55VmFsdWUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChhbnlWYWx1ZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGFueVZhbHVlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhbnlWYWx1ZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV92YWx1ZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VBbnlWYWx1ZShjb20uZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZSkgewogICAgICAgIGlmIChhbnlWYWx1ZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSAmJgogICAgICAgICAgICBhbnlWYWx1ZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBhbnlWYWx1ZV8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0QW55VmFsdWVCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGFueVZhbHVlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhbnlWYWx1ZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChhbnlWYWx1ZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4uZ29vZ2xlLnByb3RvYnVmLkFueSBhbnlfdmFsdWUgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQW55VmFsdWUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGFueVZhbHVlXyA9IG51bGw7CiAgICAgICAgaWYgKGFueVZhbHVlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgYW55VmFsdWVCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBhbnlWYWx1ZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV92YWx1ZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIgZ2V0QW55VmFsdWVCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0QW55VmFsdWVGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV92YWx1ZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55T3JCdWlsZGVyIGdldEFueVZhbHVlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChhbnlWYWx1ZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBhbnlWYWx1ZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGFueVZhbHVlXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGFueVZhbHVlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5nb29nbGUucHJvdG9idWYuQW55IGFueV92YWx1ZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnksIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55T3JCdWlsZGVyPiAKICAgICAgICAgIGdldEFueVZhbHVlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChhbnlWYWx1ZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGFueVZhbHVlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRBbnlWYWx1ZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgYW55VmFsdWVfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFueVZhbHVlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5Bbnk+IHJlcGVhdGVkQW55VmFsdWVfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEFueVZhbHVlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQW55VmFsdWVfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5Bbnk+KHJlcGVhdGVkQW55VmFsdWVfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4gcmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IHJlcGVhdGVkX2FueV92YWx1ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQW55PiBnZXRSZXBlYXRlZEFueVZhbHVlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEFueVZhbHVlXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IHJlcGVhdGVkX2FueV92YWx1ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEFueVZhbHVlQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbnlWYWx1ZV8uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSByZXBlYXRlZF9hbnlfdmFsdWUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSBnZXRSZXBlYXRlZEFueVZhbHVlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQW55VmFsdWVfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSByZXBlYXRlZF9hbnlfdmFsdWUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQW55VmFsdWUoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQW55VmFsdWVJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQW55VmFsdWVfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSByZXBlYXRlZF9hbnlfdmFsdWUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQW55VmFsdWUoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFueVZhbHVlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFueVZhbHVlXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFueVZhbHVlKGNvbS5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQW55VmFsdWVJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQW55VmFsdWVfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFueVZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFueVZhbHVlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFueVZhbHVlXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFueVZhbHVlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQW55VmFsdWVJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQW55VmFsdWVfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFueVZhbHVlKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbnlWYWx1ZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbnlWYWx1ZV8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IHJlcGVhdGVkX2FueV92YWx1ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRBbnlWYWx1ZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Bbnk+IHZhbHVlcykgewogICAgICAgIGlmIChyZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbnlWYWx1ZUlzTXV0YWJsZSgpOwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRBbnlWYWx1ZV8pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQW55VmFsdWUoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEFueVZhbHVlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IHJlcGVhdGVkX2FueV92YWx1ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRBbnlWYWx1ZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQW55VmFsdWVJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQW55VmFsdWVfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSByZXBlYXRlZF9hbnlfdmFsdWUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyIGdldFJlcGVhdGVkQW55VmFsdWVCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQW55VmFsdWVGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLmdvb2dsZS5wcm90b2J1Zi5BbnkgcmVwZWF0ZWRfYW55X3ZhbHVlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRBbnlWYWx1ZU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQW55VmFsdWVfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5nb29nbGUucHJvdG9idWYuQW55IHJlcGVhdGVkX2FueV92YWx1ZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRBbnlWYWx1ZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbnlWYWx1ZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEFueVZhbHVlXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSByZXBlYXRlZF9hbnlfdmFsdWUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyIGFkZFJlcGVhdGVkQW55VmFsdWVCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEFueVZhbHVlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSByZXBlYXRlZF9hbnlfdmFsdWUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyIGFkZFJlcGVhdGVkQW55VmFsdWVCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQW55VmFsdWVGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAuZ29vZ2xlLnByb3RvYnVmLkFueSByZXBlYXRlZF9hbnlfdmFsdWUgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEFueVZhbHVlQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQW55VmFsdWVGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnksIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuQW55T3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkQW55VmFsdWVGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEFueVZhbHVlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQW55VmFsdWVfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkQW55VmFsdWVfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQW55VmFsdWVCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHRleHRfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgdGV4dCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB0ZXh0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0VGV4dCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHRleHRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgdGV4dF8gPSBzOwogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIHRleHQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHRleHQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRUZXh0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSB0ZXh0XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgdGV4dF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgdGV4dCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHRleHQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRUZXh0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgdGV4dF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyB0ZXh0ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVGV4dCgpIHsKICAgICAgICB0ZXh0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFRleHQoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyB0ZXh0ID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHRleHQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRUZXh0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNoZWNrQnl0ZVN0cmluZ0lzVXRmOCh2YWx1ZSk7CiAgICAgICAgdGV4dF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFueSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5UZXN0QW55IERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5UZXN0QW55KCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5UZXN0QW55UHJvdG8uVGVzdEFueSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RBbnk+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEFueT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RBbnkgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0QW55PiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RBbnk+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbnlQcm90by5UZXN0QW55IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFueV9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuXDAzNmdvb2dsZS9wcm90b2J1Zi9hbnlfdGVzdC5wcm90b1wwMjJcMDIxcHJvdG9iIiArCiAgICAgICJ1Zl91bml0dGVzdFwwMzJcMDMxZ29vZ2xlL3Byb3RvYnVmL2FueS5wcm90b1wiXDIwNyIgKwogICAgICAiXDAwMVxuXDAwN1Rlc3RBbnlcMDIyXDAyM1xuXDAxM2ludDMyX3ZhbHVlXDAzMFwwMDEgXDAwMShcMDA1XDAyMlwnXG5cdGFueV92IiArCiAgICAgICJhbHVlXDAzMFwwMDIgXDAwMShcMDEzMlwwMjQuZ29vZ2xlLnByb3RvYnVmLkFueVwwMjIwXG5cMDIycmVwZSIgKwogICAgICAiYXRlZF9hbnlfdmFsdWVcMDMwXDAwMyBcMDAzKFwwMTMyXDAyNC5nb29nbGUucHJvdG9idWYuQSIgKwogICAgICAibnlcMDIyXDAxNFxuXDAwNHRleHRcMDMwXDAwNCBcMDAxKFx0QlwwMTZCXDAxNFRlc3RBbnlQcm90b2JcMDA2cHJvdG8zIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueVByb3RvLmdldERlc2NyaXB0b3IoKSwKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QW55X2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFueV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSW50MzJWYWx1ZSIsICJBbnlWYWx1ZSIsICJSZXBlYXRlZEFueVZhbHVlIiwgIlRleHQiLCB9KTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55UHJvdG8uZ2V0RGVzY3JpcHRvcigpOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEAtxFgmL/0CgC/9AoALAAAAHByb3RvYnVmX3VuaXR0ZXN0L1VuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIFVuaXR0ZXN0Q3VzdG9tT3B0aW9ucyB7CiAgcHJpdmF0ZSBVbml0dGVzdEN1c3RvbU9wdGlvbnMoKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmZpbGVPcHQxKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMubWVzc2FnZU9wdDEpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5maWVsZE9wdDEpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5maWVsZE9wdDIpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5vbmVvZk9wdDEpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5lbnVtT3B0MSk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmVudW1WYWx1ZU9wdDEpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5zZXJ2aWNlT3B0MSk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLm1ldGhvZE9wdDEpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5ib29sT3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50MzJPcHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnQ2NE9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLnVpbnQzMk9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLnVpbnQ2NE9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLnNpbnQzMk9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLnNpbnQ2NE9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmZpeGVkMzJPcHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5maXhlZDY0T3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuc2ZpeGVkMzJPcHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5zZml4ZWQ2NE9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmZsb2F0T3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuZG91YmxlT3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuc3RyaW5nT3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuYnl0ZXNPcHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5lbnVtT3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMubWVzc2FnZVR5cGVPcHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5tb29vKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuY29yZ2UpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5ncmF1bHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5nYXJwbHkpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5jb21wbGV4T3B0MSk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmNvbXBsZXhPcHQyKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuY29tcGxleE9wdDMpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5jb21wbGV4T3B0Nik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmZpbGVvcHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5tc2dvcHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5maWVsZG9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmVudW1vcHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5lbnVtdmFsb3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuc2VydmljZW9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLm1ldGhvZG9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLnJlcXVpcmVkRW51bU9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQuY29tcGxleE9wdDQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudC5tZXNzYWdlU2V0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLm5lc3RlZCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUubmVzdGVkRXh0ZW5zaW9uKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTWV0aG9kT3B0MX0KICAgKi8KICBwdWJsaWMgZW51bSBNZXRob2RPcHQxCiAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgIC8qKgogICAgICogPGNvZGU+TUVUSE9ET1BUMV9WQUwxID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIE1FVEhPRE9QVDFfVkFMMSgxKSwKICAgIC8qKgogICAgICogPGNvZGU+TUVUSE9ET1BUMV9WQUwyID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIE1FVEhPRE9QVDFfVkFMMigyKSwKICAgIDsKCiAgICAvKioKICAgICAqIDxjb2RlPk1FVEhPRE9QVDFfVkFMMSA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVRIT0RPUFQxX1ZBTDFfVkFMVUUgPSAxOwogICAgLyoqCiAgICAgKiA8Y29kZT5NRVRIT0RPUFQxX1ZBTDIgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUVUSE9ET1BUMV9WQUwyX1ZBTFVFID0gMjsKCgogICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIHN0YXRpYyBNZXRob2RPcHQxIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgTWV0aG9kT3B0MSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICBjYXNlIDE6IHJldHVybiBNRVRIT0RPUFQxX1ZBTDE7CiAgICAgICAgY2FzZSAyOiByZXR1cm4gTUVUSE9ET1BUMV9WQUwyOwogICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE1ldGhvZE9wdDE+CiAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgIE1ldGhvZE9wdDE+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TWV0aG9kT3B0MT4oKSB7CiAgICAgICAgICAgIHB1YmxpYyBNZXRob2RPcHQxIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gTWV0aG9kT3B0MS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKCiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgfQogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBNZXRob2RPcHQxW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgcHVibGljIHN0YXRpYyBNZXRob2RPcHQxIHZhbHVlT2YoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgIH0KICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgfQoKICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgIHByaXZhdGUgTWV0aG9kT3B0MShpbnQgdmFsdWUpIHsKICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk1ldGhvZE9wdDEpCiAgfQoKICAvKioKICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVFbnVtfQogICAqLwogIHB1YmxpYyBlbnVtIEFnZ3JlZ2F0ZUVudW0KICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgLyoqCiAgICAgKiA8Y29kZT5WQUxVRSA9IDEgWygucHJvdG9idWZfdW5pdHRlc3QuZW51bXZhbG9wdCkgPSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBWQUxVRSgxKSwKICAgIDsKCiAgICAvKioKICAgICAqIDxjb2RlPlZBTFVFID0gMSBbKC5wcm90b2J1Zl91bml0dGVzdC5lbnVtdmFsb3B0KSA9IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFX1ZBTFVFID0gMTsKCgogICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIHN0YXRpYyBBZ2dyZWdhdGVFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgQWdncmVnYXRlRW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICBjYXNlIDE6IHJldHVybiBWQUxVRTsKICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxBZ2dyZWdhdGVFbnVtPgogICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICBBZ2dyZWdhdGVFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPEFnZ3JlZ2F0ZUVudW0+KCkgewogICAgICAgICAgICBwdWJsaWMgQWdncmVnYXRlRW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIEFnZ3JlZ2F0ZUVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgIH0KICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMSk7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQWdncmVnYXRlRW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgIHB1YmxpYyBzdGF0aWMgQWdncmVnYXRlRW51bSB2YWx1ZU9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICB9CiAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICBwcml2YXRlIEFnZ3JlZ2F0ZUVudW0oaW50IHZhbHVlKSB7CiAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVFbnVtKQogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGQxID0gMSBbY3R5cGUgPSBDT1JELCAoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdDEpID0gODc2NTQzMjEwOV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGQxID0gMSBbY3R5cGUgPSBDT1JELCAoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdDEpID0gODc2NTQzMjEwOV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGQxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGQxID0gMSBbY3R5cGUgPSBDT1JELCAoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdDEpID0gODc2NTQzMjEwOV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0RmllbGQxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIG9uZW9mX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09uZW9mRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgb25lb2ZfZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mRmllbGQuCiAgICAgKi8KICAgIGludCBnZXRPbmVvZkZpZWxkKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9maWVsZCA9IDMgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSAxMjM0NV07PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0TWFwRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9maWVsZCA9IDMgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSAxMjM0NV07PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zTWFwRmllbGQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBGaWVsZE1hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldE1hcEZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX2ZpZWxkID0gMyBbKC5wcm90b2J1Zl91bml0dGVzdC5maWVsZF9vcHQxKSA9IDEyMzQ1XTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldE1hcEZpZWxkTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX2ZpZWxkID0gMyBbKC5wcm90b2J1Zl91bml0dGVzdC5maWVsZF9vcHQxKSA9IDEyMzQ1XTs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0TWFwRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9maWVsZCA9IDMgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSAxMjM0NV07PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE1hcEZpZWxkT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMuQW5PbmVvZkNhc2UgZ2V0QW5PbmVvZkNhc2UoKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBBIHRlc3QgbWVzc2FnZSB3aXRoIGN1c3RvbSBvcHRpb25zIGF0IGFsbCBwb3NzaWJsZSBsb2NhdGlvbnMgKGFuZCBhbHNvIHNvbWUKICAgKiByZWd1bGFyIG9wdGlvbnMsIHRvIG1ha2Ugc3VyZSB0aGV5IGludGVyYWN0IG5pY2VseSkuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zKQogICAgICBUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zKCkgewogICAgICBmaWVsZDFfID0gIiI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkUmVmbGVjdGlvbkFjY2Vzc29yIGludGVybmFsR2V0TWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgIGludCBudW1iZXIpIHsKICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaWVsZCgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgfQogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucy5BbkVudW19CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIEFuRW51bQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkFORU5VTV9WQUwxID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBBTkVOVU1fVkFMMSgxKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkFORU5VTV9WQUwyID0gMiBbKC5wcm90b2J1Zl91bml0dGVzdC5lbnVtX3ZhbHVlX29wdDEpID0gMTIzXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBBTkVOVU1fVkFMMigyKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkFORU5VTV9WQUwxID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTkVOVU1fVkFMMV9WQUxVRSA9IDE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BTkVOVU1fVkFMMiA9IDIgWygucHJvdG9idWZfdW5pdHRlc3QuZW51bV92YWx1ZV9vcHQxKSA9IDEyM107PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU5FTlVNX1ZBTDJfVkFMVUUgPSAyOwoKCiAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgQW5FbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBBbkVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIEFORU5VTV9WQUwxOwogICAgICAgICAgY2FzZSAyOiByZXR1cm4gQU5FTlVNX1ZBTDI7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxBbkVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBBbkVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxBbkVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBBbkVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIEFuRW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFuRW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBBbkVudW0gdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBBbkVudW0oaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zLkFuRW51bSkKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHJpdmF0ZSBpbnQgYW5PbmVvZkNhc2VfID0gMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGFuT25lb2ZfOwogICAgcHVibGljIGVudW0gQW5PbmVvZkNhc2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkludGVybmFsT25lT2ZFbnVtIHsKICAgICAgT05FT0ZfRklFTEQoMiksCiAgICAgIEFOT05FT0ZfTk9UX1NFVCgwKTsKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CiAgICAgIHByaXZhdGUgQW5PbmVvZkNhc2UoaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWJlciBvZiB0aGUgZW51bSB0byBsb29rIGZvci4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWJlci4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBBbk9uZW9mQ2FzZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIEFuT25lb2ZDYXNlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDI6IHJldHVybiBPTkVPRl9GSUVMRDsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIEFOT05FT0ZfTk9UX1NFVDsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgQW5PbmVvZkNhc2UKICAgIGdldEFuT25lb2ZDYXNlKCkgewogICAgICByZXR1cm4gQW5PbmVvZkNhc2UuZm9yTnVtYmVyKAogICAgICAgICAgYW5PbmVvZkNhc2VfKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRDFfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGZpZWxkMV8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZpZWxkMSA9IDEgW2N0eXBlID0gQ09SRCwgKC5wcm90b2J1Zl91bml0dGVzdC5maWVsZF9vcHQxKSA9IDg3NjU0MzIxMDldOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGQxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZDEgPSAxIFtjdHlwZSA9IENPUkQsICgucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSA4NzY1NDMyMTA5XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkMSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmaWVsZDFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGZpZWxkMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGQxID0gMSBbY3R5cGUgPSBDT1JELCAoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdDEpID0gODc2NTQzMjEwOV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZpZWxkMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZpZWxkMUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZpZWxkMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGZpZWxkMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9GSUVMRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBvbmVvZl9maWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZkZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZGaWVsZCgpIHsKICAgICAgcmV0dXJuIGFuT25lb2ZDYXNlXyA9PSAyOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBvbmVvZl9maWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZGaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPbmVvZkZpZWxkKCkgewogICAgICBpZiAoYW5PbmVvZkNhc2VfID09IDIpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSBhbk9uZW9mXzsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNQVBfRklFTERfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNfTWFwRmllbGRFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwRmllbGRfOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBpbnRlcm5hbEdldE1hcEZpZWxkKCkgewogICAgICBpZiAobWFwRmllbGRfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICB9CiAgICAgIHJldHVybiBtYXBGaWVsZF87CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcEZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9maWVsZCA9IDMgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSAxMjM0NV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBjb250YWluc01hcEZpZWxkKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcEZpZWxkTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0TWFwRmllbGQoKSB7CiAgICAgIHJldHVybiBnZXRNYXBGaWVsZE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9maWVsZCA9IDMgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSAxMjM0NV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNYXBGaWVsZE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRmllbGQoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfZmllbGQgPSAzIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdDEpID0gMTIzNDVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0TWFwRmllbGRPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9maWVsZCA9IDMgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSAxMjM0NV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRNYXBGaWVsZE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0TWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMSwgZmllbGQxXyk7CiAgICAgIH0KICAgICAgaWYgKGFuT25lb2ZDYXNlXyA9PSAyKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoCiAgICAgICAgICAgIDIsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgYW5PbmVvZl8pKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwRmllbGQoKSwKICAgICAgICAgIE1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDMpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxLCBmaWVsZDFfKTsKICAgICAgfQogICAgICBpZiAoYW5PbmVvZkNhc2VfID09IDIpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKAogICAgICAgICAgICAgIDIsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgYW5PbmVvZl8pKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwRmllbGQoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIG1hcEZpZWxkX18gPSBNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgbWFwRmllbGRfXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zKSBvYmo7CgogICAgICBpZiAoaGFzRmllbGQxKCkgIT0gb3RoZXIuaGFzRmllbGQxKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkMSgpKSB7CiAgICAgICAgaWYgKCFnZXRGaWVsZDEoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmVxdWFscygKICAgICAgICAgIG90aGVyLmludGVybmFsR2V0TWFwRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRBbk9uZW9mQ2FzZSgpLmVxdWFscyhvdGhlci5nZXRBbk9uZW9mQ2FzZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBzd2l0Y2ggKGFuT25lb2ZDYXNlXykgewogICAgICAgIGNhc2UgMjoKICAgICAgICAgIGlmIChnZXRPbmVvZkZpZWxkKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRPbmVvZkZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0ZpZWxkMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTEQxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZDEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1BUF9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgc3dpdGNoIChhbk9uZW9mQ2FzZV8pIHsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPTkVPRl9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPbmVvZkZpZWxkKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQSB0ZXN0IG1lc3NhZ2Ugd2l0aCBjdXN0b20gb3B0aW9ucyBhdCBhbGwgcG9zc2libGUgbG9jYXRpb25zIChhbmQgYWxzbyBzb21lCiAgICAgKiByZWd1bGFyIG9wdGlvbnMsIHRvIG1ha2Ugc3VyZSB0aGV5IGludGVyYWN0IG5pY2VseSkuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE1hcEZpZWxkUmVmbGVjdGlvbigKICAgICAgICAgIGludCBudW1iZXIpIHsKICAgICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaWVsZCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZFJlZmxlY3Rpb25BY2Nlc3NvciBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCk7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGZpZWxkMV8gPSAiIjsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZCgpLmNsZWFyKCk7CiAgICAgICAgYW5PbmVvZkNhc2VfID0gMDsKICAgICAgICBhbk9uZW9mXyA9IG51bGw7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgYnVpbGRQYXJ0aWFsT25lb2ZzKHJlc3VsdCk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkMV8gPSBmaWVsZDFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcEZpZWxkXyA9IGludGVybmFsR2V0TWFwRmllbGQoKTsKICAgICAgICAgIHJlc3VsdC5tYXBGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsT25lb2ZzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIHJlc3VsdCkgewogICAgICAgIHJlc3VsdC5hbk9uZW9mQ2FzZV8gPSBhbk9uZW9mQ2FzZV87CiAgICAgICAgcmVzdWx0LmFuT25lb2ZfID0gdGhpcy5hbk9uZW9mXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkMSgpKSB7CiAgICAgICAgICBmaWVsZDFfID0gb3RoZXIuZmllbGQxXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZCgpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBGaWVsZCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgc3dpdGNoIChvdGhlci5nZXRBbk9uZW9mQ2FzZSgpKSB7CiAgICAgICAgICBjYXNlIE9ORU9GX0ZJRUxEOiB7CiAgICAgICAgICAgIHNldE9uZW9mRmllbGQob3RoZXIuZ2V0T25lb2ZGaWVsZCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEFOT05FT0ZfTk9UX1NFVDogewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgZmllbGQxXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgYW5PbmVvZl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGFuT25lb2ZDYXNlXyA9IDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICAgICAgICBtYXBGaWVsZF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgTWFwRmllbGREZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkucHV0KAogICAgICAgICAgICAgICAgICAgIG1hcEZpZWxkX18uZ2V0S2V5KCksIG1hcEZpZWxkX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBhbk9uZW9mQ2FzZV8gPSAwOwogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgYW5PbmVvZl87CiAgICAgIHB1YmxpYyBBbk9uZW9mQ2FzZQogICAgICAgICAgZ2V0QW5PbmVvZkNhc2UoKSB7CiAgICAgICAgcmV0dXJuIEFuT25lb2ZDYXNlLmZvck51bWJlcigKICAgICAgICAgICAgYW5PbmVvZkNhc2VfKTsKICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBbk9uZW9mKCkgewogICAgICAgIGFuT25lb2ZDYXNlXyA9IDA7CiAgICAgICAgYW5PbmVvZl8gPSBudWxsOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGZpZWxkMV8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZDEgPSAxIFtjdHlwZSA9IENPUkQsICgucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSA4NzY1NDMyMTA5XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZDEgPSAxIFtjdHlwZSA9IENPUkQsICgucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSA4NzY1NDMyMTA5XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZpZWxkMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBmaWVsZDFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZDEgPSAxIFtjdHlwZSA9IENPUkQsICgucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSA4NzY1NDMyMTA5XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBmaWVsZDEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRGaWVsZDFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZpZWxkMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGZpZWxkMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZmllbGQxID0gMSBbY3R5cGUgPSBDT1JELCAoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdDEpID0gODc2NTQzMjEwOV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGZpZWxkMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZDEgPSAxIFtjdHlwZSA9IENPUkQsICgucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSA4NzY1NDMyMTA5XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQxKCkgewogICAgICAgIGZpZWxkMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRGaWVsZDEoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmaWVsZDEgPSAxIFtjdHlwZSA9IENPUkQsICgucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSA4NzY1NDMyMTA5XTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGZpZWxkMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBmaWVsZDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgb25lb2ZfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZkZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGFuT25lb2ZDYXNlXyA9PSAyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBvbmVvZl9maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZkZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRPbmVvZkZpZWxkKCkgewogICAgICAgIGlmIChhbk9uZW9mQ2FzZV8gPT0gMikgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgYW5PbmVvZl87CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBvbmVvZl9maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9uZW9mRmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZkZpZWxkKGludCB2YWx1ZSkgewoKICAgICAgICBhbk9uZW9mQ2FzZV8gPSAyOwogICAgICAgIGFuT25lb2ZfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIG9uZW9mX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZGaWVsZCgpIHsKICAgICAgICBpZiAoYW5PbmVvZkNhc2VfID09IDIpIHsKICAgICAgICAgIGFuT25lb2ZDYXNlXyA9IDA7CiAgICAgICAgICBhbk9uZW9mXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcEZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpZWxkKCkgewogICAgICAgIGlmIChtYXBGaWVsZF8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBGaWVsZERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwRmllbGRfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKSB7CiAgICAgICAgaWYgKG1hcEZpZWxkXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBGaWVsZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE1hcEZpZWxkRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwRmllbGRfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBGaWVsZF8gPSBtYXBGaWVsZF8uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcEZpZWxkXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcEZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwRmllbGQoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX2ZpZWxkID0gMyBbKC5wcm90b2J1Zl91bml0dGVzdC5maWVsZF9vcHQxKSA9IDEyMzQ1XTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwRmllbGRNYXAoKX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldE1hcEZpZWxkKCkgewogICAgICAgIHJldHVybiBnZXRNYXBGaWVsZE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9maWVsZCA9IDMgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSAxMjM0NV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNYXBGaWVsZE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBGaWVsZCgpLmdldE1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9maWVsZCA9IDMgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSAxMjM0NV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRNYXBGaWVsZE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwRmllbGQoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX2ZpZWxkID0gMyBbKC5wcm90b2J1Zl91bml0dGVzdC5maWVsZF9vcHQxKSA9IDEyMzQ1XTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE1hcEZpZWxkT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldE1hcEZpZWxkKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcEZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfZmllbGQgPSAzIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdDEpID0gMTIzNDVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU1hcEZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBGaWVsZCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVNYXBGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcEZpZWxkKCkuZ2V0TXV0YWJsZU1hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9maWVsZCA9IDMgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSAxMjM0NV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX2ZpZWxkID0gMyBbKC5wcm90b2J1Zl91bml0dGVzdC5maWVsZF9vcHQxKSA9IDEyMzQ1XTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxNYXBGaWVsZCgKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGQoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dEFsbCh2YWx1ZXMpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBDdXN0b21PcHRpb25Gb29SZXF1ZXN0T3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogQSB0ZXN0IFJQQyBzZXJ2aWNlIHdpdGggY3VzdG9tIG9wdGlvbnMgYXQgYWxsIHBvc3NpYmxlIGxvY2F0aW9ucyAoYW5kIGFsc28KICAgKiBzb21lIHJlZ3VsYXIgb3B0aW9ucywgdG8gbWFrZSBzdXJlIHRoZXkgaW50ZXJhY3QgbmljZWx5KS4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbkZvb1JlcXVlc3R9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBDdXN0b21PcHRpb25Gb29SZXF1ZXN0IGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QpCiAgICAgIEN1c3RvbU9wdGlvbkZvb1JlcXVlc3RPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEN1c3RvbU9wdGlvbkZvb1JlcXVlc3QubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEN1c3RvbU9wdGlvbkZvb1JlcXVlc3QoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdF9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0LmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1JlcXVlc3Qgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEEgdGVzdCBSUEMgc2VydmljZSB3aXRoIGN1c3RvbSBvcHRpb25zIGF0IGFsbCBwb3NzaWJsZSBsb2NhdGlvbnMgKGFuZCBhbHNvCiAgICAgKiBzb21lIHJlZ3VsYXIgb3B0aW9ucywgdG8gbWFrZSBzdXJlIHRoZXkgaW50ZXJhY3QgbmljZWx5KS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbkZvb1JlcXVlc3R9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25Gb29SZXF1ZXN0KQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0T3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbkZvb1JlcXVlc3RfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0LkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbkZvb1JlcXVlc3RfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdCh0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0KSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0KCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEN1c3RvbU9wdGlvbkZvb1JlcXVlc3Q+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Q3VzdG9tT3B0aW9uRm9vUmVxdWVzdD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEN1c3RvbU9wdGlvbkZvb1JlcXVlc3QgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDdXN0b21PcHRpb25Gb29SZXF1ZXN0PiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEN1c3RvbU9wdGlvbkZvb1JlcXVlc3Q+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UpCiAgICAgIEN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBDdXN0b21PcHRpb25Gb29SZXNwb25zZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBDdXN0b21PcHRpb25Gb29SZXNwb25zZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29SZXNwb25zZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29SZXNwb25zZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25Gb29SZXNwb25zZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDdXN0b21PcHRpb25Gb29SZXNwb25zZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxDdXN0b21PcHRpb25Gb29SZXNwb25zZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q3VzdG9tT3B0aW9uRm9vUmVzcG9uc2U+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q3VzdG9tT3B0aW9uRm9vUmVzcG9uc2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSkKICAgICAgQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBDdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBDdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2UodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBDdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSkKICAgICAgQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBDdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBDdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2UodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEN1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBDdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIER1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIER1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtKQogICAgICBEdW1teU1lc3NhZ2VDb250YWluaW5nRW51bU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0ubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0oY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBEdW1teU1lc3NhZ2VDb250YWluaW5nRW51bSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBEdW1teU1lc3NhZ2VDb250YWluaW5nRW51bSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW1fZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0R1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0uQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bS5UZXN0RW51bVR5cGV9CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIFRlc3RFbnVtVHlwZQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlRFU1RfT1BUSU9OX0VOVU1fVFlQRTEgPSAyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBURVNUX09QVElPTl9FTlVNX1RZUEUxKDIyKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlRFU1RfT1BUSU9OX0VOVU1fVFlQRTIgPSAtMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgVEVTVF9PUFRJT05fRU5VTV9UWVBFMigtMjMpLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+VEVTVF9PUFRJT05fRU5VTV9UWVBFMSA9IDIyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRFU1RfT1BUSU9OX0VOVU1fVFlQRTFfVkFMVUUgPSAyMjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlRFU1RfT1BUSU9OX0VOVU1fVFlQRTIgPSAtMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEVTVF9PUFRJT05fRU5VTV9UWVBFMl9WQUxVRSA9IC0yMzsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIFRlc3RFbnVtVHlwZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgVGVzdEVudW1UeXBlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDIyOiByZXR1cm4gVEVTVF9PUFRJT05fRU5VTV9UWVBFMTsKICAgICAgICAgIGNhc2UgLTIzOiByZXR1cm4gVEVTVF9PUFRJT05fRU5VTV9UWVBFMjsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFRlc3RFbnVtVHlwZT4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIFRlc3RFbnVtVHlwZT4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFRlc3RFbnVtVHlwZT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIFRlc3RFbnVtVHlwZSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gVGVzdEVudW1UeXBlLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgICB9CiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRlc3RFbnVtVHlwZVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBUZXN0RW51bVR5cGUgdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBUZXN0RW51bVR5cGUoaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bS5UZXN0RW51bVR5cGUpCiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0gb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtKSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0gcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0gcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0R1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW1fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0uQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0ubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0R1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0uZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0gcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0gYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0pb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0pCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8RHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBEdW1teU1lc3NhZ2VDb250YWluaW5nRW51bSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPER1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPER1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBEdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBEdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUpCiAgICAgIER1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIER1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIER1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxEdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPER1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBDdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBDdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMpCiAgICAgIEN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxDdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBDdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBDdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMpCiAgICAgIEN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxDdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBDdXN0b21PcHRpb25PdGhlclZhbHVlc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25PdGhlclZhbHVlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBDdXN0b21PcHRpb25PdGhlclZhbHVlcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25PdGhlclZhbHVlcykKICAgICAgQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEN1c3RvbU9wdGlvbk90aGVyVmFsdWVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIEN1c3RvbU9wdGlvbk90aGVyVmFsdWVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXMoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbk90aGVyVmFsdWVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25PdGhlclZhbHVlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcykgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25PdGhlclZhbHVlcykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25PdGhlclZhbHVlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbk90aGVyVmFsdWVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25PdGhlclZhbHVlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXMgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcyh0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25PdGhlclZhbHVlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25PdGhlclZhbHVlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEN1c3RvbU9wdGlvbk90aGVyVmFsdWVzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEN1c3RvbU9wdGlvbk90aGVyVmFsdWVzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDdXN0b21PcHRpb25PdGhlclZhbHVlcz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDdXN0b21PcHRpb25PdGhlclZhbHVlcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbk90aGVyVmFsdWVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50c09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzKQogICAgICBTZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBTZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBTZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzKSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50c19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cyh0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8U2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50cz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxTZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50c09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzKQogICAgICBTZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBTZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBTZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzKSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50c19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cyh0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8U2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50cz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxTZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFNldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgQ29tcGxleE9wdGlvblR5cGUxT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxDb21wbGV4T3B0aW9uVHlwZTE+IHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvbyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb28gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZvbygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb28gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvby4KICAgICAqLwogICAgaW50IGdldEZvbygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb28yIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb28yKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvbzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvbzIuCiAgICAgKi8KICAgIGludCBnZXRGb28yKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb28zID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvbzMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZvbzMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vMy4KICAgICAqLwogICAgaW50IGdldEZvbzMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZvbzQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZvbzQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRGb280TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmb280ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmb280LgogICAgICovCiAgICBpbnQgZ2V0Rm9vNENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZvbzQgPSA0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZm9vNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRGb280KGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIENvbXBsZXhPcHRpb25UeXBlMSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVNZXNzYWdlPAogICAgICAgIENvbXBsZXhPcHRpb25UeXBlMT4gaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMSkKICAgICAgQ29tcGxleE9wdGlvblR5cGUxT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBDb21wbGV4T3B0aW9uVHlwZTEubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgQ29tcGxleE9wdGlvblR5cGUxKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEsID8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIENvbXBsZXhPcHRpb25UeXBlMSgpIHsKICAgICAgZm9vNF8gPSBlbXB0eUludExpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBDb21wbGV4T3B0aW9uVHlwZTEoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlMV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUxX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBmb29fID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvbyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZvbygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb28gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvby4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGb28oKSB7CiAgICAgIHJldHVybiBmb29fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPTzJfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgaW50IGZvbzJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb28yIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb28yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb28yLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZvbzIoKSB7CiAgICAgIHJldHVybiBmb28yXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT08zX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIGludCBmb28zXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvbzMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZvbzMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGb28zKCkgewogICAgICByZXR1cm4gZm9vM187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PNF9GSUVMRF9OVU1CRVIgPSA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBmb280XyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZvbzQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGZvbzQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRGb280TGlzdCgpIHsKICAgICAgcmV0dXJuIGZvbzRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmb280ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBmb280LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldEZvbzRDb3VudCgpIHsKICAgICAgcmV0dXJuIGZvbzRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgZm9vNCA9IDQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBmb280IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRGb280KGludCBpbmRleCkgewogICAgICByZXR1cm4gZm9vNF8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5FeHRlbmRhYmxlTWVzc2FnZTxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxPi5FeHRlbnNpb25Xcml0ZXIKICAgICAgICAgIGV4dGVuc2lvbldyaXRlciA9IG5ld0V4dGVuc2lvbldyaXRlcigpOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBmb29fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyLCBmb28yXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMywgZm9vM18pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZm9vNF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig0LCBmb280Xy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDUzNjg3MDkxMiwgb3V0cHV0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgZm9vXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgyLCBmb28yXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgzLCBmb28zXyk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmb280Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGZvbzRfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0Rm9vNExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBleHRlbnNpb25zU2VyaWFsaXplZFNpemUoKTsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxKSBvYmo7CgogICAgICBpZiAoaGFzRm9vKCkgIT0gb3RoZXIuaGFzRm9vKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZvbygpKSB7CiAgICAgICAgaWYgKGdldEZvbygpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZvbygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZvbzIoKSAhPSBvdGhlci5oYXNGb28yKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZvbzIoKSkgewogICAgICAgIGlmIChnZXRGb28yKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0Rm9vMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZvbzMoKSAhPSBvdGhlci5oYXNGb28zKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZvbzMoKSkgewogICAgICAgIGlmIChnZXRGb28zKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0Rm9vMygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRGb280TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZvbzRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RXh0ZW5zaW9uRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldEV4dGVuc2lvbkZpZWxkcygpKSkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0ZvbygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGb28oKTsKICAgICAgfQogICAgICBpZiAoaGFzRm9vMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Rm9vMigpOwogICAgICB9CiAgICAgIGlmIChoYXNGb28zKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGT08zX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGb28zKCk7CiAgICAgIH0KICAgICAgaWYgKGdldEZvbzRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZPTzRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZvbzRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUxfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMSwgQnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUxKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTFPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTFfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTFfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGZvb18gPSAwOwogICAgICAgIGZvbzJfID0gMDsKICAgICAgICBmb28zXyA9IDA7CiAgICAgICAgZm9vNF8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTFfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZm9vXyA9IGZvb187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZm9vMl8gPSBmb28yXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5mb28zXyA9IGZvbzNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgZm9vNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmZvbzRfID0gZm9vNF87CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEsIFR5cGU+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMSwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMSwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxLCBUPiBleHRlbnNpb24pIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0ZvbygpKSB7CiAgICAgICAgICBzZXRGb28ob3RoZXIuZ2V0Rm9vKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRm9vMigpKSB7CiAgICAgICAgICBzZXRGb28yKG90aGVyLmdldEZvbzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGb28zKCkpIHsKICAgICAgICAgIHNldEZvbzMob3RoZXIuZ2V0Rm9vMygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5mb280Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChmb280Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgZm9vNF8gPSBvdGhlci5mb280XzsKICAgICAgICAgICAgZm9vNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVGb280SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGZvbzRfLmFkZEFsbChvdGhlci5mb280Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIGZvb18gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgZm9vMl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMjQ6IHsKICAgICAgICAgICAgICAgIGZvbzNfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQKICAgICAgICAgICAgICBjYXNlIDMyOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlRm9vNElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZm9vNF8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyCiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVGb280SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGZvbzRfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgZm9vXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb28gPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb28gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb28oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb28gPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZm9vLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZvbygpIHsKICAgICAgICByZXR1cm4gZm9vXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZm9vIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vKGludCB2YWx1ZSkgewoKICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb28gPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb28oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGZvb18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmb28yXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb28yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZvbzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb28yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZvbzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0Rm9vMigpIHsKICAgICAgICByZXR1cm4gZm9vMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvbzIgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb28yIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZm9vMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvbzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb28yKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBmb28yXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZvbzNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvbzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb28zIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvbzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZm9vMy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGb28zKCkgewogICAgICAgIHJldHVybiBmb28zXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZvbzMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb28zKGludCB2YWx1ZSkgewoKICAgICAgICBmb28zXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZvbzMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGZvbzNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgZm9vNF8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUZvbzRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFmb280Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZm9vNF8gPSBtYWtlTXV0YWJsZUNvcHkoZm9vNF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZvbzQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZm9vNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEZvbzRMaXN0KCkgewogICAgICAgIGZvbzRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZm9vNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZvbzQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZm9vNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0Rm9vNENvdW50KCkgewogICAgICAgIHJldHVybiBmb280Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZvbzQgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGZvbzQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRGb280KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmb280Xy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmb280ID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb280IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vNCgKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUZvbzRJc011dGFibGUoKTsKICAgICAgICBmb280Xy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGZvbzQgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb280IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRm9vNChpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlRm9vNElzTXV0YWJsZSgpOwogICAgICAgIGZvbzRfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmb280ID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIGZvbzQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxGb280KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRm9vNElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBmb280Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBmb280ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vNCgpIHsKICAgICAgICBmb280XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPENvbXBsZXhPcHRpb25UeXBlMT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxDb21wbGV4T3B0aW9uVHlwZTE+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBDb21wbGV4T3B0aW9uVHlwZTEgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDb21wbGV4T3B0aW9uVHlwZTE+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q29tcGxleE9wdGlvblR5cGUxPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgQ29tcGxleE9wdGlvblR5cGUyT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxDb21wbGV4T3B0aW9uVHlwZTI+IHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEgYmFyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJhciBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQmFyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEgYmFyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXIuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgZ2V0QmFyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEgYmFyID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTFPckJ1aWxkZXIgZ2V0QmFyT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYXogPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmF6IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNCYXooKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmF6ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXouCiAgICAgKi8KICAgIGludCBnZXRCYXooKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGZyZWQgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZnJlZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRnJlZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBmcmVkID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmcmVkLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBnZXRGcmVkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGZyZWQgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTRPckJ1aWxkZXIgZ2V0RnJlZE9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgYmFybmV5ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0PiAKICAgICAgICBnZXRCYXJuZXlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGJhcm5leSA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBnZXRCYXJuZXkoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgYmFybmV5ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRCYXJuZXlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBiYXJuZXkgPSA0OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0T3JCdWlsZGVyPiAKICAgICAgICBnZXRCYXJuZXlPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGJhcm5leSA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNE9yQnVpbGRlciBnZXRCYXJuZXlPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQ29tcGxleE9wdGlvblR5cGUyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZU1lc3NhZ2U8CiAgICAgICAgQ29tcGxleE9wdGlvblR5cGUyPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyKQogICAgICBDb21wbGV4T3B0aW9uVHlwZTJPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIENvbXBsZXhPcHRpb25UeXBlMi5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBDb21wbGV4T3B0aW9uVHlwZTIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMiwgPz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgQ29tcGxleE9wdGlvblR5cGUyKCkgewogICAgICBiYXJuZXlfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IENvbXBsZXhPcHRpb25UeXBlMigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUyX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgQ29tcGxleE9wdGlvblR5cGU0T3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHdhbGRvID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgd2FsZG8gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNXYWxkbygpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgd2FsZG8gPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgd2FsZG8uCiAgICAgICAqLwogICAgICBpbnQgZ2V0V2FsZG8oKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBDb21wbGV4T3B0aW9uVHlwZTQgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQpCiAgICAgICAgQ29tcGxleE9wdGlvblR5cGU0T3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgQ29tcGxleE9wdGlvblR5cGU0Lm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgQ29tcGxleE9wdGlvblR5cGU0KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgQ29tcGxleE9wdGlvblR5cGU0KCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IENvbXBsZXhPcHRpb25UeXBlNCgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTJfQ29tcGxleE9wdGlvblR5cGU0X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUyX0NvbXBsZXhPcHRpb25UeXBlNF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFdBTERPX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgaW50IHdhbGRvXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB3YWxkbyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHdhbGRvIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzV2FsZG8oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB3YWxkbyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB3YWxkby4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRXYWxkbygpIHsKICAgICAgICByZXR1cm4gd2FsZG9fOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgd2FsZG9fKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgd2FsZG9fKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQpKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0KSBvYmo7CgogICAgICAgIGlmIChoYXNXYWxkbygpICE9IG90aGVyLmhhc1dhbGRvKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzV2FsZG8oKSkgewogICAgICAgICAgaWYgKGdldFdhbGRvKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRXYWxkbygpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzV2FsZG8oKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgV0FMRE9fRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0V2FsZG8oKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNH0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCkKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0T3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUyX0NvbXBsZXhPcHRpb25UeXBlNF9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTJfQ29tcGxleE9wdGlvblR5cGU0X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICB3YWxkb18gPSAwOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlMl9Db21wbGV4T3B0aW9uVHlwZTRfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0KHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LndhbGRvXyA9IHdhbGRvXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0KSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0KW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc1dhbGRvKCkpIHsKICAgICAgICAgICAgc2V0V2FsZG8ob3RoZXIuZ2V0V2FsZG8oKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgICAgd2FsZG9fID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBpbnQgd2FsZG9fIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB3YWxkbyA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgd2FsZG8gZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNXYWxkbygpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgd2FsZG8gPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSB3YWxkby4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRXYWxkbygpIHsKICAgICAgICAgIHJldHVybiB3YWxkb187CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHdhbGRvID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB3YWxkbyB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFdhbGRvKGludCB2YWx1ZSkgewoKICAgICAgICAgIHdhbGRvXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgd2FsZG8gPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJXYWxkbygpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIHdhbGRvXyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0KQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPENvbXBsZXhPcHRpb25UeXBlND4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPENvbXBsZXhPcHRpb25UeXBlND4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBDb21wbGV4T3B0aW9uVHlwZTQgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDb21wbGV4T3B0aW9uVHlwZTQ+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDb21wbGV4T3B0aW9uVHlwZTQ+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NUExFWF9PUFQ0X0ZJRUxEX05VTUJFUiA9IDc2MzM1NDY7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuTWVzc2FnZU9wdGlvbnMsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlND4gY29tcGxleE9wdDQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAgIDAsCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0LmNsYXNzLAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxIGJhcl87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEgYmFyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJhciBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0JhcigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUxIGJhciA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYmFyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMSBnZXRCYXIoKSB7CiAgICAgIHJldHVybiBiYXJfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxLmdldERlZmF1bHRJbnN0YW5jZSgpIDogYmFyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMSBiYXIgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTFPckJ1aWxkZXIgZ2V0QmFyT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gYmFyXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGJhcl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFaX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGludCBiYXpfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmF6ID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJheiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0JheigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYXogPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJhei4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRCYXooKSB7CiAgICAgIHJldHVybiBiYXpfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZSRURfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgZnJlZF87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGZyZWQgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZnJlZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZyZWQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgZnJlZCA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZnJlZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGdldEZyZWQoKSB7CiAgICAgIHJldHVybiBmcmVkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmcmVkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgZnJlZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTRPckJ1aWxkZXIgZ2V0RnJlZE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGZyZWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZyZWRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUk5FWV9GSUVMRF9OVU1CRVIgPSA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0PiBiYXJuZXlfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBiYXJuZXkgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0PiBnZXRCYXJuZXlMaXN0KCkgewogICAgICByZXR1cm4gYmFybmV5XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgYmFybmV5ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTRPckJ1aWxkZXI+IAogICAgICAgIGdldEJhcm5leU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiBiYXJuZXlfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBiYXJuZXkgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRCYXJuZXlDb3VudCgpIHsKICAgICAgcmV0dXJuIGJhcm5leV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBiYXJuZXkgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGdldEJhcm5leShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGJhcm5leV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgYmFybmV5ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNE9yQnVpbGRlciBnZXRCYXJuZXlPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBiYXJuZXlfLmdldChpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKGhhc0JhcigpKSB7CiAgICAgICAgaWYgKCFnZXRCYXIoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLkV4dGVuZGFibGVNZXNzYWdlPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTI+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgZ2V0QmFyKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIGJhel8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMywgZ2V0RnJlZCgpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJhcm5leV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDQsIGJhcm5leV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCg1MzY4NzA5MTIsIG91dHB1dCk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0QmFyKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMiwgYmF6Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGdldEZyZWQoKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBiYXJuZXlfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQsIGJhcm5leV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIpIG9iajsKCiAgICAgIGlmIChoYXNCYXIoKSAhPSBvdGhlci5oYXNCYXIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQmFyKCkpIHsKICAgICAgICBpZiAoIWdldEJhcigpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0QmFyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0JheigpICE9IG90aGVyLmhhc0JheigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNCYXooKSkgewogICAgICAgIGlmIChnZXRCYXooKQogICAgICAgICAgICAhPSBvdGhlci5nZXRCYXooKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGcmVkKCkgIT0gb3RoZXIuaGFzRnJlZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGcmVkKCkpIHsKICAgICAgICBpZiAoIWdldEZyZWQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZyZWQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldEJhcm5leUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRCYXJuZXlMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RXh0ZW5zaW9uRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldEV4dGVuc2lvbkZpZWxkcygpKSkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0JhcigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkFSX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCYXIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNCYXooKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEJBWl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QmF6KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZyZWQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZSRURfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZyZWQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRCYXJuZXlDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEJBUk5FWV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QmFybmV5TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9IGhhc2hGaWVsZHMoaGFzaCwgZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMiBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIsIEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldEJhckZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0RnJlZEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0QmFybmV5RmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBiYXJfID0gbnVsbDsKICAgICAgICBpZiAoYmFyQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgYmFyQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgYmFyQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBiYXpfID0gMDsKICAgICAgICBmcmVkXyA9IG51bGw7CiAgICAgICAgaWYgKGZyZWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmcmVkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgZnJlZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKGJhcm5leUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGJhcm5leV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJhcm5leV8gPSBudWxsOwogICAgICAgICAgYmFybmV5QnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlMl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIodGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMiByZXN1bHQpIHsKICAgICAgICBpZiAoYmFybmV5QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICAgIGJhcm5leV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChiYXJuZXlfKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJhcm5leV8gPSBiYXJuZXlfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQuYmFybmV5XyA9IGJhcm5leUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmJhcl8gPSBiYXJCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBiYXJfCiAgICAgICAgICAgICAgOiBiYXJCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmJhel8gPSBiYXpfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZyZWRfID0gZnJlZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGZyZWRfCiAgICAgICAgICAgICAgOiBmcmVkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMiwgVHlwZT4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgaW50IGluZGV4LCBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgYWRkRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFQ+IEJ1aWxkZXIgY2xlYXJFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIsIFQ+IGV4dGVuc2lvbikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckV4dGVuc2lvbihleHRlbnNpb24pOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMiBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzQmFyKCkpIHsKICAgICAgICAgIG1lcmdlQmFyKG90aGVyLmdldEJhcigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0JheigpKSB7CiAgICAgICAgICBzZXRCYXoob3RoZXIuZ2V0QmF6KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRnJlZCgpKSB7CiAgICAgICAgICBtZXJnZUZyZWQob3RoZXIuZ2V0RnJlZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGJhcm5leUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIuYmFybmV5Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKGJhcm5leV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgYmFybmV5XyA9IG90aGVyLmJhcm5leV87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZUJhcm5leUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgIGJhcm5leV8uYWRkQWxsKG90aGVyLmJhcm5leV8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLmJhcm5leV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChiYXJuZXlCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBiYXJuZXlCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgYmFybmV5QnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIGJhcm5leV8gPSBvdGhlci5iYXJuZXlfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICAgICAgICBiYXJuZXlCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRCYXJuZXlGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgYmFybmV5QnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIuYmFybmV5Xyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmIChoYXNCYXIoKSkgewogICAgICAgICAgaWYgKCFnZXRCYXIoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0QmFyRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIGJhel8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldEZyZWRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0LlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKGJhcm5leUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlQmFybmV5SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIGJhcm5leV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgYmFybmV5QnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEgYmFyXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxT3JCdWlsZGVyPiBiYXJCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEgYmFyID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmFyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0JhcigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEgYmFyID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJhci4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxIGdldEJhcigpIHsKICAgICAgICBpZiAoYmFyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGJhcl8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBiYXJfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gYmFyQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMSBiYXIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJhcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxIHZhbHVlKSB7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgYmFyXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBiYXJCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUxIGJhciA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmFyKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChiYXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBiYXJfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJhckJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEgYmFyID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUJhcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxIHZhbHVlKSB7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBiYXJfICE9IG51bGwgJiYKICAgICAgICAgICAgYmFyXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEJhckJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYmFyXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBiYXJCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoYmFyXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEgYmFyID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJhcigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgYmFyXyA9IG51bGw7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGJhckJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGJhckJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEgYmFyID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMS5CdWlsZGVyIGdldEJhckJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRCYXJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEgYmFyID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMU9yQnVpbGRlciBnZXRCYXJPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBiYXJCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBiYXJfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBiYXJfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMSBiYXIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRCYXJGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGJhckJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0QmFyKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBiYXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJhckJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiYXpfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJheiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJheiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0JheigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJheiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBiYXouCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0QmF6KCkgewogICAgICAgIHJldHVybiBiYXpfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYXogPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBiYXogdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRCYXooaW50IHZhbHVlKSB7CgogICAgICAgIGJhel8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJheiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJheigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgYmF6XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgZnJlZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNE9yQnVpbGRlcj4gZnJlZEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgZnJlZCA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZyZWQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRnJlZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGZyZWQgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZnJlZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBnZXRGcmVkKCkgewogICAgICAgIGlmIChmcmVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZyZWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZyZWRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZnJlZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGZyZWQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZyZWQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgdmFsdWUpIHsKICAgICAgICBpZiAoZnJlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZnJlZF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZnJlZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGZyZWQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZyZWQoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmcmVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZnJlZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZnJlZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGZyZWQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJlZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCB2YWx1ZSkgewogICAgICAgIGlmIChmcmVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApICYmCiAgICAgICAgICAgIGZyZWRfICE9IG51bGwgJiYKICAgICAgICAgICAgZnJlZF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0RnJlZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZnJlZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgZnJlZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChmcmVkXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGZyZWQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRnJlZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgZnJlZF8gPSBudWxsOwogICAgICAgIGlmIChmcmVkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZnJlZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZyZWRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBmcmVkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQuQnVpbGRlciBnZXRGcmVkQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZyZWRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGZyZWQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNE9yQnVpbGRlciBnZXRGcmVkT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChmcmVkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZyZWRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmcmVkXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZyZWRfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgZnJlZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0LkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0T3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZyZWRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZyZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmcmVkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTRPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRGcmVkKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmcmVkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmcmVkQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQ+IGJhcm5leV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUJhcm5leUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICBiYXJuZXlfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQ+KGJhcm5leV8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0LkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0T3JCdWlsZGVyPiBiYXJuZXlCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBiYXJuZXkgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlND4gZ2V0QmFybmV5TGlzdCgpIHsKICAgICAgICBpZiAoYmFybmV5QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGJhcm5leV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gYmFybmV5QnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGJhcm5leSA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRCYXJuZXlDb3VudCgpIHsKICAgICAgICBpZiAoYmFybmV5QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGJhcm5leV8uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gYmFybmV5QnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGJhcm5leSA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGdldEJhcm5leShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAoYmFybmV5QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGJhcm5leV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGJhcm5leUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgYmFybmV5ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRCYXJuZXkoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IHZhbHVlKSB7CiAgICAgICAgaWYgKGJhcm5leUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlQmFybmV5SXNNdXRhYmxlKCk7CiAgICAgICAgICBiYXJuZXlfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJhcm5leUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGJhcm5leSA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmFybmV5KAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChiYXJuZXlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVCYXJuZXlJc011dGFibGUoKTsKICAgICAgICAgIGJhcm5leV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYmFybmV5QnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgYmFybmV5ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRCYXJuZXkocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgdmFsdWUpIHsKICAgICAgICBpZiAoYmFybmV5QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVCYXJuZXlJc011dGFibGUoKTsKICAgICAgICAgIGJhcm5leV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBiYXJuZXlCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGJhcm5leSA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQmFybmV5KAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCB2YWx1ZSkgewogICAgICAgIGlmIChiYXJuZXlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZUJhcm5leUlzTXV0YWJsZSgpOwogICAgICAgICAgYmFybmV5Xy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBiYXJuZXlCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBiYXJuZXkgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEJhcm5leSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGJhcm5leUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUJhcm5leUlzTXV0YWJsZSgpOwogICAgICAgICAgYmFybmV5Xy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJhcm5leUJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgYmFybmV5ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRCYXJuZXkoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGJhcm5leUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUJhcm5leUlzTXV0YWJsZSgpOwogICAgICAgICAgYmFybmV5Xy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBiYXJuZXlCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBiYXJuZXkgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEJhcm5leSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQ+IHZhbHVlcykgewogICAgICAgIGlmIChiYXJuZXlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVCYXJuZXlJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIGJhcm5leV8pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJhcm5leUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBiYXJuZXkgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQmFybmV5KCkgewogICAgICAgIGlmIChiYXJuZXlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBiYXJuZXlfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJhcm5leUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBiYXJuZXkgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUJhcm5leShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAoYmFybmV5QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlQmFybmV5SXNNdXRhYmxlKCk7CiAgICAgICAgICBiYXJuZXlfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYmFybmV5QnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGJhcm5leSA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0LkJ1aWxkZXIgZ2V0QmFybmV5QnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRCYXJuZXlGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgYmFybmV5ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTRPckJ1aWxkZXIgZ2V0QmFybmV5T3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKGJhcm5leUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBiYXJuZXlfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGJhcm5leUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgYmFybmV5ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0T3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRCYXJuZXlPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChiYXJuZXlCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gYmFybmV5QnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGJhcm5leV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQgYmFybmV5ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQuQnVpbGRlciBhZGRCYXJuZXlCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRCYXJuZXlGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0IGJhcm5leSA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0LkJ1aWxkZXIgYWRkQmFybmV5QnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRCYXJuZXlGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCBiYXJuZXkgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5CdWlsZGVyPiAKICAgICAgICAgICBnZXRCYXJuZXlCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0QmFybmV5RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRCYXJuZXlGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGJhcm5leUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGJhcm5leUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb25UeXBlNCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTRPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBiYXJuZXlfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGJhcm5leV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYmFybmV5QnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDb21wbGV4T3B0aW9uVHlwZTI+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Q29tcGxleE9wdGlvblR5cGUyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQ29tcGxleE9wdGlvblR5cGUyIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q29tcGxleE9wdGlvblR5cGUyPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPENvbXBsZXhPcHRpb25UeXBlMj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIENvbXBsZXhPcHRpb25UeXBlM09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBtb28gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbW9vIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNNb28oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbW9vID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtb28uCiAgICAgKi8KICAgIGludCBnZXRNb28oKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIENvbXBsZXhPcHRpb25UeXBlNSA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY29tcGxleG9wdGlvbnR5cGU1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNDb21wbGV4T3B0aW9uVHlwZTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQ29tcGxleE9wdGlvblR5cGU1ID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY29tcGxleG9wdGlvbnR5cGU1LgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSBnZXRDb21wbGV4T3B0aW9uVHlwZTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQ29tcGxleE9wdGlvblR5cGU1ID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNU9yQnVpbGRlciBnZXRDb21wbGV4T3B0aW9uVHlwZTVPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQ29tcGxleE9wdGlvblR5cGUzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMykKICAgICAgQ29tcGxleE9wdGlvblR5cGUzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBDb21wbGV4T3B0aW9uVHlwZTMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgQ29tcGxleE9wdGlvblR5cGUzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgQ29tcGxleE9wdGlvblR5cGUzKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IENvbXBsZXhPcHRpb25UeXBlMygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgQ29tcGxleE9wdGlvblR5cGU1T3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHBsdWdoID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcGx1Z2ggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNQbHVnaCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgcGx1Z2ggPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcGx1Z2guCiAgICAgICAqLwogICAgICBpbnQgZ2V0UGx1Z2goKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBDb21wbGV4T3B0aW9uVHlwZTUgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUpCiAgICAgICAgQ29tcGxleE9wdGlvblR5cGU1T3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgQ29tcGxleE9wdGlvblR5cGU1Lm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgQ29tcGxleE9wdGlvblR5cGU1KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgQ29tcGxleE9wdGlvblR5cGU1KCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IENvbXBsZXhPcHRpb25UeXBlNSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTNfQ29tcGxleE9wdGlvblR5cGU1X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUzX0NvbXBsZXhPcHRpb25UeXBlNV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBMVUdIX0ZJRUxEX05VTUJFUiA9IDM7CiAgICAgIHByaXZhdGUgaW50IHBsdWdoXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBwbHVnaCA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBsdWdoIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUGx1Z2goKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBwbHVnaCA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBwbHVnaC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRQbHVnaCgpIHsKICAgICAgICByZXR1cm4gcGx1Z2hfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMywgcGx1Z2hfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMywgcGx1Z2hfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUpKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1IG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1KSBvYmo7CgogICAgICAgIGlmIChoYXNQbHVnaCgpICE9IG90aGVyLmhhc1BsdWdoKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzUGx1Z2goKSkgewogICAgICAgICAgaWYgKGdldFBsdWdoKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRQbHVnaCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzUGx1Z2goKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUExVR0hfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGx1Z2goKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1IHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1IHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1IHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1IHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSkKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1T3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUzX0NvbXBsZXhPcHRpb25UeXBlNV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTNfQ29tcGxleE9wdGlvblR5cGU1X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBwbHVnaF8gPSAwOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlM19Db21wbGV4T3B0aW9uVHlwZTVfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1KHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LnBsdWdoXyA9IHBsdWdoXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1KSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1KW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1IG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc1BsdWdoKCkpIHsKICAgICAgICAgICAgc2V0UGx1Z2gob3RoZXIuZ2V0UGx1Z2goKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICAgIHBsdWdoXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCBwbHVnaF8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHBsdWdoID0gMzs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwbHVnaCBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1BsdWdoKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBwbHVnaCA9IDM7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIHBsdWdoLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldFBsdWdoKCkgewogICAgICAgICAgcmV0dXJuIHBsdWdoXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgcGx1Z2ggPSAzOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBsdWdoIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGx1Z2goaW50IHZhbHVlKSB7CgogICAgICAgICAgcGx1Z2hfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBwbHVnaCA9IDM7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBsdWdoKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgcGx1Z2hfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1IERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1IGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q29tcGxleE9wdGlvblR5cGU1PgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Q29tcGxleE9wdGlvblR5cGU1PigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIENvbXBsZXhPcHRpb25UeXBlNSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPENvbXBsZXhPcHRpb25UeXBlNT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPENvbXBsZXhPcHRpb25UeXBlNT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT09fRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IG1vb18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBtb28gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbW9vIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTW9vKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG1vbyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbW9vLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE1vbygpIHsKICAgICAgcmV0dXJuIG1vb187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NUExFWE9QVElPTlRZUEU1X0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1IGNvbXBsZXhPcHRpb25UeXBlNV87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIENvbXBsZXhPcHRpb25UeXBlNSA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY29tcGxleG9wdGlvbnR5cGU1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQ29tcGxleE9wdGlvblR5cGU1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIENvbXBsZXhPcHRpb25UeXBlNSA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvbXBsZXhvcHRpb250eXBlNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1IGdldENvbXBsZXhPcHRpb25UeXBlNSgpIHsKICAgICAgcmV0dXJuIGNvbXBsZXhPcHRpb25UeXBlNV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1LmdldERlZmF1bHRJbnN0YW5jZSgpIDogY29tcGxleE9wdGlvblR5cGU1XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQ29tcGxleE9wdGlvblR5cGU1ID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTVPckJ1aWxkZXIgZ2V0Q29tcGxleE9wdGlvblR5cGU1T3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gY29tcGxleE9wdGlvblR5cGU1XyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjb21wbGV4T3B0aW9uVHlwZTVfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgbW9vXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlR3JvdXAoMiwgZ2V0Q29tcGxleE9wdGlvblR5cGU1KCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIG1vb18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVHcm91cFNpemUoMiwgZ2V0Q29tcGxleE9wdGlvblR5cGU1KCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMykgb2JqOwoKICAgICAgaWYgKGhhc01vbygpICE9IG90aGVyLmhhc01vbygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNNb28oKSkgewogICAgICAgIGlmIChnZXRNb28oKQogICAgICAgICAgICAhPSBvdGhlci5nZXRNb28oKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNDb21wbGV4T3B0aW9uVHlwZTUoKSAhPSBvdGhlci5oYXNDb21wbGV4T3B0aW9uVHlwZTUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQ29tcGxleE9wdGlvblR5cGU1KCkpIHsKICAgICAgICBpZiAoIWdldENvbXBsZXhPcHRpb25UeXBlNSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Q29tcGxleE9wdGlvblR5cGU1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzTW9vKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNT09fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE1vbygpOwogICAgICB9CiAgICAgIGlmIChoYXNDb21wbGV4T3B0aW9uVHlwZTUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIENPTVBMRVhPUFRJT05UWVBFNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Q29tcGxleE9wdGlvblR5cGU1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlM30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldENvbXBsZXhPcHRpb25UeXBlNUZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgbW9vXyA9IDA7CiAgICAgICAgY29tcGxleE9wdGlvblR5cGU1XyA9IG51bGw7CiAgICAgICAgaWYgKGNvbXBsZXhPcHRpb25UeXBlNUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGNvbXBsZXhPcHRpb25UeXBlNUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGNvbXBsZXhPcHRpb25UeXBlNUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMyBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMyByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1vb18gPSBtb29fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNvbXBsZXhPcHRpb25UeXBlNV8gPSBjb21wbGV4T3B0aW9uVHlwZTVCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBjb21wbGV4T3B0aW9uVHlwZTVfCiAgICAgICAgICAgICAgOiBjb21wbGV4T3B0aW9uVHlwZTVCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNNb28oKSkgewogICAgICAgICAgc2V0TW9vKG90aGVyLmdldE1vbygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0NvbXBsZXhPcHRpb25UeXBlNSgpKSB7CiAgICAgICAgICBtZXJnZUNvbXBsZXhPcHRpb25UeXBlNShvdGhlci5nZXRDb21wbGV4T3B0aW9uVHlwZTUoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgbW9vXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE5OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkR3JvdXAoMiwKICAgICAgICAgICAgICAgICAgICBnZXRDb21wbGV4T3B0aW9uVHlwZTVGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE5CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IG1vb18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbW9vID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbW9vIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzTW9vKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbW9vID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG1vby4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRNb28oKSB7CiAgICAgICAgcmV0dXJuIG1vb187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG1vbyA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG1vbyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE1vbyhpbnQgdmFsdWUpIHsKCiAgICAgICAgbW9vXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbW9vID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTW9vKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBtb29fID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSBjb21wbGV4T3B0aW9uVHlwZTVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTVPckJ1aWxkZXI+IGNvbXBsZXhPcHRpb25UeXBlNUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQ29tcGxleE9wdGlvblR5cGU1ID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNvbXBsZXhvcHRpb250eXBlNSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNDb21wbGV4T3B0aW9uVHlwZTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBDb21wbGV4T3B0aW9uVHlwZTUgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvbXBsZXhvcHRpb250eXBlNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSBnZXRDb21wbGV4T3B0aW9uVHlwZTUoKSB7CiAgICAgICAgaWYgKGNvbXBsZXhPcHRpb25UeXBlNUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb21wbGV4T3B0aW9uVHlwZTVfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNvbXBsZXhPcHRpb25UeXBlNV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBjb21wbGV4T3B0aW9uVHlwZTVCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBDb21wbGV4T3B0aW9uVHlwZTUgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDb21wbGV4T3B0aW9uVHlwZTUocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUgdmFsdWUpIHsKICAgICAgICBpZiAoY29tcGxleE9wdGlvblR5cGU1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBjb21wbGV4T3B0aW9uVHlwZTVfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNvbXBsZXhPcHRpb25UeXBlNUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIENvbXBsZXhPcHRpb25UeXBlNSA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENvbXBsZXhPcHRpb25UeXBlNSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGNvbXBsZXhPcHRpb25UeXBlNUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGNvbXBsZXhPcHRpb25UeXBlNV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY29tcGxleE9wdGlvblR5cGU1QnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQ29tcGxleE9wdGlvblR5cGU1ID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VDb21wbGV4T3B0aW9uVHlwZTUocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUgdmFsdWUpIHsKICAgICAgICBpZiAoY29tcGxleE9wdGlvblR5cGU1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApICYmCiAgICAgICAgICAgIGNvbXBsZXhPcHRpb25UeXBlNV8gIT0gbnVsbCAmJgogICAgICAgICAgICBjb21wbGV4T3B0aW9uVHlwZTVfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1LmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldENvbXBsZXhPcHRpb25UeXBlNUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY29tcGxleE9wdGlvblR5cGU1XyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjb21wbGV4T3B0aW9uVHlwZTVCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoY29tcGxleE9wdGlvblR5cGU1XyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIENvbXBsZXhPcHRpb25UeXBlNSA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ29tcGxleE9wdGlvblR5cGU1KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBjb21wbGV4T3B0aW9uVHlwZTVfID0gbnVsbDsKICAgICAgICBpZiAoY29tcGxleE9wdGlvblR5cGU1QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgY29tcGxleE9wdGlvblR5cGU1QnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgY29tcGxleE9wdGlvblR5cGU1QnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQ29tcGxleE9wdGlvblR5cGU1ID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1LkJ1aWxkZXIgZ2V0Q29tcGxleE9wdGlvblR5cGU1QnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldENvbXBsZXhPcHRpb25UeXBlNUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQ29tcGxleE9wdGlvblR5cGU1ID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1T3JCdWlsZGVyIGdldENvbXBsZXhPcHRpb25UeXBlNU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoY29tcGxleE9wdGlvblR5cGU1QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbXBsZXhPcHRpb25UeXBlNUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGNvbXBsZXhPcHRpb25UeXBlNV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjb21wbGV4T3B0aW9uVHlwZTVfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQ29tcGxleE9wdGlvblR5cGU1ID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1LkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuQ29tcGxleE9wdGlvblR5cGU1T3JCdWlsZGVyPiAKICAgICAgICAgIGdldENvbXBsZXhPcHRpb25UeXBlNUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoY29tcGxleE9wdGlvblR5cGU1QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgY29tcGxleE9wdGlvblR5cGU1QnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLkNvbXBsZXhPcHRpb25UeXBlNSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTUuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uVHlwZTVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRDb21wbGV4T3B0aW9uVHlwZTUoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGNvbXBsZXhPcHRpb25UeXBlNV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tcGxleE9wdGlvblR5cGU1QnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUzKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxDb21wbGV4T3B0aW9uVHlwZTM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Q29tcGxleE9wdGlvblR5cGUzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQ29tcGxleE9wdGlvblR5cGUzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q29tcGxleE9wdGlvblR5cGUzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPENvbXBsZXhPcHRpb25UeXBlMz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIENvbXBsZXhPcHQ2T3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHQ2KQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgeHl6enkgPSA3NTkzOTUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgeHl6enkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1h5enp5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHh5enp5ID0gNzU5Mzk1MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSB4eXp6eS4KICAgICAqLwogICAgaW50IGdldFh5enp5KCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHQ2fQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQ29tcGxleE9wdDYgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdDYpCiAgICAgIENvbXBsZXhPcHQ2T3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBDb21wbGV4T3B0Ni5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBDb21wbGV4T3B0Nihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIENvbXBsZXhPcHQ2KCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IENvbXBsZXhPcHQ2KCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0Nl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdDZfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0Ni5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgWFlaWllfRklFTERfTlVNQkVSID0gNzU5Mzk1MTsKICAgIHByaXZhdGUgaW50IHh5enp5XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHh5enp5ID0gNzU5Mzk1MTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHh5enp5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzWHl6enkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgeHl6enkgPSA3NTkzOTUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHh5enp5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFh5enp5KCkgewogICAgICByZXR1cm4geHl6enlfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNzU5Mzk1MSwgeHl6enlfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg3NTkzOTUxLCB4eXp6eV8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0NikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHQ2IG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0Nikgb2JqOwoKICAgICAgaWYgKGhhc1h5enp5KCkgIT0gb3RoZXIuaGFzWHl6enkoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzWHl6enkoKSkgewogICAgICAgIGlmIChnZXRYeXp6eSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldFh5enp5KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNYeXp6eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgWFlaWllfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFh5enp5KCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0NiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0NiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0NiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHQ2IHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0NiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0NiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHQ2IHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHQ2IHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHQ2fQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdDYpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHQ2T3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdDZfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0Nl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0Ni5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0Ni5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgeHl6enlfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0Nl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHQ2LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHQ2IHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHQ2IGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0Nih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQueHl6enlfID0geHl6enlfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHQ2KSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHQ2IG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0Ni5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc1h5enp5KCkpIHsKICAgICAgICAgIHNldFh5enp5KG90aGVyLmdldFh5enp5KCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDYwNzUxNjA4OiB7CiAgICAgICAgICAgICAgICB4eXp6eV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MDc1MTYwOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCB4eXp6eV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgeHl6enkgPSA3NTkzOTUxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB4eXp6eSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1h5enp5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgeHl6enkgPSA3NTkzOTUxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgeHl6enkuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0WHl6enkoKSB7CiAgICAgICAgcmV0dXJuIHh5enp5XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgeHl6enkgPSA3NTkzOTUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB4eXp6eSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFh5enp5KGludCB2YWx1ZSkgewoKICAgICAgICB4eXp6eV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHh5enp5ID0gNzU5Mzk1MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyWHl6enkoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHh5enp5XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdDYpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHQ2KQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHQ2IERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0NigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHQ2IGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Q29tcGxleE9wdDY+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Q29tcGxleE9wdDY+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBDb21wbGV4T3B0NiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPENvbXBsZXhPcHQ2PiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPENvbXBsZXhPcHQ2PiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBWYXJpb3VzQ29tcGxleE9wdGlvbnNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVmFyaW91c0NvbXBsZXhPcHRpb25zKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiA8cHJlPgogICAqIE5vdGUgdGhhdCB3ZSB0cnkgdmFyaW91cyBkaWZmZXJlbnQgd2F5cyBvZiBuYW1pbmcgdGhlIHNhbWUgZXh0ZW5zaW9uLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVmFyaW91c0NvbXBsZXhPcHRpb25zfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVmFyaW91c0NvbXBsZXhPcHRpb25zIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlZhcmlvdXNDb21wbGV4T3B0aW9ucykKICAgICAgVmFyaW91c0NvbXBsZXhPcHRpb25zT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBWYXJpb3VzQ29tcGxleE9wdGlvbnMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVmFyaW91c0NvbXBsZXhPcHRpb25zKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVmFyaW91c0NvbXBsZXhPcHRpb25zKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFZhcmlvdXNDb21wbGV4T3B0aW9ucygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVmFyaW91c0NvbXBsZXhPcHRpb25zX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9WYXJpb3VzQ29tcGxleE9wdGlvbnNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5WYXJpb3VzQ29tcGxleE9wdGlvbnMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5WYXJpb3VzQ29tcGxleE9wdGlvbnMgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlZhcmlvdXNDb21wbGV4T3B0aW9ucykgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlZhcmlvdXNDb21wbGV4T3B0aW9ucyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlZhcmlvdXNDb21wbGV4T3B0aW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlZhcmlvdXNDb21wbGV4T3B0aW9ucyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5WYXJpb3VzQ29tcGxleE9wdGlvbnMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlZhcmlvdXNDb21wbGV4T3B0aW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOb3RlIHRoYXQgd2UgdHJ5IHZhcmlvdXMgZGlmZmVyZW50IHdheXMgb2YgbmFtaW5nIHRoZSBzYW1lIGV4dGVuc2lvbi4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlZhcmlvdXNDb21wbGV4T3B0aW9uc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlZhcmlvdXNDb21wbGV4T3B0aW9ucykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVmFyaW91c0NvbXBsZXhPcHRpb25zX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVmFyaW91c0NvbXBsZXhPcHRpb25zX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5WYXJpb3VzQ29tcGxleE9wdGlvbnMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5WYXJpb3VzQ29tcGxleE9wdGlvbnMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9WYXJpb3VzQ29tcGxleE9wdGlvbnNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlZhcmlvdXNDb21wbGV4T3B0aW9ucyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5WYXJpb3VzQ29tcGxleE9wdGlvbnMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlZhcmlvdXNDb21wbGV4T3B0aW9ucykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlZhcmlvdXNDb21wbGV4T3B0aW9ucylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5WYXJpb3VzQ29tcGxleE9wdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlZhcmlvdXNDb21wbGV4T3B0aW9ucykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVmFyaW91c0NvbXBsZXhPcHRpb25zKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlZhcmlvdXNDb21wbGV4T3B0aW9ucyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVmFyaW91c0NvbXBsZXhPcHRpb25zIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VmFyaW91c0NvbXBsZXhPcHRpb25zPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFZhcmlvdXNDb21wbGV4T3B0aW9ucz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFZhcmlvdXNDb21wbGV4T3B0aW9ucyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFZhcmlvdXNDb21wbGV4T3B0aW9ucz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxWYXJpb3VzQ29tcGxleE9wdGlvbnM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5WYXJpb3VzQ29tcGxleE9wdGlvbnMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBBZ2dyZWdhdGVNZXNzYWdlU2V0T3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLgogICAgICAgICAgRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXI8QWdncmVnYXRlTWVzc2FnZVNldD4gewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0fQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQWdncmVnYXRlTWVzc2FnZVNldCBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVNZXNzYWdlPAogICAgICAgIEFnZ3JlZ2F0ZU1lc3NhZ2VTZXQ+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0KQogICAgICBBZ2dyZWdhdGVNZXNzYWdlU2V0T3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBBZ2dyZWdhdGVNZXNzYWdlU2V0Lm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIEFnZ3JlZ2F0ZU1lc3NhZ2VTZXQoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQsID8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEFnZ3JlZ2F0ZU1lc3NhZ2VTZXQoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgQWdncmVnYXRlTWVzc2FnZVNldCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZVNldF9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZVNldF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0LmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5FeHRlbmRhYmxlTWVzc2FnZTxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldD4uRXh0ZW5zaW9uV3JpdGVyCiAgICAgICAgICBleHRlbnNpb25Xcml0ZXIgPSBuZXdNZXNzYWdlU2V0RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDIxNDc0ODM2NDcsIG91dHB1dCk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZUFzTWVzc2FnZVNldFRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZUFzTWVzc2FnZVNldCgpOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZUFzTWVzc2FnZVNldCgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RXh0ZW5zaW9uRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldEV4dGVuc2lvbkZpZWxkcygpKSkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9IGhhc2hGaWVsZHMoaGFzaCwgZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0IHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0fQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQsIEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9BZ2dyZWdhdGVNZXNzYWdlU2V0X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZVNldF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldC5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZVNldF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0KHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCwgVHlwZT4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VD4gQnVpbGRlciBjbGVhckV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQsIFQ+IGV4dGVuc2lvbikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckV4dGVuc2lvbihleHRlbnNpb24pOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0KSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0KQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0KQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0IGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8QWdncmVnYXRlTWVzc2FnZVNldD4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxBZ2dyZWdhdGVNZXNzYWdlU2V0PigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQWdncmVnYXRlTWVzc2FnZVNldCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEFnZ3JlZ2F0ZU1lc3NhZ2VTZXQ+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8QWdncmVnYXRlTWVzc2FnZVNldD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBBZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1MoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHMuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFNCeXRlcygpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50KQogICAgICBBZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBBZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCgpIHsKICAgICAgc18gPSAiIjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBBZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnRfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50LmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHNfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxLCBzXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMSwgc18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCkgb2JqOwoKICAgICAgaWYgKGhhc1MoKSAhPSBvdGhlci5oYXNTKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1MoKSkgewogICAgICAgIGlmICghZ2V0UygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc1MoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50KQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50LmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHNfID0gIiI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnNfID0gc187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50LmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzUygpKSB7CiAgICAgICAgICBzXyA9IG90aGVyLnNfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIHNfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHNfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzUygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igcy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHMgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTKCkgewogICAgICAgIHNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0UygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHMgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50KQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50IGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8QWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQ+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8QWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQ+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBBZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50PiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50PiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUVTU0FHRV9TRVRfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDE1NDQ3NTQyOwogICAgLyoqCiAgICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0LAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudD4gbWVzc2FnZVNldEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudC5nZXREZWZhdWx0SW5zdGFuY2UoKSwKICAgICAgICAgIDAsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQuY2xhc3MsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIH0KCiAgcHVibGljIGludGVyZmFjZSBBZ2dyZWdhdGVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNJKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGkgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGkuCiAgICAgKi8KICAgIGludCBnZXRJKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHMgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBIG5lc3RlZCBvYmplY3QKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGUgc3ViID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN1YiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3ViKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBIG5lc3RlZCBvYmplY3QKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGUgc3ViID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdWIuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUgZ2V0U3ViKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBIG5lc3RlZCBvYmplY3QKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGUgc3ViID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVPckJ1aWxkZXIgZ2V0U3ViT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVG8gdGVzdCB0aGUgcGFyc2luZyBvZiBleHRlbnNpb25zIGluc2lkZSBhZ2dyZWdhdGUgdmFsdWVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIGZpbGUgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmlsZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmlsZSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVG8gdGVzdCB0aGUgcGFyc2luZyBvZiBleHRlbnNpb25zIGluc2lkZSBhZ2dyZWdhdGUgdmFsdWVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIGZpbGUgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpbGUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5GaWxlT3B0aW9ucyBnZXRGaWxlKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUbyB0ZXN0IHRoZSBwYXJzaW5nIG9mIGV4dGVuc2lvbnMgaW5zaWRlIGFnZ3JlZ2F0ZSB2YWx1ZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgZmlsZSA9IDQ7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmlsZU9wdGlvbnNPckJ1aWxkZXIgZ2V0RmlsZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFuIGVtYmVkZGVkIG1lc3NhZ2Ugc2V0CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZVNldCBtc2V0ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1zZXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc01zZXQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFuIGVtYmVkZGVkIG1lc3NhZ2Ugc2V0CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZVNldCBtc2V0ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtc2V0LgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCBnZXRNc2V0KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBbiBlbWJlZGRlZCBtZXNzYWdlIHNldAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgbXNldCA9IDU7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldE9yQnVpbGRlciBnZXRNc2V0T3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQW4gYW55CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnkgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYW55IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNBbnkoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFuIGFueQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhbnkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGdldEFueSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQW4gYW55CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnkgPSA2OzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIgZ2V0QW55T3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogQSBoZWxwZXIgdHlwZSB1c2VkIHRvIHRlc3QgYWdncmVnYXRlIG9wdGlvbiBwYXJzaW5nCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBBZ2dyZWdhdGUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlKQogICAgICBBZ2dyZWdhdGVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEFnZ3JlZ2F0ZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBBZ2dyZWdhdGUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBBZ2dyZWdhdGUoKSB7CiAgICAgIHNfID0gIiI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgQWdncmVnYXRlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9BZ2dyZWdhdGVfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IGlfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzSSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEkoKSB7CiAgICAgIHJldHVybiBpXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBzXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBzXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFNCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVUJfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSBzdWJfOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQSBuZXN0ZWQgb2JqZWN0CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlIHN1YiA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdWIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdWIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEEgbmVzdGVkIG9iamVjdAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZSBzdWIgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN1Yi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUgZ2V0U3ViKCkgewogICAgICByZXR1cm4gc3ViXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHN1Yl87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBIG5lc3RlZCBvYmplY3QKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGUgc3ViID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlT3JCdWlsZGVyIGdldFN1Yk9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHN1Yl8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJTEVfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zIGZpbGVfOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVG8gdGVzdCB0aGUgcGFyc2luZyBvZiBleHRlbnNpb25zIGluc2lkZSBhZ2dyZWdhdGUgdmFsdWVzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIGZpbGUgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmlsZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpbGUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRvIHRlc3QgdGhlIHBhcnNpbmcgb2YgZXh0ZW5zaW9ucyBpbnNpZGUgYWdncmVnYXRlIHZhbHVlcwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyBmaWxlID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWxlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zIGdldEZpbGUoKSB7CiAgICAgIHJldHVybiBmaWxlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmlsZV87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUbyB0ZXN0IHRoZSBwYXJzaW5nIG9mIGV4dGVuc2lvbnMgaW5zaWRlIGFnZ3JlZ2F0ZSB2YWx1ZXMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgZmlsZSA9IDQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zT3JCdWlsZGVyIGdldEZpbGVPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBmaWxlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmlsZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTVNFVF9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCBtc2V0XzsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFuIGVtYmVkZGVkIG1lc3NhZ2Ugc2V0CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZVNldCBtc2V0ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1zZXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNNc2V0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBbiBlbWJlZGRlZCBtZXNzYWdlIHNldAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgbXNldCA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbXNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0IGdldE1zZXQoKSB7CiAgICAgIHJldHVybiBtc2V0XyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtc2V0XzsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFuIGVtYmVkZGVkIG1lc3NhZ2Ugc2V0CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZVNldCBtc2V0ID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldE9yQnVpbGRlciBnZXRNc2V0T3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gbXNldF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0LmdldERlZmF1bHRJbnN0YW5jZSgpIDogbXNldF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQU5ZX0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGFueV87CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBbiBhbnkKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuQW55IGFueSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhbnkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNBbnkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFuIGFueQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhbnkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSBnZXRBbnkoKSB7CiAgICAgIHJldHVybiBhbnlfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGFueV87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBbiBhbnkKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuQW55IGFueSA9IDY7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXIgZ2V0QW55T3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gYW55XyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBhbnlfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmIChoYXNTdWIoKSkgewogICAgICAgIGlmICghZ2V0U3ViKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoaGFzRmlsZSgpKSB7CiAgICAgICAgaWYgKCFnZXRGaWxlKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoaGFzTXNldCgpKSB7CiAgICAgICAgaWYgKCFnZXRNc2V0KCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGlfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDIsIHNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDMsIGdldFN1YigpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDQsIGdldEZpbGUoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg1LCBnZXRNc2V0KCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNiwgZ2V0QW55KCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIGlfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDIsIHNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgZ2V0U3ViKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBnZXRGaWxlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1LCBnZXRNc2V0KCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2LCBnZXRBbnkoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlKSBvYmo7CgogICAgICBpZiAoaGFzSSgpICE9IG90aGVyLmhhc0koKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzSSgpKSB7CiAgICAgICAgaWYgKGdldEkoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRJKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUygpICE9IG90aGVyLmhhc1MoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUygpKSB7CiAgICAgICAgaWYgKCFnZXRTKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1N1YigpICE9IG90aGVyLmhhc1N1YigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTdWIoKSkgewogICAgICAgIGlmICghZ2V0U3ViKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdWIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmlsZSgpICE9IG90aGVyLmhhc0ZpbGUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmlsZSgpKSB7CiAgICAgICAgaWYgKCFnZXRGaWxlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWxlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc01zZXQoKSAhPSBvdGhlci5oYXNNc2V0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc01zZXQoKSkgewogICAgICAgIGlmICghZ2V0TXNldCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TXNldCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNBbnkoKSAhPSBvdGhlci5oYXNBbnkoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQW55KCkpIHsKICAgICAgICBpZiAoIWdldEFueSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0QW55KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzSSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0SSgpOwogICAgICB9CiAgICAgIGlmIChoYXNTKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3ViKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVUJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN1YigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpbGUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJTEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpbGUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNNc2V0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNU0VUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRNc2V0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzQW55KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBBTllfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEFueSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQSBoZWxwZXIgdHlwZSB1c2VkIHRvIHRlc3QgYWdncmVnYXRlIG9wdGlvbiBwYXJzaW5nCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGUpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRTdWJGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldEZpbGVGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldE1zZXRGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldEFueUZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaV8gPSAwOwogICAgICAgIHNfID0gIiI7CiAgICAgICAgc3ViXyA9IG51bGw7CiAgICAgICAgaWYgKHN1YkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHN1YkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHN1YkJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZmlsZV8gPSBudWxsOwogICAgICAgIGlmIChmaWxlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZmlsZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZpbGVCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG1zZXRfID0gbnVsbDsKICAgICAgICBpZiAobXNldEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1zZXRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBtc2V0QnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBhbnlfID0gbnVsbDsKICAgICAgICBpZiAoYW55QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgYW55QnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgYW55QnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9BZ2dyZWdhdGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaV8gPSBpXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zXyA9IHNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN1Yl8gPSBzdWJCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBzdWJfCiAgICAgICAgICAgICAgOiBzdWJCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpbGVfID0gZmlsZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGZpbGVfCiAgICAgICAgICAgICAgOiBmaWxlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5tc2V0XyA9IG1zZXRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBtc2V0XwogICAgICAgICAgICAgIDogbXNldEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuYW55XyA9IGFueUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGFueV8KICAgICAgICAgICAgICA6IGFueUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0koKSkgewogICAgICAgICAgc2V0SShvdGhlci5nZXRJKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUygpKSB7CiAgICAgICAgICBzXyA9IG90aGVyLnNfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdWIoKSkgewogICAgICAgICAgbWVyZ2VTdWIob3RoZXIuZ2V0U3ViKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmlsZSgpKSB7CiAgICAgICAgICBtZXJnZUZpbGUob3RoZXIuZ2V0RmlsZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc01zZXQoKSkgewogICAgICAgICAgbWVyZ2VNc2V0KG90aGVyLmdldE1zZXQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNBbnkoKSkgewogICAgICAgICAgbWVyZ2VBbnkob3RoZXIuZ2V0QW55KCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKGhhc1N1YigpKSB7CiAgICAgICAgICBpZiAoIWdldFN1YigpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChoYXNGaWxlKCkpIHsKICAgICAgICAgIGlmICghZ2V0RmlsZSgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChoYXNNc2V0KCkpIHsKICAgICAgICAgIGlmICghZ2V0TXNldCgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBpXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBzXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0U3ViRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldEZpbGVGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0TXNldEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRBbnlGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGlfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGkgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzSSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGkgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgaS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJKCkgewogICAgICAgIHJldHVybiBpXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRJKGludCB2YWx1ZSkgewoKICAgICAgICBpXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckkoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGlfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHNfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcyA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzUygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcyA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igcy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFNCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFMoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHMgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTKCkgewogICAgICAgIHNfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0UygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHMgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSBzdWJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVPckJ1aWxkZXI+IHN1YkJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQSBuZXN0ZWQgb2JqZWN0CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlIHN1YiA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN1YiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdWIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBIG5lc3RlZCBvYmplY3QKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGUgc3ViID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN1Yi4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlIGdldFN1YigpIHsKICAgICAgICBpZiAoc3ViQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHN1Yl8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gc3ViQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQSBuZXN0ZWQgb2JqZWN0CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlIHN1YiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3ViKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUgdmFsdWUpIHsKICAgICAgICBpZiAoc3ViQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBzdWJfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1YkJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEEgbmVzdGVkIG9iamVjdAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZSBzdWIgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN1YigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoc3ViQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgc3ViXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdWJCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBIG5lc3RlZCBvYmplY3QKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGUgc3ViID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVN1Yihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlIHZhbHVlKSB7CiAgICAgICAgaWYgKHN1YkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSAmJgogICAgICAgICAgICBzdWJfICE9IG51bGwgJiYKICAgICAgICAgICAgc3ViXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldFN1YkJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3ViXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdWJCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoc3ViXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEEgbmVzdGVkIG9iamVjdAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZSBzdWIgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3ViKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBzdWJfID0gbnVsbDsKICAgICAgICBpZiAoc3ViQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgc3ViQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgc3ViQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQSBuZXN0ZWQgb2JqZWN0CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlIHN1YiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUuQnVpbGRlciBnZXRTdWJCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0U3ViRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBIG5lc3RlZCBvYmplY3QKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGUgc3ViID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU9yQnVpbGRlciBnZXRTdWJPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHN1YkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBzdWJCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBzdWJfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQSBuZXN0ZWQgb2JqZWN0CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlIHN1YiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFN1YkZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoc3ViQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgc3ViQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRTdWIoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHN1Yl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3ViQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zIGZpbGVfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmlsZU9wdGlvbnMsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5GaWxlT3B0aW9ucy5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmlsZU9wdGlvbnNPckJ1aWxkZXI+IGZpbGVCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRvIHRlc3QgdGhlIHBhcnNpbmcgb2YgZXh0ZW5zaW9ucyBpbnNpZGUgYWdncmVnYXRlIHZhbHVlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyBmaWxlID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmlsZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWxlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVG8gdGVzdCB0aGUgcGFyc2luZyBvZiBleHRlbnNpb25zIGluc2lkZSBhZ2dyZWdhdGUgdmFsdWVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIGZpbGUgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmlsZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmlsZU9wdGlvbnMgZ2V0RmlsZSgpIHsKICAgICAgICBpZiAoZmlsZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmaWxlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmlsZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmaWxlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVG8gdGVzdCB0aGUgcGFyc2luZyBvZiBleHRlbnNpb25zIGluc2lkZSBhZ2dyZWdhdGUgdmFsdWVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIGZpbGUgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpbGUoY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpbGVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZpbGVfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZpbGVCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUbyB0ZXN0IHRoZSBwYXJzaW5nIG9mIGV4dGVuc2lvbnMgaW5zaWRlIGFnZ3JlZ2F0ZSB2YWx1ZXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgZmlsZSA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmlsZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5GaWxlT3B0aW9ucy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmaWxlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmlsZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmlsZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRvIHRlc3QgdGhlIHBhcnNpbmcgb2YgZXh0ZW5zaW9ucyBpbnNpZGUgYWdncmVnYXRlIHZhbHVlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyBmaWxlID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZpbGUoY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zIHZhbHVlKSB7CiAgICAgICAgaWYgKGZpbGVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkgJiYKICAgICAgICAgICAgZmlsZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBmaWxlXyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmlsZU9wdGlvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0RmlsZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmlsZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgZmlsZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChmaWxlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRvIHRlc3QgdGhlIHBhcnNpbmcgb2YgZXh0ZW5zaW9ucyBpbnNpZGUgYWdncmVnYXRlIHZhbHVlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyBmaWxlID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpbGUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGZpbGVfID0gbnVsbDsKICAgICAgICBpZiAoZmlsZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmaWxlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVG8gdGVzdCB0aGUgcGFyc2luZyBvZiBleHRlbnNpb25zIGluc2lkZSBhZ2dyZWdhdGUgdmFsdWVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIGZpbGUgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmlsZU9wdGlvbnMuQnVpbGRlciBnZXRGaWxlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZpbGVGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRvIHRlc3QgdGhlIHBhcnNpbmcgb2YgZXh0ZW5zaW9ucyBpbnNpZGUgYWdncmVnYXRlIHZhbHVlcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyBmaWxlID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zT3JCdWlsZGVyIGdldEZpbGVPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZpbGVCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZmlsZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZpbGVfID09IG51bGwgPwogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5GaWxlT3B0aW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpbGVfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVG8gdGVzdCB0aGUgcGFyc2luZyBvZiBleHRlbnNpb25zIGluc2lkZSBhZ2dyZWdhdGUgdmFsdWVzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIGZpbGUgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5GaWxlT3B0aW9ucywgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5GaWxlT3B0aW9uc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWxlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmaWxlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZmlsZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zLCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmlsZU9wdGlvbnMuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0RmlsZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgZmlsZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZmlsZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0IG1zZXRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRPckJ1aWxkZXI+IG1zZXRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFuIGVtYmVkZGVkIG1lc3NhZ2Ugc2V0CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZVNldCBtc2V0ID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbXNldCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNc2V0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQW4gZW1iZWRkZWQgbWVzc2FnZSBzZXQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0IG1zZXQgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbXNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCBnZXRNc2V0KCkgewogICAgICAgIGlmIChtc2V0QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG1zZXRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1zZXRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbXNldEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFuIGVtYmVkZGVkIG1lc3NhZ2Ugc2V0CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZVNldCBtc2V0ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNc2V0KHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0IHZhbHVlKSB7CiAgICAgICAgaWYgKG1zZXRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG1zZXRfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1zZXRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBbiBlbWJlZGRlZCBtZXNzYWdlIHNldAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQgbXNldCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TXNldCgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG1zZXRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBtc2V0XyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtc2V0QnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQW4gZW1iZWRkZWQgbWVzc2FnZSBzZXQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0IG1zZXQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlTXNldChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldCB2YWx1ZSkgewogICAgICAgIGlmIChtc2V0QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApICYmCiAgICAgICAgICAgIG1zZXRfICE9IG51bGwgJiYKICAgICAgICAgICAgbXNldF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0TXNldEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbXNldF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgbXNldEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChtc2V0XyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFuIGVtYmVkZGVkIG1lc3NhZ2Ugc2V0CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZVNldCBtc2V0ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1zZXQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG1zZXRfID0gbnVsbDsKICAgICAgICBpZiAobXNldEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1zZXRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBtc2V0QnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQW4gZW1iZWRkZWQgbWVzc2FnZSBzZXQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0IG1zZXQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldC5CdWlsZGVyIGdldE1zZXRCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0TXNldEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQW4gZW1iZWRkZWQgbWVzc2FnZSBzZXQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0IG1zZXQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldE9yQnVpbGRlciBnZXRNc2V0T3JCdWlsZGVyKCkgewogICAgICAgIGlmIChtc2V0QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG1zZXRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtc2V0XyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1zZXRfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQW4gZW1iZWRkZWQgbWVzc2FnZSBzZXQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlU2V0IG1zZXQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZVNldE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRNc2V0RmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChtc2V0QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbXNldEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0LkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlU2V0T3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TXNldCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgbXNldF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbXNldEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQW55IGFueV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4gYW55QnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBbiBhbnkKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuQW55IGFueSA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGFueSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBbnkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBbiBhbnkKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuQW55IGFueSA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBhbnkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkgZ2V0QW55KCkgewogICAgICAgIGlmIChhbnlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gYW55XyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBhbnlfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gYW55QnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQW4gYW55CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnkgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEFueShjb20uZ29vZ2xlLnByb3RvYnVmLkFueSB2YWx1ZSkgewogICAgICAgIGlmIChhbnlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGFueV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYW55QnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQW4gYW55CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnkgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEFueSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGFueUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGFueV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYW55QnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQW4gYW55CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnkgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlQW55KGNvbS5nb29nbGUucHJvdG9idWYuQW55IHZhbHVlKSB7CiAgICAgICAgaWYgKGFueUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSAmJgogICAgICAgICAgICBhbnlfICE9IG51bGwgJiYKICAgICAgICAgICAgYW55XyAhPSBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRBbnlCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGFueV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgYW55QnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGFueV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBbiBhbnkKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuQW55IGFueSA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBbnkoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGFueV8gPSBudWxsOwogICAgICAgIGlmIChhbnlCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBhbnlCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBhbnlCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBbiBhbnkKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5nb29nbGUucHJvdG9idWYuQW55IGFueSA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQW55LkJ1aWxkZXIgZ2V0QW55QnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEFueUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQW4gYW55CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAuZ29vZ2xlLnByb3RvYnVmLkFueSBhbnkgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlciBnZXRBbnlPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGFueUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBhbnlCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBhbnlfID09IG51bGwgPwogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LmdldERlZmF1bHRJbnN0YW5jZSgpIDogYW55XzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFuIGFueQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLmdvb2dsZS5wcm90b2J1Zi5BbnkgYW55ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueSwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnkuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0QW55RmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChhbnlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBhbnlCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQW55LCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLkFueU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldEFueSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgYW55XyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBhbnlCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEFnZ3JlZ2F0ZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxBZ2dyZWdhdGU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBBZ2dyZWdhdGUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxBZ2dyZWdhdGU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8QWdncmVnYXRlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5FU1RFRF9GSUVMRF9OVU1CRVIgPSAxNTQ3NjkwMzsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5GaWxlT3B0aW9ucywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlPiBuZXN0ZWQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMCwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUuY2xhc3MsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgQWdncmVnYXRlTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRuYW1lID0gMSBbKC5wcm90b2J1Zl91bml0dGVzdC5maWVsZG9wdCkgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZG5hbWUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkbmFtZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZG5hbWUgPSAxIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkb3B0KSA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZG5hbWUuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZG5hbWUoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEFnZ3JlZ2F0ZU1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZSkKICAgICAgQWdncmVnYXRlTWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgQWdncmVnYXRlTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBBZ2dyZWdhdGVNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgQWdncmVnYXRlTWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBBZ2dyZWdhdGVNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9BZ2dyZWdhdGVNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9BZ2dyZWdhdGVNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRE5BTUVfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IGZpZWxkbmFtZV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZG5hbWUgPSAxIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkb3B0KSA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkbmFtZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkbmFtZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZG5hbWUgPSAxIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkb3B0KSA9IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZG5hbWUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRuYW1lKCkgewogICAgICByZXR1cm4gZmllbGRuYW1lXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGZpZWxkbmFtZV8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIGZpZWxkbmFtZV8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKGhhc0ZpZWxkbmFtZSgpICE9IG90aGVyLmhhc0ZpZWxkbmFtZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZG5hbWUoKSkgewogICAgICAgIGlmIChnZXRGaWVsZG5hbWUoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZG5hbWUoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0ZpZWxkbmFtZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTEROQU1FX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZG5hbWUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9BZ2dyZWdhdGVNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBmaWVsZG5hbWVfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9BZ2dyZWdhdGVNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGRuYW1lXyA9IGZpZWxkbmFtZV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZG5hbWUoKSkgewogICAgICAgICAgc2V0RmllbGRuYW1lKG90aGVyLmdldEZpZWxkbmFtZSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBmaWVsZG5hbWVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBmaWVsZG5hbWVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkbmFtZSA9IDEgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRvcHQpID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZG5hbWUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZG5hbWUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZG5hbWUgPSAxIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkb3B0KSA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkbmFtZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZG5hbWUoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkbmFtZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkbmFtZSA9IDEgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRvcHQpID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZG5hbWUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZG5hbWUoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkbmFtZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkbmFtZSA9IDEgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRvcHQpID0geyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZG5hbWUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGZpZWxkbmFtZV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZU1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZU1lc3NhZ2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxBZ2dyZWdhdGVNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEFnZ3JlZ2F0ZU1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBBZ2dyZWdhdGVNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8QWdncmVnYXRlTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxBZ2dyZWdhdGVNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIE5lc3RlZE9wdGlvblR5cGVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkT3B0aW9uVHlwZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUZXN0IGN1c3RvbSBvcHRpb25zIGZvciBuZXN0ZWQgdHlwZS4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZE9wdGlvblR5cGV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBOZXN0ZWRPcHRpb25UeXBlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZE9wdGlvblR5cGUpCiAgICAgIE5lc3RlZE9wdGlvblR5cGVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIE5lc3RlZE9wdGlvblR5cGUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgTmVzdGVkT3B0aW9uVHlwZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIE5lc3RlZE9wdGlvblR5cGUoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgTmVzdGVkT3B0aW9uVHlwZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkT3B0aW9uVHlwZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkT3B0aW9uVHlwZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkRW51bX0KICAgICAqLwogICAgcHVibGljIGVudW0gTmVzdGVkRW51bQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPk5FU1RFRF9FTlVNX1ZBTFVFID0gMSBbKC5wcm90b2J1Zl91bml0dGVzdC5lbnVtX3ZhbHVlX29wdDEpID0gMTAwNF07PC9jb2RlPgogICAgICAgKi8KICAgICAgTkVTVEVEX0VOVU1fVkFMVUUoMSksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ORVNURURfRU5VTV9WQUxVRSA9IDEgWygucHJvdG9idWZfdW5pdHRlc3QuZW51bV92YWx1ZV9vcHQxKSA9IDEwMDRdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5FU1RFRF9FTlVNX1ZBTFVFX1ZBTFVFID0gMTsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIE5FU1RFRF9FTlVNX1ZBTFVFOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIE5lc3RlZEVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxOZXN0ZWRFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgTmVzdGVkRW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gTmVzdGVkRW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE5lc3RlZEVudW1bXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSB2YWx1ZU9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgICBwcml2YXRlIE5lc3RlZEVudW0oaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZEVudW0pCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbmVzdGVkX2ZpZWxkID0gMSBbKC5wcm90b2J1Zl91bml0dGVzdC5maWVsZF9vcHQxKSA9IDEwMDJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuZXN0ZWRGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc05lc3RlZEZpZWxkKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBuZXN0ZWRfZmllbGQgPSAxIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdDEpID0gMTAwMl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBuZXN0ZWRGaWVsZC4KICAgICAgICovCiAgICAgIGludCBnZXROZXN0ZWRGaWVsZCgpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTmVzdGVkTWVzc2FnZSBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlKQogICAgICAgIE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBOZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgTmVzdGVkTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRPcHRpb25UeXBlX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRPcHRpb25UeXBlX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkVTVEVEX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgaW50IG5lc3RlZEZpZWxkXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBuZXN0ZWRfZmllbGQgPSAxIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdDEpID0gMTAwMl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lc3RlZEZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmVzdGVkRmllbGQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBuZXN0ZWRfZmllbGQgPSAxIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdDEpID0gMTAwMl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBuZXN0ZWRGaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXROZXN0ZWRGaWVsZCgpIHsKICAgICAgICByZXR1cm4gbmVzdGVkRmllbGRfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgbmVzdGVkRmllbGRfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgbmVzdGVkRmllbGRfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICAgIGlmIChoYXNOZXN0ZWRGaWVsZCgpICE9IG90aGVyLmhhc05lc3RlZEZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzTmVzdGVkRmllbGQoKSkgewogICAgICAgICAgaWYgKGdldE5lc3RlZEZpZWxkKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXROZXN0ZWRGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzTmVzdGVkRmllbGQoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTkVTVEVEX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE5lc3RlZEZpZWxkKCk7CiAgICAgICAgfQogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkT3B0aW9uVHlwZV9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZE9wdGlvblR5cGVfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgbmVzdGVkRmllbGRfID0gMDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRPcHRpb25UeXBlX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5uZXN0ZWRGaWVsZF8gPSBuZXN0ZWRGaWVsZF87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZS5OZXN0ZWRNZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2Upb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc05lc3RlZEZpZWxkKCkpIHsKICAgICAgICAgICAgc2V0TmVzdGVkRmllbGQob3RoZXIuZ2V0TmVzdGVkRmllbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgICAgbmVzdGVkRmllbGRfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBpbnQgbmVzdGVkRmllbGRfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBuZXN0ZWRfZmllbGQgPSAxIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdDEpID0gMTAwMl07PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmVzdGVkRmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZXN0ZWRGaWVsZCgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbmVzdGVkX2ZpZWxkID0gMSBbKC5wcm90b2J1Zl91bml0dGVzdC5maWVsZF9vcHQxKSA9IDEwMDJdOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBuZXN0ZWRGaWVsZC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXROZXN0ZWRGaWVsZCgpIHsKICAgICAgICAgIHJldHVybiBuZXN0ZWRGaWVsZF87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG5lc3RlZF9maWVsZCA9IDEgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0MSkgPSAxMDAyXTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBuZXN0ZWRGaWVsZCB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE5lc3RlZEZpZWxkKGludCB2YWx1ZSkgewoKICAgICAgICAgIG5lc3RlZEZpZWxkXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbmVzdGVkX2ZpZWxkID0gMSBbKC5wcm90b2J1Zl91bml0dGVzdC5maWVsZF9vcHQxKSA9IDEwMDJdOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJOZXN0ZWRGaWVsZCgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIG5lc3RlZEZpZWxkXyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZSkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkTWVzc2FnZT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBOZXN0ZWRNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdCBjdXN0b20gb3B0aW9ucyBmb3IgbmVzdGVkIHR5cGUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRPcHRpb25UeXBlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkT3B0aW9uVHlwZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZE9wdGlvblR5cGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRPcHRpb25UeXBlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRPcHRpb25UeXBlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZE9wdGlvblR5cGUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZE9wdGlvblR5cGUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5lc3RlZE9wdGlvblR5cGUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRPcHRpb25UeXBlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE5lc3RlZE9wdGlvblR5cGU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBOZXN0ZWRPcHRpb25UeXBlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkT3B0aW9uVHlwZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRPcHRpb25UeXBlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmVzdGVkT3B0aW9uVHlwZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBORVNURURfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDc5MTI1NzM7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmlsZU9wdGlvbnMsCiAgICAgICAgamF2YS5sYW5nLkludGVnZXI+IG5lc3RlZEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXN0ZWRPcHRpb25UeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMCwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgICAgbnVsbCk7CiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIE9sZE9wdGlvblR5cGVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuT2xkT3B0aW9uVHlwZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5PbGRPcHRpb25UeXBlLlRlc3RFbnVtIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuT2xkT3B0aW9uVHlwZS5UZXN0RW51bSB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlLlRlc3RFbnVtIGdldFZhbHVlKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogQ3VzdG9tIG1lc3NhZ2Ugb3B0aW9uIHRoYXQgaGFzIGEgcmVxdWlyZWQgZW51bSBmaWVsZC4KICAgKiBXQVJOSU5HOiB0aGlzIGlzIHN0cm9uZ2x5IGRpc2NvdXJhZ2VkIQogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuT2xkT3B0aW9uVHlwZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE9sZE9wdGlvblR5cGUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuT2xkT3B0aW9uVHlwZSkKICAgICAgT2xkT3B0aW9uVHlwZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgT2xkT3B0aW9uVHlwZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBPbGRPcHRpb25UeXBlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgT2xkT3B0aW9uVHlwZSgpIHsKICAgICAgdmFsdWVfID0gMDsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBPbGRPcHRpb25UeXBlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbGRPcHRpb25UeXBlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbGRPcHRpb25UeXBlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuT2xkT3B0aW9uVHlwZS5UZXN0RW51bX0KICAgICAqLwogICAgcHVibGljIGVudW0gVGVzdEVudW0KICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5PTERfVkFMVUUgPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIE9MRF9WQUxVRSgwKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPk9MRF9WQUxVRSA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT0xEX1ZBTFVFX1ZBTFVFID0gMDsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIFRlc3RFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBUZXN0RW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAwOiByZXR1cm4gT0xEX1ZBTFVFOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8VGVzdEVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBUZXN0RW51bT4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFRlc3RFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgVGVzdEVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIFRlc3RFbnVtLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgICB9CiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGVzdEVudW1bXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgVGVzdEVudW0gdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBUZXN0RW51bShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk9sZE9wdGlvblR5cGUuVGVzdEVudW0pCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFZBTFVFX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCB2YWx1ZV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuT2xkT3B0aW9uVHlwZS5UZXN0RW51bSB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzVmFsdWUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk9sZE9wdGlvblR5cGUuVGVzdEVudW0gdmFsdWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHZhbHVlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZS5UZXN0RW51bSBnZXRWYWx1ZSgpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUuVGVzdEVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUuVGVzdEVudW0uZm9yTnVtYmVyKHZhbHVlXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlLlRlc3RFbnVtLk9MRF9WQUxVRSA6IHJlc3VsdDsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWhhc1ZhbHVlKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMSwgdmFsdWVfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDEsIHZhbHVlXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlKSBvYmo7CgogICAgICBpZiAoaGFzVmFsdWUoKSAhPSBvdGhlci5oYXNWYWx1ZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNWYWx1ZSgpKSB7CiAgICAgICAgaWYgKHZhbHVlXyAhPSBvdGhlci52YWx1ZV8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNWYWx1ZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVkFMVUVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHZhbHVlXzsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQ3VzdG9tIG1lc3NhZ2Ugb3B0aW9uIHRoYXQgaGFzIGEgcmVxdWlyZWQgZW51bSBmaWVsZC4KICAgICAqIFdBUk5JTkc6IHRoaXMgaXMgc3Ryb25nbHkgZGlzY291cmFnZWQhCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5PbGRPcHRpb25UeXBlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuT2xkT3B0aW9uVHlwZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09sZE9wdGlvblR5cGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbGRPcHRpb25UeXBlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICB2YWx1ZV8gPSAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09sZE9wdGlvblR5cGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC52YWx1ZV8gPSB2YWx1ZV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNWYWx1ZSgpKSB7CiAgICAgICAgICBzZXRWYWx1ZShvdGhlci5nZXRWYWx1ZSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghaGFzVmFsdWUoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZS5UZXN0RW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUuVGVzdEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgdmFsdWVfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCB2YWx1ZV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk9sZE9wdGlvblR5cGUuVGVzdEVudW0gdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc1ZhbHVlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk9sZE9wdGlvblR5cGUuVGVzdEVudW0gdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZS5UZXN0RW51bSBnZXRWYWx1ZSgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZS5UZXN0RW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZS5UZXN0RW51bS5mb3JOdW1iZXIodmFsdWVfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZS5UZXN0RW51bS5PTERfVkFMVUUgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5PbGRPcHRpb25UeXBlLlRlc3RFbnVtIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRWYWx1ZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZS5UZXN0RW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHZhbHVlXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuT2xkT3B0aW9uVHlwZS5UZXN0RW51bSB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICB2YWx1ZV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk9sZE9wdGlvblR5cGUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk9sZE9wdGlvblR5cGUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk9sZE9wdGlvblR5cGUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPbGRPcHRpb25UeXBlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE9sZE9wdGlvblR5cGU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBPbGRPcHRpb25UeXBlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T2xkT3B0aW9uVHlwZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPbGRPcHRpb25UeXBlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuT2xkT3B0aW9uVHlwZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIE5ld09wdGlvblR5cGVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuTmV3T3B0aW9uVHlwZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5OZXdPcHRpb25UeXBlLlRlc3RFbnVtIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNWYWx1ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuTmV3T3B0aW9uVHlwZS5UZXN0RW51bSB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlLlRlc3RFbnVtIGdldFZhbHVlKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVXBkYXRlZCB2ZXJzaW9uIG9mIHRoZSBjdXN0b20gb3B0aW9uIGFib3ZlLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTmV3T3B0aW9uVHlwZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5ld09wdGlvblR5cGUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTmV3T3B0aW9uVHlwZSkKICAgICAgTmV3T3B0aW9uVHlwZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgTmV3T3B0aW9uVHlwZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBOZXdPcHRpb25UeXBlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgTmV3T3B0aW9uVHlwZSgpIHsKICAgICAgdmFsdWVfID0gMDsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBOZXdPcHRpb25UeXBlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXdPcHRpb25UeXBlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXdPcHRpb25UeXBlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTmV3T3B0aW9uVHlwZS5UZXN0RW51bX0KICAgICAqLwogICAgcHVibGljIGVudW0gVGVzdEVudW0KICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5PTERfVkFMVUUgPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIE9MRF9WQUxVRSgwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPk5FV19WQUxVRSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgTkVXX1ZBTFVFKDEpLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+T0xEX1ZBTFVFID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTERfVkFMVUVfVkFMVUUgPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+TkVXX1ZBTFVFID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBORVdfVkFMVUVfVkFMVUUgPSAxOwoKCiAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgVGVzdEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIFRlc3RFbnVtIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBPTERfVkFMVUU7CiAgICAgICAgICBjYXNlIDE6IHJldHVybiBORVdfVkFMVUU7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxUZXN0RW51bT4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIFRlc3RFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8VGVzdEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBUZXN0RW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gVGVzdEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZS5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUZXN0RW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBUZXN0RW51bSB2YWx1ZU9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgICBwcml2YXRlIFRlc3RFbnVtKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTmV3T3B0aW9uVHlwZS5UZXN0RW51bSkKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVkFMVUVfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IHZhbHVlXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5OZXdPcHRpb25UeXBlLlRlc3RFbnVtIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNWYWx1ZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuTmV3T3B0aW9uVHlwZS5UZXN0RW51bSB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlLlRlc3RFbnVtIGdldFZhbHVlKCkgewogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZS5UZXN0RW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZS5UZXN0RW51bS5mb3JOdW1iZXIodmFsdWVfKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUuVGVzdEVudW0uT0xEX1ZBTFVFIDogcmVzdWx0OwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmICghaGFzVmFsdWUoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgxLCB2YWx1ZV8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMSwgdmFsdWVfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUpIG9iajsKCiAgICAgIGlmIChoYXNWYWx1ZSgpICE9IG90aGVyLmhhc1ZhbHVlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1ZhbHVlKCkpIHsKICAgICAgICBpZiAodmFsdWVfICE9IG90aGVyLnZhbHVlXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc1ZhbHVlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBWQUxVRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgdmFsdWVfOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBVcGRhdGVkIHZlcnNpb24gb2YgdGhlIGN1c3RvbSBvcHRpb24gYWJvdmUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5OZXdPcHRpb25UeXBlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTmV3T3B0aW9uVHlwZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05ld09wdGlvblR5cGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXdPcHRpb25UeXBlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICB2YWx1ZV8gPSAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05ld09wdGlvblR5cGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5OZXdPcHRpb25UeXBlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC52YWx1ZV8gPSB2YWx1ZV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNWYWx1ZSgpKSB7CiAgICAgICAgICBzZXRWYWx1ZShvdGhlci5nZXRWYWx1ZSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghaGFzVmFsdWUoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZS5UZXN0RW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUuVGVzdEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgdmFsdWVfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCB2YWx1ZV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk5ld09wdGlvblR5cGUuVGVzdEVudW0gdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB2YWx1ZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc1ZhbHVlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk5ld09wdGlvblR5cGUuVGVzdEVudW0gdmFsdWUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgdmFsdWUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZS5UZXN0RW51bSBnZXRWYWx1ZSgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZS5UZXN0RW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZS5UZXN0RW51bS5mb3JOdW1iZXIodmFsdWVfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZS5UZXN0RW51bS5PTERfVkFMVUUgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5OZXdPcHRpb25UeXBlLlRlc3RFbnVtIHZhbHVlID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRWYWx1ZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZS5UZXN0RW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHZhbHVlXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuTmV3T3B0aW9uVHlwZS5UZXN0RW51bSB2YWx1ZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclZhbHVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICB2YWx1ZV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk5ld09wdGlvblR5cGUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk5ld09wdGlvblR5cGUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLk5ld09wdGlvblR5cGUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXdPcHRpb25UeXBlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE5ld09wdGlvblR5cGU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBOZXdPcHRpb25UeXBlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmV3T3B0aW9uVHlwZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXdPcHRpb25UeXBlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTmV3T3B0aW9uVHlwZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbk9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24pCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVGVzdCBtZXNzYWdlIHVzaW5nIHRoZSAicmVxdWlyZWRfZW51bV9vcHQiIG9wdGlvbiBkZWZpbmVkIGFib3ZlLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9ufQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbikKICAgICAgVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24ubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24pKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24gb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbikgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbiBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0IG1lc3NhZ2UgdXNpbmcgdGhlICJyZXF1aXJlZF9lbnVtX29wdCIgb3B0aW9uIGRlZmluZWQgYWJvdmUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb259CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24pCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbi5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbiBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbiBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbih0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24pIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24pb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbiBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24pCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5UZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24gREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLlRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbiBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24gcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb24+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIC8qKgogICAqIFByb3RvYnVmIHNlcnZpY2Uge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTZXJ2aWNlV2l0aEN1c3RvbU9wdGlvbnN9CiAgICovCiAgcHVibGljIHN0YXRpYyBhYnN0cmFjdCBjbGFzcyBUZXN0U2VydmljZVdpdGhDdXN0b21PcHRpb25zCiAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlIHsKICAgIHByb3RlY3RlZCBUZXN0U2VydmljZVdpdGhDdXN0b21PcHRpb25zKCkge30KCiAgICBwdWJsaWMgaW50ZXJmYWNlIEludGVyZmFjZSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ycGMgRm9vKC5wcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25Gb29SZXF1ZXN0KSByZXR1cm5zICgucHJvdG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UpIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBmb28oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IHJlcXVlc3QsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NhbGxiYWNrPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZT4gZG9uZSk7CgogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlIG5ld1JlZmxlY3RpdmVTZXJ2aWNlKAogICAgICAgIGZpbmFsIEludGVyZmFjZSBpbXBsKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFNlcnZpY2VXaXRoQ3VzdG9tT3B0aW9ucygpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljICB2b2lkIGZvbygKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IHJlcXVlc3QsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2FsbGJhY2s8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlPiBkb25lKSB7CiAgICAgICAgICBpbXBsLmZvbyhjb250cm9sbGVyLCByZXF1ZXN0LCBkb25lKTsKICAgICAgICB9CgogICAgICB9OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1NlcnZpY2UKICAgICAgICBuZXdSZWZsZWN0aXZlQmxvY2tpbmdTZXJ2aWNlKGZpbmFsIEJsb2NraW5nSW50ZXJmYWNlIGltcGwpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkJsb2NraW5nU2VydmljZSgpIHsKICAgICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5TZXJ2aWNlRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIGNhbGxCbG9ja2luZ01ldGhvZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSByZXF1ZXN0KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChtZXRob2QuZ2V0U2VydmljZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAiU2VydmljZS5jYWxsQmxvY2tpbmdNZXRob2QoKSBnaXZlbiBtZXRob2QgZGVzY3JpcHRvciBmb3IgIiArCiAgICAgICAgICAgICAgIndyb25nIHNlcnZpY2UgdHlwZS4iKTsKICAgICAgICAgIH0KICAgICAgICAgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkgewogICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgcmV0dXJuIGltcGwuZm9vKGNvbnRyb2xsZXIsIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdClyZXF1ZXN0KTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLkFzc2VydGlvbkVycm9yKCJDYW4ndCBnZXQgaGVyZS4iKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UKICAgICAgICAgICAgZ2V0UmVxdWVzdFByb3RvdHlwZSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCkgewogICAgICAgICAgaWYgKG1ldGhvZC5nZXRTZXJ2aWNlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICJTZXJ2aWNlLmdldFJlcXVlc3RQcm90b3R5cGUoKSBnaXZlbiBtZXRob2QgIiArCiAgICAgICAgICAgICAgImRlc2NyaXB0b3IgZm9yIHdyb25nIHNlcnZpY2UgdHlwZS4iKTsKICAgICAgICAgIH0KICAgICAgICAgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkgewogICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoIkNhbid0IGdldCBoZXJlLiIpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZQogICAgICAgICAgICBnZXRSZXNwb25zZVByb3RvdHlwZSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCkgewogICAgICAgICAgaWYgKG1ldGhvZC5nZXRTZXJ2aWNlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICJTZXJ2aWNlLmdldFJlc3BvbnNlUHJvdG90eXBlKCkgZ2l2ZW4gbWV0aG9kICIgKwogICAgICAgICAgICAgICJkZXNjcmlwdG9yIGZvciB3cm9uZyBzZXJ2aWNlIHR5cGUuIik7CiAgICAgICAgICB9CiAgICAgICAgICBzd2l0Y2gobWV0aG9kLmdldEluZGV4KCkpIHsKICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5Bc3NlcnRpb25FcnJvcigiQ2FuJ3QgZ2V0IGhlcmUuIik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgfTsKICAgIH0KCiAgICAvKioKICAgICAqIDxjb2RlPnJwYyBGb28oLnByb3RvYnVmX3VuaXR0ZXN0LkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QpIHJldHVybnMgKC5wcm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25Gb29SZXNwb25zZSkgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgZm9vKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IHJlcXVlc3QsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDYWxsYmFjazxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2U+IGRvbmUpOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLlNlcnZpY2VEZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5nZXREZXNjcmlwdG9yKCkuZ2V0U2VydmljZXMoKS5nZXQoMCk7CiAgICB9CiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5TZXJ2aWNlRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgfQoKICAgIHB1YmxpYyBmaW5hbCB2b2lkIGNhbGxNZXRob2QoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UgcmVxdWVzdCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NhbGxiYWNrPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlPiBkb25lKSB7CiAgICAgIGlmIChtZXRob2QuZ2V0U2VydmljZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgIlNlcnZpY2UuY2FsbE1ldGhvZCgpIGdpdmVuIG1ldGhvZCBkZXNjcmlwdG9yIGZvciB3cm9uZyAiICsKICAgICAgICAgICJzZXJ2aWNlIHR5cGUuIik7CiAgICAgIH0KICAgICAgc3dpdGNoKG1ldGhvZC5nZXRJbmRleCgpKSB7CiAgICAgICAgY2FzZSAwOgogICAgICAgICAgdGhpcy5mb28oY29udHJvbGxlciwgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0KXJlcXVlc3QsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjVXRpbC48cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlPnNwZWNpYWxpemVDYWxsYmFjaygKICAgICAgICAgICAgICBkb25lKSk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoIkNhbid0IGdldCBoZXJlLiIpOwogICAgICB9CiAgICB9CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZQogICAgICAgIGdldFJlcXVlc3RQcm90b3R5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCkgewogICAgICBpZiAobWV0aG9kLmdldFNlcnZpY2UoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJTZXJ2aWNlLmdldFJlcXVlc3RQcm90b3R5cGUoKSBnaXZlbiBtZXRob2QgIiArCiAgICAgICAgICAiZGVzY3JpcHRvciBmb3Igd3Jvbmcgc2VydmljZSB0eXBlLiIpOwogICAgICB9CiAgICAgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkgewogICAgICAgIGNhc2UgMDoKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5Bc3NlcnRpb25FcnJvcigiQ2FuJ3QgZ2V0IGhlcmUuIik7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlCiAgICAgICAgZ2V0UmVzcG9uc2VQcm90b3R5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCkgewogICAgICBpZiAobWV0aG9kLmdldFNlcnZpY2UoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJTZXJ2aWNlLmdldFJlc3BvbnNlUHJvdG90eXBlKCkgZ2l2ZW4gbWV0aG9kICIgKwogICAgICAgICAgImRlc2NyaXB0b3IgZm9yIHdyb25nIHNlcnZpY2UgdHlwZS4iKTsKICAgICAgfQogICAgICBzd2l0Y2gobWV0aG9kLmdldEluZGV4KCkpIHsKICAgICAgICBjYXNlIDA6CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLkFzc2VydGlvbkVycm9yKCJDYW4ndCBnZXQgaGVyZS4iKTsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgU3R1YiBuZXdTdHViKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2hhbm5lbCBjaGFubmVsKSB7CiAgICAgIHJldHVybiBuZXcgU3R1YihjaGFubmVsKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFN0dWIgZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuVGVzdFNlcnZpY2VXaXRoQ3VzdG9tT3B0aW9ucyBpbXBsZW1lbnRzIEludGVyZmFjZSB7CiAgICAgIHByaXZhdGUgU3R1Yihjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NoYW5uZWwgY2hhbm5lbCkgewogICAgICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWw7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDaGFubmVsIGNoYW5uZWw7CgogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDaGFubmVsIGdldENoYW5uZWwoKSB7CiAgICAgICAgcmV0dXJuIGNoYW5uZWw7CiAgICAgIH0KCiAgICAgIHB1YmxpYyAgdm9pZCBmb28oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IHJlcXVlc3QsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NhbGxiYWNrPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZT4gZG9uZSkgewogICAgICAgIGNoYW5uZWwuY2FsbE1ldGhvZCgKICAgICAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXRob2RzKCkuZ2V0KDApLAogICAgICAgICAgY29udHJvbGxlciwKICAgICAgICAgIHJlcXVlc3QsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY1V0aWwuZ2VuZXJhbGl6ZUNhbGxiYWNrKAogICAgICAgICAgICBkb25lLAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UuY2xhc3MsCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkpOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBCbG9ja2luZ0ludGVyZmFjZSBuZXdCbG9ja2luZ1N0dWIoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1JwY0NoYW5uZWwgY2hhbm5lbCkgewogICAgICByZXR1cm4gbmV3IEJsb2NraW5nU3R1YihjaGFubmVsKTsKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIEJsb2NraW5nSW50ZXJmYWNlIHsKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZSBmb28oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXF1ZXN0IHJlcXVlc3QpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRXhjZXB0aW9uOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEJsb2NraW5nU3R1YiBpbXBsZW1lbnRzIEJsb2NraW5nSW50ZXJmYWNlIHsKICAgICAgcHJpdmF0ZSBCbG9ja2luZ1N0dWIoY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1JwY0NoYW5uZWwgY2hhbm5lbCkgewogICAgICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWw7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1JwY0NoYW5uZWwgY2hhbm5lbDsKCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UgZm9vKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdCByZXF1ZXN0KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuU2VydmljZUV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UpIGNoYW5uZWwuY2FsbEJsb2NraW5nTWV0aG9kKAogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1ldGhvZHMoKS5nZXQoMCksCiAgICAgICAgICBjb250cm9sbGVyLAogICAgICAgICAgcmVxdWVzdCwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5DdXN0b21PcHRpb25Gb29SZXNwb25zZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTZXJ2aWNlV2l0aEN1c3RvbU9wdGlvbnMpCiAgfQoKICAvKioKICAgKiBQcm90b2J1ZiBzZXJ2aWNlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVTZXJ2aWNlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgYWJzdHJhY3QgY2xhc3MgQWdncmVnYXRlU2VydmljZQogICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuU2VydmljZSB7CiAgICBwcm90ZWN0ZWQgQWdncmVnYXRlU2VydmljZSgpIHt9CgogICAgcHVibGljIGludGVyZmFjZSBJbnRlcmZhY2UgewogICAgICAvKioKICAgICAgICogPGNvZGU+cnBjIE1ldGhvZCgucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZSkgcmV0dXJucyAoLnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZU1lc3NhZ2UpIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBtZXRob2QoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlIHJlcXVlc3QsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NhbGxiYWNrPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlPiBkb25lKTsKCiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2UgbmV3UmVmbGVjdGl2ZVNlcnZpY2UoCiAgICAgICAgZmluYWwgSW50ZXJmYWNlIGltcGwpIHsKICAgICAgcmV0dXJuIG5ldyBBZ2dyZWdhdGVTZXJ2aWNlKCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgIHZvaWQgbWV0aG9kKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UgcmVxdWVzdCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDYWxsYmFjazxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZT4gZG9uZSkgewogICAgICAgICAgaW1wbC5tZXRob2QoY29udHJvbGxlciwgcmVxdWVzdCwgZG9uZSk7CiAgICAgICAgfQoKICAgICAgfTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuQmxvY2tpbmdTZXJ2aWNlCiAgICAgICAgbmV3UmVmbGVjdGl2ZUJsb2NraW5nU2VydmljZShmaW5hbCBCbG9ja2luZ0ludGVyZmFjZSBpbXBsKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1NlcnZpY2UoKSB7CiAgICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuU2VydmljZURlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBjYWxsQmxvY2tpbmdNZXRob2QoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UgcmVxdWVzdCkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuU2VydmljZUV4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAobWV0aG9kLmdldFNlcnZpY2UoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgIlNlcnZpY2UuY2FsbEJsb2NraW5nTWV0aG9kKCkgZ2l2ZW4gbWV0aG9kIGRlc2NyaXB0b3IgZm9yICIgKwogICAgICAgICAgICAgICJ3cm9uZyBzZXJ2aWNlIHR5cGUuIik7CiAgICAgICAgICB9CiAgICAgICAgICBzd2l0Y2gobWV0aG9kLmdldEluZGV4KCkpIHsKICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIHJldHVybiBpbXBsLm1ldGhvZChjb250cm9sbGVyLCAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UpcmVxdWVzdCk7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5Bc3NlcnRpb25FcnJvcigiQ2FuJ3QgZ2V0IGhlcmUuIik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlCiAgICAgICAgICAgIGdldFJlcXVlc3RQcm90b3R5cGUoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QpIHsKICAgICAgICAgIGlmIChtZXRob2QuZ2V0U2VydmljZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAiU2VydmljZS5nZXRSZXF1ZXN0UHJvdG90eXBlKCkgZ2l2ZW4gbWV0aG9kICIgKwogICAgICAgICAgICAgICJkZXNjcmlwdG9yIGZvciB3cm9uZyBzZXJ2aWNlIHR5cGUuIik7CiAgICAgICAgICB9CiAgICAgICAgICBzd2l0Y2gobWV0aG9kLmdldEluZGV4KCkpIHsKICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLkFzc2VydGlvbkVycm9yKCJDYW4ndCBnZXQgaGVyZS4iKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UKICAgICAgICAgICAgZ2V0UmVzcG9uc2VQcm90b3R5cGUoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QpIHsKICAgICAgICAgIGlmIChtZXRob2QuZ2V0U2VydmljZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAiU2VydmljZS5nZXRSZXNwb25zZVByb3RvdHlwZSgpIGdpdmVuIG1ldGhvZCAiICsKICAgICAgICAgICAgICAiZGVzY3JpcHRvciBmb3Igd3Jvbmcgc2VydmljZSB0eXBlLiIpOwogICAgICAgICAgfQogICAgICAgICAgc3dpdGNoKG1ldGhvZC5nZXRJbmRleCgpKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5Bc3NlcnRpb25FcnJvcigiQ2FuJ3QgZ2V0IGhlcmUuIik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgfTsKICAgIH0KCiAgICAvKioKICAgICAqIDxjb2RlPnJwYyBNZXRob2QoLnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZU1lc3NhZ2UpIHJldHVybnMgKC5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVNZXNzYWdlKSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBtZXRob2QoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UgcmVxdWVzdCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NhbGxiYWNrPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlPiBkb25lKTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5TZXJ2aWNlRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuZ2V0RGVzY3JpcHRvcigpLmdldFNlcnZpY2VzKCkuZ2V0KDEpOwogICAgfQogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuU2VydmljZURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgIH0KCiAgICBwdWJsaWMgZmluYWwgdm9pZCBjYWxsTWV0aG9kKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIHJlcXVlc3QsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDYWxsYmFjazwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZT4gZG9uZSkgewogICAgICBpZiAobWV0aG9kLmdldFNlcnZpY2UoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJTZXJ2aWNlLmNhbGxNZXRob2QoKSBnaXZlbiBtZXRob2QgZGVzY3JpcHRvciBmb3Igd3JvbmcgIiArCiAgICAgICAgICAic2VydmljZSB0eXBlLiIpOwogICAgICB9CiAgICAgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkgewogICAgICAgIGNhc2UgMDoKICAgICAgICAgIHRoaXMubWV0aG9kKGNvbnRyb2xsZXIsIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSlyZXF1ZXN0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY1V0aWwuPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlPnNwZWNpYWxpemVDYWxsYmFjaygKICAgICAgICAgICAgICBkb25lKSk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoIkNhbid0IGdldCBoZXJlLiIpOwogICAgICB9CiAgICB9CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZQogICAgICAgIGdldFJlcXVlc3RQcm90b3R5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCkgewogICAgICBpZiAobWV0aG9kLmdldFNlcnZpY2UoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJTZXJ2aWNlLmdldFJlcXVlc3RQcm90b3R5cGUoKSBnaXZlbiBtZXRob2QgIiArCiAgICAgICAgICAiZGVzY3JpcHRvciBmb3Igd3Jvbmcgc2VydmljZSB0eXBlLiIpOwogICAgICB9CiAgICAgIHN3aXRjaChtZXRob2QuZ2V0SW5kZXgoKSkgewogICAgICAgIGNhc2UgMDoKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5Bc3NlcnRpb25FcnJvcigiQ2FuJ3QgZ2V0IGhlcmUuIik7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlCiAgICAgICAgZ2V0UmVzcG9uc2VQcm90b3R5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCkgewogICAgICBpZiAobWV0aG9kLmdldFNlcnZpY2UoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJTZXJ2aWNlLmdldFJlc3BvbnNlUHJvdG90eXBlKCkgZ2l2ZW4gbWV0aG9kICIgKwogICAgICAgICAgImRlc2NyaXB0b3IgZm9yIHdyb25nIHNlcnZpY2UgdHlwZS4iKTsKICAgICAgfQogICAgICBzd2l0Y2gobWV0aG9kLmdldEluZGV4KCkpIHsKICAgICAgICBjYXNlIDA6CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoIkNhbid0IGdldCBoZXJlLiIpOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBTdHViIG5ld1N0dWIoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDaGFubmVsIGNoYW5uZWwpIHsKICAgICAgcmV0dXJuIG5ldyBTdHViKGNoYW5uZWwpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU3R1YiBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVTZXJ2aWNlIGltcGxlbWVudHMgSW50ZXJmYWNlIHsKICAgICAgcHJpdmF0ZSBTdHViKGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2hhbm5lbCBjaGFubmVsKSB7CiAgICAgICAgdGhpcy5jaGFubmVsID0gY2hhbm5lbDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NoYW5uZWwgY2hhbm5lbDsKCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NoYW5uZWwgZ2V0Q2hhbm5lbCgpIHsKICAgICAgICByZXR1cm4gY2hhbm5lbDsKICAgICAgfQoKICAgICAgcHVibGljICB2b2lkIG1ldGhvZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UgcmVxdWVzdCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2FsbGJhY2s8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2U+IGRvbmUpIHsKICAgICAgICBjaGFubmVsLmNhbGxNZXRob2QoCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWV0aG9kcygpLmdldCgwKSwKICAgICAgICAgIGNvbnRyb2xsZXIsCiAgICAgICAgICByZXF1ZXN0LAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY1V0aWwuZ2VuZXJhbGl6ZUNhbGxiYWNrKAogICAgICAgICAgICBkb25lLAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZS5jbGFzcywKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpKTsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgQmxvY2tpbmdJbnRlcmZhY2UgbmV3QmxvY2tpbmdTdHViKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQmxvY2tpbmdScGNDaGFubmVsIGNoYW5uZWwpIHsKICAgICAgcmV0dXJuIG5ldyBCbG9ja2luZ1N0dWIoY2hhbm5lbCk7CiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBCbG9ja2luZ0ludGVyZmFjZSB7CiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSBtZXRob2QoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlIHJlcXVlc3QpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRXhjZXB0aW9uOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIEJsb2NraW5nU3R1YiBpbXBsZW1lbnRzIEJsb2NraW5nSW50ZXJmYWNlIHsKICAgICAgcHJpdmF0ZSBCbG9ja2luZ1N0dWIoY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1JwY0NoYW5uZWwgY2hhbm5lbCkgewogICAgICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWw7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1JwY0NoYW5uZWwgY2hhbm5lbDsKCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZSBtZXRob2QoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlIHJlcXVlc3QpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGVNZXNzYWdlKSBjaGFubmVsLmNhbGxCbG9ja2luZ01ldGhvZCgKICAgICAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXRob2RzKCkuZ2V0KDApLAogICAgICAgICAgY29udHJvbGxlciwKICAgICAgICAgIHJlcXVlc3QsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZVNlcnZpY2UpCiAgfQoKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUxFX09QVDFfRklFTERfTlVNQkVSID0gNzczNjk3NDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5GaWxlT3B0aW9ucywKICAgICAgamF2YS5sYW5nLkxvbmc+IGZpbGVPcHQxID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX09QVDFfRklFTERfTlVNQkVSID0gNzczOTAzNjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5NZXNzYWdlT3B0aW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IG1lc3NhZ2VPcHQxID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9PUFQxX0ZJRUxEX05VTUJFUiA9IDc3NDA5MzY7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpZWxkT3B0aW9ucywKICAgICAgamF2YS5sYW5nLkxvbmc+IGZpZWxkT3B0MSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfT1BUMl9GSUVMRF9OVU1CRVIgPSA3NzUzOTEzOwogIC8qKgogICAqIDxwcmU+CiAgICogVGhpcyBpcyB1c2VmdWwgZm9yIHRlc3RpbmcgdGhhdCB3ZSBjb3JyZWN0bHkgcmVnaXN0ZXIgZGVmYXVsdCB2YWx1ZXMgZm9yCiAgICogZXh0ZW5zaW9uIG9wdGlvbnMuCiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmllbGRPcHRpb25zLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gZmllbGRPcHQyID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9PUFQxX0ZJRUxEX05VTUJFUiA9IDc3NDAxMTE7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuT25lb2ZPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk9uZW9mT3B0aW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IG9uZW9mT3B0MSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9PUFQxX0ZJRUxEX05VTUJFUiA9IDc3NTM1NzY7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRW51bU9wdGlvbnMsCiAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiBlbnVtT3B0MSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9WQUxVRV9PUFQxX0ZJRUxEX05VTUJFUiA9IDE1NjA2Nzg7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5FbnVtVmFsdWVPcHRpb25zLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gZW51bVZhbHVlT3B0MSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VSVklDRV9PUFQxX0ZJRUxEX05VTUJFUiA9IDc4ODc2NTA7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuU2VydmljZU9wdGlvbnMsCiAgICAgIGphdmEubGFuZy5Mb25nPiBzZXJ2aWNlT3B0MSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUVUSE9EX09QVDFfRklFTERfTlVNQkVSID0gNzg5MDg2MDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1ldGhvZE9wdGlvbnMsCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5NZXRob2RPcHQxPiBtZXRob2RPcHQxID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuTWV0aG9kT3B0MS5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCT09MX09QVF9GSUVMRF9OVU1CRVIgPSA3NzA2MDkwOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLAogICAgICBqYXZhLmxhbmcuQm9vbGVhbj4gYm9vbE9wdCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4uY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UMzJfT1BUX0ZJRUxEX05VTUJFUiA9IDc3MDU3MDk7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuTWVzc2FnZU9wdGlvbnMsCiAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiBpbnQzMk9wdCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5UNjRfT1BUX0ZJRUxEX05VTUJFUiA9IDc3MDU1NDI7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuTWVzc2FnZU9wdGlvbnMsCiAgICAgIGphdmEubGFuZy5Mb25nPiBpbnQ2NE9wdCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVUlOVDMyX09QVF9GSUVMRF9OVU1CRVIgPSA3NzA0ODgwOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gdWludDMyT3B0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVSU5UNjRfT1BUX0ZJRUxEX05VTUJFUiA9IDc3MDIzNjc7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuTWVzc2FnZU9wdGlvbnMsCiAgICAgIGphdmEubGFuZy5Mb25nPiB1aW50NjRPcHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNJTlQzMl9PUFRfRklFTERfTlVNQkVSID0gNzcwMTU2ODsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5NZXNzYWdlT3B0aW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IHNpbnQzMk9wdCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0lOVDY0X09QVF9GSUVMRF9OVU1CRVIgPSA3NzAwODYzOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLAogICAgICBqYXZhLmxhbmcuTG9uZz4gc2ludDY0T3B0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSVhFRDMyX09QVF9GSUVMRF9OVU1CRVIgPSA3NzAwMzA3OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gZml4ZWQzMk9wdCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklYRUQ2NF9PUFRfRklFTERfTlVNQkVSID0gNzcwMDE5NDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5NZXNzYWdlT3B0aW9ucywKICAgICAgamF2YS5sYW5nLkxvbmc+IGZpeGVkNjRPcHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNGSVhFRDMyX09QVF9GSUVMRF9OVU1CRVIgPSA3Njk4NjQ1OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gc2ZpeGVkMzJPcHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNGSVhFRDY0X09QVF9GSUVMRF9OVU1CRVIgPSA3Njg1NDc1OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLAogICAgICBqYXZhLmxhbmcuTG9uZz4gc2ZpeGVkNjRPcHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZMT0FUX09QVF9GSUVMRF9OVU1CRVIgPSA3Njc1MzkwOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLAogICAgICBqYXZhLmxhbmcuRmxvYXQ+IGZsb2F0T3B0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuRmxvYXQuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRE9VQkxFX09QVF9GSUVMRF9OVU1CRVIgPSA3NjczMjkzOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLAogICAgICBqYXZhLmxhbmcuRG91YmxlPiBkb3VibGVPcHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Eb3VibGUuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HX09QVF9GSUVMRF9OVU1CRVIgPSA3NjczMjg1OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLAogICAgICBqYXZhLmxhbmcuU3RyaW5nPiBzdHJpbmdPcHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQllURVNfT1BUX0ZJRUxEX05VTUJFUiA9IDc2NzMyMzg7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuTWVzc2FnZU9wdGlvbnMsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gYnl0ZXNPcHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX09QVF9GSUVMRF9OVU1CRVIgPSA3NjczMjMzOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0uVGVzdEVudW1UeXBlPiBlbnVtT3B0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0uVGVzdEVudW1UeXBlLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1FU1NBR0VfVFlQRV9PUFRfRklFTERfTlVNQkVSID0gNzY2NTk2NzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5NZXNzYWdlT3B0aW9ucywKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGU+IG1lc3NhZ2VUeXBlT3B0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZS5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTU9PT19GSUVMRF9OVU1CRVIgPSA3NjYzNzA3OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUxIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMSwKICAgICAgamF2YS5sYW5nLkludGVnZXI+IG1vb28gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPUkdFX0ZJRUxEX05VTUJFUiA9IDc2NjM0NDI7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxLAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzPiBjb3JnZSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMy5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBHUkFVTFRfRklFTERfTlVNQkVSID0gNzY1MDkyNzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMiB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIsCiAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiBncmF1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEdBUlBMWV9GSUVMRF9OVU1CRVIgPSA3NjQ5OTkyOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMiwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMT4gZ2FycGx5ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxLmNsYXNzLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTEuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTVBMRVhfT1BUMV9GSUVMRF9OVU1CRVIgPSA3NjQ2NzU2OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxPiBjb21wbGV4T3B0MSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMS5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUxLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDT01QTEVYX09QVDJfRklFTERfTlVNQkVSID0gNzYzNjk0OTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5NZXNzYWdlT3B0aW9ucywKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMj4gY29tcGxleE9wdDIgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuY2xhc3MsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkNvbXBsZXhPcHRpb25UeXBlMi5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09NUExFWF9PUFQzX0ZJRUxEX05VTUJFUiA9IDc2MzY0NjM7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuTWVzc2FnZU9wdGlvbnMsCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTM+IGNvbXBsZXhPcHQzID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdGlvblR5cGUzLmNsYXNzLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTVBMRVhPUFQ2X0ZJRUxEX05VTUJFUiA9IDc1OTU0Njg7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuTWVzc2FnZU9wdGlvbnMsCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0Nj4gY29tcGxleE9wdDYgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0Ni5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQ29tcGxleE9wdDYuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJTEVPUFRfRklFTERfTlVNQkVSID0gMTU0Nzg0Nzk7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmlsZU9wdGlvbnMsCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGU+IGZpbGVvcHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUuY2xhc3MsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTVNHT1BUX0ZJRUxEX05VTUJFUiA9IDE1NDgwMDg4OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlPiBtc2dvcHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUuY2xhc3MsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERPUFRfRklFTERfTlVNQkVSID0gMTU0ODEzNzQ7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpZWxkT3B0aW9ucywKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZT4gZmllbGRvcHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUuY2xhc3MsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTU9QVF9GSUVMRF9OVU1CRVIgPSAxNTQ4MzIxODsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5FbnVtT3B0aW9ucywKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZT4gZW51bW9wdCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZS5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNVkFMT1BUX0ZJRUxEX05VTUJFUiA9IDE1NDg2OTIxOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRW51bVZhbHVlT3B0aW9ucywKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZT4gZW51bXZhbG9wdCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZS5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVJWSUNFT1BUX0ZJRUxEX05VTUJFUiA9IDE1NDk3MTQ1OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLlNlcnZpY2VPcHRpb25zLAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlPiBzZXJ2aWNlb3B0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLmNsYXNzLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1FVEhPRE9QVF9GSUVMRF9OVU1CRVIgPSAxNTUxMjcxMzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1ldGhvZE9wdGlvbnMsCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5BZ2dyZWdhdGU+IG1ldGhvZG9wdCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZS5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuQWdncmVnYXRlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFVSVJFRF9FTlVNX09QVF9GSUVMRF9OVU1CRVIgPSAxMDYxNjE4MDc7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuTWVzc2FnZU9wdGlvbnMsCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlPiByZXF1aXJlZEVudW1PcHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlLmNsYXNzLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5PbGRPcHRpb25UeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNfTWFwRmllbGRFbnRyeV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zX01hcEZpZWxkRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbkZvb1JlcXVlc3RfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9EdW1teU1lc3NhZ2VDb250YWluaW5nRW51bV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NldHRpbmdSZWFsc0Zyb21Qb3NpdGl2ZUludHNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50c19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50c19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9TZXR0aW5nUmVhbHNGcm9tTmVnYXRpdmVJbnRzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTFfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUxX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTJfQ29tcGxleE9wdGlvblR5cGU0X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlMl9Db21wbGV4T3B0aW9uVHlwZTRfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlM19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlM19Db21wbGV4T3B0aW9uVHlwZTVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUzX0NvbXBsZXhPcHRpb25UeXBlNV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdDZfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdDZfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1ZhcmlvdXNDb21wbGV4T3B0aW9uc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9WYXJpb3VzQ29tcGxleE9wdGlvbnNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZU1lc3NhZ2VTZXRfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZVNldF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnRfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnRfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9BZ2dyZWdhdGVfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZU1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkT3B0aW9uVHlwZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRPcHRpb25UeXBlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRPcHRpb25UeXBlX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkT3B0aW9uVHlwZV9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbGRPcHRpb25UeXBlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09sZE9wdGlvblR5cGVfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05ld09wdGlvblR5cGVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmV3T3B0aW9uVHlwZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aFJlcXVpcmVkRW51bU9wdGlvbl9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuLWdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9jdXN0b21fb3B0aW9uIiArCiAgICAgICJzLnByb3RvXDAyMlwwMjFwcm90b2J1Zl91bml0dGVzdFwwMzJcMDMxZ29vZ2xlL3Byb3RvIiArCiAgICAgICJidWYvYW55LnByb3RvXDAzMiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvIiArCiAgICAgICJyLnByb3RvXCJcMzIwXDAwMlxuXDAzNFRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnMiICsKICAgICAgIlwwMjJcMDM2XG5cMDA2ZmllbGQxXDAzMFwwMDEgXDAwMShcdEJcMDE2XDAxMFwwMDFcMzAxXDM0MFwzMDNcMDM1LVwzNDF1XG5cMDAyXDAwMFwwMDBcMDAwXDAyMlwwMjVcblwwMTNvbmVvIiArCiAgICAgICJmX2ZpZWxkXDAzMFwwMDIgXDAwMShcMDA1SFwwMDBcMDIyXlxuXHRtYXBfZmllbGRcMDMwXDAwMyBcMDAzKFwwMTMyPS5wcm8iICsKICAgICAgInRvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGkiICsKICAgICAgIm9ucy5NYXBGaWVsZEVudHJ5QlwwMTRcMzAxXDM0MFwzMDNcMDM1OTBcMDAwXDAwMFwwMDBcMDAwXDAwMFwwMDBcMDMyL1xuXHJNYXBGaSIgKwogICAgICAiZWxkRW50cnlcMDIyXDAxM1xuXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxIiArCiAgICAgICJcIjtcblwwMDZBbkVudW1cMDIyXDAxN1xuXDAxM0FORU5VTV9WQUwxXDAyMFwwMDFcMDIyXDAyNlxuXDAxM0FORU5VTV9WQSIgKwogICAgICAiTDJcMDIwXDAwMlwwMzJcMDA1XDI2MFwyMDZcMzcyXDAwNXtcMDMyXDAxMFwzMDVcMzY2XDMxMVwwMzVcMzUzXDM3NFwzNzdcMzc3OlwwMjBcMDEwXDAwMFwzNDBcMzUxXDMwMlwwMzVcMzEwXDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMDAxQiIgKwogICAgICAiXDAzMVxuXDAwN0FuT25lb2ZcMDIyXDAxNlwzNzBcMjU0XDMwM1wwMzVcMjM1XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMDAxXCJcMDMwXG5cMDI2Q3VzdG9tT3B0aSIgKwogICAgICAib25Gb29SZXF1ZXN0XCJcMDMxXG5cMDI3Q3VzdG9tT3B0aW9uRm9vUmVzcG9uc2VcIiIgKwogICAgICAiXDAzNlxuXDAzNEN1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2VcIlwwMzZcblwwMzRDdXN0byIgKwogICAgICAibU9wdGlvbkZvb1NlcnZlck1lc3NhZ2VcIm1cblwwMzJEdW1teU1lc3NhZ2VDIiArCiAgICAgICJvbnRhaW5pbmdFbnVtXCJPXG5cMDE0VGVzdEVudW1UeXBlXDAyMlwwMzJcblwwMjZURVNUX09QIiArCiAgICAgICJUSU9OX0VOVU1fVFlQRTFcMDIwXDAyNlwwMjIjXG5cMDI2VEVTVF9PUFRJT05fRU5VTV9UWSIgKwogICAgICAiUEUyXDAyMFwzNTFcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wwMDFcIiFcblwwMzdEdW1teU1lc3NhZ2VJbnZhbGlkQXNPIiArCiAgICAgICJwdGlvblR5cGVcIlwyMTJcMDAxXG5cMDM0Q3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHUiICsKICAgICAgImVzOmpcMjMxXDMyNlwyNTBcMDM1XDAwMFwwMDBcMDAwXDAwMFwwMDBcMDAwXDAwMFwyMDBcMjU1XDIxNVwyNTdcMDM1XDAwMFwwMDBcMDAwXDIwMFwyMjFcMzU2XDI1N1wwMzVcMDAwXDAwMFwwMDBcMDAwXDAwMFwwMDBcMDAwXDAwMFwyMzVcMzY1XDI1N1wwMzUiICsKICAgICAgIlwwMDBcMDAwXDAwMFwwMDBcMzcwXDIyN1wyNjBcMDM1XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDAwMVwyMDBcMzA0XDI2MFwwMzVcMzc3XDM3N1wzNzdcMzc3XDAxN1wzNzBcMzY1XDI2MFwwMzVcMDAwXDIwMFwyMjNcMjYyXDAzNVwwMDBcMjYwXDI3NFwyNjIiICsKICAgICAgIlwwMzVcMjAwXDIwMFwyMDBcMjAwXDIwMFwyMDBcMjAwXDIwMFwyMDBcMDAxXDM1MFwzMDZcMjYyXDAzNVwyMDBcMjAwXDIwMFwyMDBcMzcwXDM3N1wzNzdcMzc3XDM3N1wwMDFcMzIwXDMzNlwyNjJcMDM1XDAwMFwiXDIyMVwwMDFcblwwMzRDdXN0byIgKwogICAgICAibU9wdGlvbk1heEludGVnZXJWYWx1ZXM6cVwyMzFcMzI2XDI1MFwwMzVcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDE3N1wyNTVcMjE1XDI1NyIgKwogICAgICAiXDAzNVwzNzdcMzc3XDM3N1wxNzdcMjIxXDM1NlwyNTdcMDM1XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMjM1XDM2NVwyNTdcMDM1XDM3N1wzNzdcMzc3XDM3N1wzNzBcMjI3XDI2MFwwMzVcMzc2XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMDAxXDIwMCIgKwogICAgICAiXDMwNFwyNjBcMDM1XDM3NlwzNzdcMzc3XDM3N1wwMTdcMzcwXDM2NVwyNjBcMDM1XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDAwMVwyMDBcMjIzXDI2MlwwMzVcMzc3XDM3N1wzNzdcMzc3XDAxN1wyNjBcMjc0XDI2MlwwMzVcMzc3XDM3N1wzNzdcMzc3XDM3NyIgKwogICAgICAiXDM3N1wzNzdcMzc3XDE3N1wzNTBcMzA2XDI2MlwwMzVcMzc3XDM3N1wzNzdcMzc3XDAwN1wzMjBcMzM2XDI2MlwwMzVcMDAxXCJuXG5cMDI3Q3VzdG9tT3B0aW9uT3RoZXJWIiArCiAgICAgICJhbHVlczpTXDIxMFwzMzFcMjQyXDAzNVwzNTFcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wwMDFcMjYyXDMzMVwyNDJcMDM1XDAxM0hlbGxvXDAwMFdvcmxkXDI1MlwzMzRcMjQyIiArCiAgICAgICJcMDM1XDAxNkhlbGxvLCBcIldvcmxkXCJcMzUxXDMzNFwyNDJcMDM1XDM3M1lcMjE0QlwzMTJcMzAwXDM2Mz9cMzY1XDMzN1wyNDNcMDM1XDM0N1wyMDdFQVwzNTBcMzA2XDI2MlwwMzUiICsKICAgICAgIlwyMzRcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wwMDFcIjRcblwwMzRTZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbiIgKwogICAgICAidHM6XDAyNFwzNTFcMzM0XDI0MlwwMzVcMDAwXDAwMFwwMDBcMDAwXDAwMEBjQFwzNjVcMzM3XDI0M1wwMzVcMDAwXDAwMEBBXCI0XG5cMDM0U2V0dGluZ1JlYWxzIiArCiAgICAgICJGcm9tTmVnYXRpdmVJbnRzOlwwMjRcMzUxXDMzNFwyNDJcMDM1XDAwMFwwMDBcMDAwXDAwMFwwMDBAY1wzMDBcMzY1XDMzN1wyNDNcMDM1XDAwMFwwMDBAXDMwMVwiVSIgKwogICAgICAiXG5cMDIyQ29tcGxleE9wdGlvblR5cGUxXDAyMlwwMTNcblwwMDNmb29cMDMwXDAwMSBcMDAxKFwwMDVcMDIyXDAxNFxuXDAwNGZvbyIgKwogICAgICAiMlwwMzBcMDAyIFwwMDEoXDAwNVwwMjJcMDE0XG5cMDA0Zm9vM1wwMzBcMDAzIFwwMDEoXDAwNVwwMjJcMDE0XG5cMDA0Zm9vNFwwMzBcMDA0IFwwMDMoXDAwNSpcMDEwXDAxMGRcMDIwIiArCiAgICAgICJcMjAwXDIwMFwyMDBcMjAwXDAwMlwiXDIxM1wwMDNcblwwMjJDb21wbGV4T3B0aW9uVHlwZTJcMDIyMlxuXDAwM2JhclwwMzBcMDAxIFwwMDEoIiArCiAgICAgICJcMDEzMiUucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUxIiArCiAgICAgICJcMDIyXDAxM1xuXDAwM2JhelwwMzBcMDAyIFwwMDEoXDAwNVwwMjJGXG5cMDA0ZnJlZFwwMzBcMDAzIFwwMDEoXDAxMzI4LnByb3RvYnVmX3UiICsKICAgICAgIm5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyLkNvbXBsZXhPcHRpb24iICsKICAgICAgIlR5cGU0XDAyMkhcblwwMDZiYXJuZXlcMDMwXDAwNCBcMDAzKFwwMTMyOC5wcm90b2J1Zl91bml0dGVzIiArCiAgICAgICJ0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTRcMDMyIiArCiAgICAgICJcMjI3XDAwMVxuXDAyMkNvbXBsZXhPcHRpb25UeXBlNFwwMjJcclxuXDAwNXdhbGRvXDAzMFwwMDEgXDAwMShcMDA1MnJcbiIgKwogICAgICAiXDAxNGNvbXBsZXhfb3B0NFwwMjJcMDM3Lmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTyIgKwogICAgICAicHRpb25zXDAzMFwyMTJcMzY1XDMyMVwwMDMgXDAwMShcMDEzMjgucHJvdG9idWZfdW5pdHRlc3QuQ29tcCIgKwogICAgICAibGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0KlwwMTBcMDEwZFwwMjBcMjAwXDIwMCIgKwogICAgICAiXDIwMFwyMDBcMDAyXCJcMjM0XDAwMVxuXDAyMkNvbXBsZXhPcHRpb25UeXBlM1wwMjJcMDEzXG5cMDAzbW9vXDAzMFwwMDEgXDAwMShcMDA1XDAyMiIgKwogICAgICAiVFxuXDAyMmNvbXBsZXhvcHRpb250eXBlNVwwMzBcMDAyIFwwMDEoXG4yOC5wcm90b2J1Zl91IiArCiAgICAgICJuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMy5Db21wbGV4T3B0aW9uIiArCiAgICAgICJUeXBlNVwwMzIjXG5cMDIyQ29tcGxleE9wdGlvblR5cGU1XDAyMlxyXG5cMDA1cGx1Z2hcMDMwXDAwMyBcMDAxIiArCiAgICAgICIoXDAwNVwiXDAzN1xuXDAxM0NvbXBsZXhPcHQ2XDAyMlwwMjBcblwwMDV4eXp6eVwwMzBcMzM3XDI3N1wzMTdcMDAzIFwwMDEoXDAwNVwiXDIyN1wwMDFcblwwMjUiICsKICAgICAgIlZhcmlvdXNDb21wbGV4T3B0aW9uczp+XDM0M1wzMzRcMzc0XDAzNFwzNzBcMzc1XDM3M1wwMzRcMDMwXDM0NFwzMzRcMzc0XDAzNFwzMjJcMjUwXDIxN1wwMzUiICsKICAgICAgIlwwMDNcMDEwXDI2M1wwMTdcMzcyXDMzNlwyMjBcMDM1XDAwNlwwMTBcdFwwMjNcMDMwXDAyNlwwMjRcMjUyXDM3NVwyMjBcMDM1QFxuXDAyMVwwMTBcMzQ3XDAwNVwyMjJcMzY1XDIzNVwwMzVcMDAzXDAxMFwzMzBcMDE3XDMzMFwyMDVcMjM2XDAzNVwzMTdcMDE3XDAyMCIgKwogICAgICAiXDMzM1wwMDdcMDMyXDAwM1wwMTBcMzAxXDAwMlwiXDAwMlwwMTBlXCJcMDAzXDAxMFwzMjRcMDAxXDMwMlwyNTRcMjI3XDAzNVwwMjFcMDEwXDM0NVwwMDVcMjIyXDM2NVwyMzVcMDM1XDAwM1wwMTBcMzExXDAyMFwzMzBcMjA1XDIzNlwwMzVcMzE2XDAxN1wzNzBcMzQ2IiArCiAgICAgICJcMjI3XDAzNVwyMTZcMDA1XDI0MlwzNDJcMjI1XDAzNVwwMjRcMDEwKiBjIFhcMjIyXDM2NVwyMzVcMDM1XDAwM1wwMTBcMzU0XDAwNlwzMzBcMjA1XDIzNlwwMzVcMzA0XDAwMlwiI1xuXDAyM0FnZ3JlZ2EiICsKICAgICAgInRlTWVzc2FnZVNldCpcMDEwXDAxMFwwMDRcMDIwXDM3N1wzNzdcMzc3XDM3N1wwMDc6XDAwMlwwMTBcMDAxXCJcMjQwXDAwMVxuXDAzMkFnZ3JlZ2F0ZSIgKwogICAgICAiTWVzc2FnZVNldEVsZW1lbnRcMDIyXHRcblwwMDFzXDAzMFwwMDEgXDAwMShcdDJ3XG5cMDI1bWVzc2FnZV8iICsKICAgICAgInNldF9leHRlbnNpb25cMDIyJi5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWciICsKICAgICAgImF0ZU1lc3NhZ2VTZXRcMDMwXDM2NlwzNTNcMjU2XDAwNyBcMDAxKFwwMTMyLS5wcm90b2J1Zl91bml0dGUiICsKICAgICAgInN0LkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50XCJcMjQwXDAwMlxuXHRBZ2dyZWciICsKICAgICAgImF0ZVwwMjJcdFxuXDAwMWlcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHRcblwwMDFzXDAzMFwwMDIgXDAwMShcdFwwMjIpXG5cMDAzc3ViXDAzMFwwMDMgXDAwMShcMDEzMlwwMzQiICsKICAgICAgIi5wcm90b2J1Zl91bml0dGVzdC5BZ2dyZWdhdGVcMDIyKlxuXDAwNGZpbGVcMDMwXDAwNCBcMDAxIiArCiAgICAgICIoXDAxMzJcMDM0Lmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wwMjI0XG5cMDA0bXNldCIgKwogICAgICAiXDAzMFwwMDUgXDAwMShcMDEzMiYucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzcyIgKwogICAgICAiYWdlU2V0XDAyMiFcblwwMDNhbnlcMDMwXDAwNiBcMDAxKFwwMTMyXDAyNC5nb29nbGUucHJvdG9idWYuQW4iICsKICAgICAgInkyTVxuXDAwNm5lc3RlZFwwMjJcMDM0Lmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uIiArCiAgICAgICJzXDAzMFwyNDdcMzIxXDI2MFwwMDcgXDAwMShcMDEzMlwwMzQucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlIiArCiAgICAgICJcIllcblwwMjBBZ2dyZWdhdGVNZXNzYWdlXDAyMilcblx0ZmllbGRuYW1lXDAzMFwwMDEgXDAwMShcMDA1QiIgKwogICAgICAiXDAyNlwzNjJcMjQxXDIwNztcMDIxXDAyMlwwMTdGaWVsZEFubm90YXRpb246XDAzMlwzMDJcMzIxXDIwNjtcMDI1XDAxMGVcMDIyXDAyMU1lc3NhZyIgKwogICAgICAiZUFubm90YXRpb25cIlwzMTFcMDAxXG5cMDIwTmVzdGVkT3B0aW9uVHlwZVwwMzI7XG5cck5lc3QiICsKICAgICAgImVkTWVzc2FnZVwwMjJcIlxuXDAxNG5lc3RlZF9maWVsZFwwMzBcMDAxIFwwMDEoXDAwNUJcMDE0XDMwMVwzNDBcMzAzXDAzNVwzNTJcMDAzXDAwMCIgKwogICAgICAiXDAwMFwwMDBcMDAwXDAwMFwwMDA6XDAwNlwzNDBcMzUxXDMwMlwwMzVcMzUxXDAwN1wiNVxuXG5OZXN0ZWRFbnVtXDAyMlwwMzVcblwwMjFORVNURURfRU4iICsKICAgICAgIlVNX1ZBTFVFXDAyMFwwMDFcMDMyXDAwNlwyNjBcMjA2XDM3MlwwMDVcMzU0XDAwN1wwMzJcMDEwXDMwNVwzNjZcMzExXDAzNVwzNTNcMDAzXDAwMFwwMDAyQVxuXDAyMG5lc3RlZF9lIiArCiAgICAgICJ4dGVuc2lvblwwMjJcMDM0Lmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9uc1wwMzBcMzc1IiArCiAgICAgICJcMzcwXDM0MlwwMDMgXDAwMShcMDA1QlwwMDZcMzEwXDIxM1wzMTJcMDM1XDM1NVwwMDdcImRcblxyT2xkT3B0aW9uVHlwZVwwMjI4XG5cMDA1dmFsdSIgKwogICAgICAiZVwwMzBcMDAxIFwwMDIoXDAxNjIpLnByb3RvYnVmX3VuaXR0ZXN0Lk9sZE9wdGlvblR5cCIgKwogICAgICAiZS5UZXN0RW51bVwiXDAzMVxuXDAxMFRlc3RFbnVtXDAyMlxyXG5cdE9MRF9WQUxVRVwwMjBcMDAwXCJzXG4iICsKICAgICAgIlxyTmV3T3B0aW9uVHlwZVwwMjI4XG5cMDA1dmFsdWVcMDMwXDAwMSBcMDAyKFwwMTYyKS5wcm90b2J1ZiIgKwogICAgICAiX3VuaXR0ZXN0Lk5ld09wdGlvblR5cGUuVGVzdEVudW1cIihcblwwMTBUZXN0IiArCiAgICAgICJFbnVtXDAyMlxyXG5cdE9MRF9WQUxVRVwwMjBcMDAwXDAyMlxyXG5cdE5FV19WQUxVRVwwMjBcMDAxXCItXG4hVGUiICsKICAgICAgInN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb246XDAxMFwzNzJcMzUwXDM3NFwyMjRcMDAzXDAwMlwwMTAiICsKICAgICAgIlwwMDAqNlxuXG5NZXRob2RPcHQxXDAyMlwwMjNcblwwMTdNRVRIT0RPUFQxX1ZBTDFcMDIwXDAwMVwwMjJcMDIzXG5cMDE3IiArCiAgICAgICJNRVRIT0RPUFQxX1ZBTDJcMDIwXDAwMipNXG5cckFnZ3JlZ2F0ZUVudW1cMDIyJVxuXDAwNVZBIiArCiAgICAgICJMVUVcMDIwXDAwMVwwMzJcMDMyXDMxMlwzNzRcMjExO1wwMjVcMDIyXDAyM0VudW1WYWx1ZUFubm90YXRpb25cMDMyXDAyNVwyMjJcMjI1XDIxMDtcMDIwIiArCiAgICAgICJcMDIyXDAxNkVudW1Bbm5vdGF0aW9uMlwyMTZcMDAxXG5cMDM0VGVzdFNlcnZpY2VXaXRoQ3VzdCIgKwogICAgICAib21PcHRpb25zXDAyMmNcblwwMDNGb29cMDIyKS5wcm90b2J1Zl91bml0dGVzdC5DdXMiICsKICAgICAgInRvbU9wdGlvbkZvb1JlcXVlc3RcMDMyKi5wcm90b2J1Zl91bml0dGVzdC4iICsKICAgICAgIkN1c3RvbU9wdGlvbkZvb1Jlc3BvbnNlXCJcMDA1XDM0MFwzNzJcMjE0XDAzNlwwMDJcMDMyXHRcMjIwXDI2MlwyMTNcMDM2XDMyM1wzMzNcMjAwXDMxMyIgKwogICAgICAiSTJcMjMxXDAwMVxuXDAyMEFnZ3JlZ2F0ZVNlcnZpY2VcMDIya1xuXDAwNk1ldGhvZFwwMjIjLnByb3RvIiArCiAgICAgICJidWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZVwwMzIjLnByb3RvYnVmIiArCiAgICAgICJfdW5pdHRlc3QuQWdncmVnYXRlTWVzc2FnZVwiXDAyN1wzMTJcMzEwXDIyNjtcMDIyXDAyMlwwMjBNZXRobyIgKwogICAgICAiZEFubm90YXRpb25cMDMyXDAzMFwzMTJcMzczXDIxNjtcMDIzXDAyMlwwMjFTZXJ2aWNlQW5ub3RhdGlvbjoyXG4iICsKICAgICAgIlx0ZmlsZV9vcHQxXDAyMlwwMzQuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIiArCiAgICAgICJcMDMwXDIxNlwyMzVcMzMwXDAwMyBcMDAxKFwwMDQ6OFxuXDAxNG1lc3NhZ2Vfb3B0MVwwMjJcMDM3Lmdvb2dsZS5wcm90byIgKwogICAgICAiYnVmLk1lc3NhZ2VPcHRpb25zXDAzMFwyMzRcMjU1XDMzMFwwMDMgXDAwMShcMDA1OjRcblxuZmllbGRfb3B0IiArCiAgICAgICIxXDAyMlwwMzUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9uc1wwMzBcMjEwXDI3NFwzMzBcMDAzIFwwMDEoIiArCiAgICAgICJcMDA2OjhcblxuZmllbGRfb3B0MlwwMjJcMDM1Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE8iICsKICAgICAgInB0aW9uc1wwMzBcMjcxXDI0MVwzMzFcMDAzIFwwMDEoXDAwNTpcMDAyNDI6NFxuXG5vbmVvZl9vcHQxXDAyMlwwMzUuZ29vZyIgKwogICAgICAibGUucHJvdG9idWYuT25lb2ZPcHRpb25zXDAzMFwzMTdcMjY1XDMzMFwwMDMgXDAwMShcMDA1OjJcblx0ZW51IiArCiAgICAgICJtX29wdDFcMDIyXDAzNC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnNcMDMwXDM1MFwyMzZcMzMxIiArCiAgICAgICJcMDAzIFwwMDEoXDAxNzo8XG5cMDE3ZW51bV92YWx1ZV9vcHQxXDAyMiEuZ29vZ2xlLnByb3RvYiIgKwogICAgICAidWYuRW51bVZhbHVlT3B0aW9uc1wwMzBcMzQ2XDI0MF8gXDAwMShcMDA1OjhcblwwMTRzZXJ2aWNlX28iICsKICAgICAgInB0MVwwMjJcMDM3Lmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9uc1wwMzBcMjQyXDI2NlwzNDEiICsKICAgICAgIlwwMDMgXDAwMShcMDIyOlVcblwwMTNtZXRob2Rfb3B0MVwwMjJcMDM2Lmdvb2dsZS5wcm90b2J1Zi5NIiArCiAgICAgICJldGhvZE9wdGlvbnNcMDMwXDI1NFwzMTdcMzQxXDAwMyBcMDAxKFwwMTYyXDAzNS5wcm90b2J1Zl91bml0dGVzIiArCiAgICAgICJ0Lk1ldGhvZE9wdDE6NFxuXDAxMGJvb2xfb3B0XDAyMlwwMzcuZ29vZ2xlLnByb3RvYiIgKwogICAgICAidWYuTWVzc2FnZU9wdGlvbnNcMDMwXDM1MlwyNTNcMzI2XDAwMyBcMDAxKFwwMTA6NVxuXHRpbnQzMl9vcHRcMDIyIiArCiAgICAgICJcMDM3Lmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9uc1wwMzBcMzU1XDI1MFwzMjZcMDAzIFwwMDEoIiArCiAgICAgICJcMDA1OjVcblx0aW50NjRfb3B0XDAyMlwwMzcuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UiICsKICAgICAgIk9wdGlvbnNcMDMwXDMwNlwyNDdcMzI2XDAwMyBcMDAxKFwwMDM6NlxuXG51aW50MzJfb3B0XDAyMlwwMzcuZ29vZ2xlLiIgKwogICAgICAicHJvdG9idWYuTWVzc2FnZU9wdGlvbnNcMDMwXDI2MFwyNDJcMzI2XDAwMyBcMDAxKFxyOjZcblxudWludCIgKwogICAgICAiNjRfb3B0XDAyMlwwMzcuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zXDAzMCIgKwogICAgICAiXDMzN1wyMTZcMzI2XDAwMyBcMDAxKFwwMDQ6NlxuXG5zaW50MzJfb3B0XDAyMlwwMzcuZ29vZ2xlLnByb3RvYnVmIiArCiAgICAgICIuTWVzc2FnZU9wdGlvbnNcMDMwXDMwMFwyMTBcMzI2XDAwMyBcMDAxKFwwMjE6NlxuXG5zaW50NjRfb3B0XDAyMlwwMzciICsKICAgICAgIi5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnNcMDMwXDM3N1wyMDJcMzI2XDAwMyBcMDAxKFwwMjIiICsKICAgICAgIjo3XG5cMDEzZml4ZWQzMl9vcHRcMDIyXDAzNy5nb29nbGUucHJvdG9idWYuTWVzc2FnIiArCiAgICAgICJlT3B0aW9uc1wwMzBcMzIzXDM3NlwzMjVcMDAzIFwwMDEoXDAwNzo3XG5cMDEzZml4ZWQ2NF9vcHRcMDIyXDAzNy5nb29nbCIgKwogICAgICAiZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9uc1wwMzBcMzQyXDM3NVwzMjVcMDAzIFwwMDEoXDAwNjo4XG5cMDE0c2YiICsKICAgICAgIml4ZWQzMl9vcHRcMDIyXDAzNy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGkiICsKICAgICAgIm9uc1wwMzBcMzI1XDM2MVwzMjVcMDAzIFwwMDEoXDAxNzo4XG5cMDE0c2ZpeGVkNjRfb3B0XDAyMlwwMzcuZ29vZ2xlLnByIiArCiAgICAgICJvdG9idWYuTWVzc2FnZU9wdGlvbnNcMDMwXDM0M1wyMTJcMzI1XDAwMyBcMDAxKFwwMjA6NVxuXHRmbG9hdF8iICsKICAgICAgIm9wdFwwMjJcMDM3Lmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9uc1wwMzBcMzc2XDI3M1wzMjQiICsKICAgICAgIlwwMDMgXDAwMShcMDAyOjZcblxuZG91YmxlX29wdFwwMjJcMDM3Lmdvb2dsZS5wcm90b2J1Zi5NZSIgKwogICAgICAic3NhZ2VPcHRpb25zXDAzMFwzMTVcMjUzXDMyNFwwMDMgXDAwMShcMDAxOjZcblxuc3RyaW5nX29wdFwwMjJcMDM3LmdvIiArCiAgICAgICJvZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zXDAzMFwzMDVcMjUzXDMyNFwwMDMgXDAwMShcdDo1XG4iICsKICAgICAgIlx0Ynl0ZXNfb3B0XDAyMlwwMzcuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpIiArCiAgICAgICJvbnNcMDMwXDIyNlwyNTNcMzI0XDAwMyBcMDAxKFwwMTQ6cFxuXDAxMGVudW1fb3B0XDAyMlwwMzcuZ29vZ2xlLnByb3RvYiIgKwogICAgICAidWYuTWVzc2FnZU9wdGlvbnNcMDMwXDIyMVwyNTNcMzI0XDAwMyBcMDAxKFwwMTYyOi5wcm90b2J1Zl91biIgKwogICAgICAiaXR0ZXN0LkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtLlRlc3RFbiIgKwogICAgICAidW1UeXBlOnBcblwwMjBtZXNzYWdlX3R5cGVfb3B0XDAyMlwwMzcuZ29vZ2xlLnByb3QiICsKICAgICAgIm9idWYuTWVzc2FnZU9wdGlvbnNcMDMwXDI1N1wzNjJcMzIzXDAwMyBcMDAxKFwwMTMyMi5wcm90b2J1Zl8iICsKICAgICAgInVuaXR0ZXN0LkR1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGUiICsKICAgICAgIjo2XG5cMDA0bW9vb1wwMjIlLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpIiArCiAgICAgICJvblR5cGUxXDAzMFwzMzNcMzQwXDMyM1wwMDMgXDAwMShcMDA1Ol5cblwwMDVjb3JnZVwwMjIlLnByb3RvYnVmX3VuaSIgKwogICAgICAidHRlc3QuQ29tcGxleE9wdGlvblR5cGUxXDAzMFwzMjJcMzM2XDMyM1wwMDMgXDAwMShcMDEzMiUucHJvdCIgKwogICAgICAib2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTM6OFxuXDAwNmdyYXUiICsKICAgICAgImx0XDAyMiUucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUiICsKICAgICAgIjJcMDMwXDM1N1wzNzRcMzIyXDAwMyBcMDAxKFwwMDU6X1xuXDAwNmdhcnBseVwwMjIlLnByb3RvYnVmX3VuaXR0ZXN0IiArCiAgICAgICIuQ29tcGxleE9wdGlvblR5cGUyXDAzMFwzMTBcMzY1XDMyMlwwMDMgXDAwMShcMDEzMiUucHJvdG9idWZfIiArCiAgICAgICJ1bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTE6X1xuXDAxNGNvbXBsZXhfbyIgKwogICAgICAicHQxXDAyMlwwMzcuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zXDAzMFwyNDRcMzM0XDMyMiIgKwogICAgICAiXDAwMyBcMDAxKFwwMTMyJS5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVCIgKwogICAgICAieXBlMTpfXG5cMDE0Y29tcGxleF9vcHQyXDAyMlwwMzcuZ29vZ2xlLnByb3RvYnVmLk0iICsKICAgICAgImVzc2FnZU9wdGlvbnNcMDMwXDMyNVwyMTdcMzIyXDAwMyBcMDAxKFwwMTMyJS5wcm90b2J1Zl91bml0dGUiICsKICAgICAgInN0LkNvbXBsZXhPcHRpb25UeXBlMjpfXG5cMDE0Y29tcGxleF9vcHQzXDAyMlwwMzcuIiArCiAgICAgICJnb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnNcMDMwXDM1N1wyMTNcMzIyXDAwMyBcMDAxKFwwMTMyIiArCiAgICAgICIlLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMzpXIiArCiAgICAgICJcblwwMTNjb21wbGV4b3B0NlwwMjJcMDM3Lmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlTyIgKwogICAgICAicHRpb25zXDAzMFwzMTRcMzEzXDMxN1wwMDMgXDAwMShcbjJcMDM2LnByb3RvYnVmX3VuaXR0ZXN0LkNvbXAiICsKICAgICAgImxleE9wdDY6TlxuXDAwN2ZpbGVvcHRcMDIyXDAzNC5nb29nbGUucHJvdG9idWYuRmlsIiArCiAgICAgICJlT3B0aW9uc1wwMzBcMzE3XDMzNVwyNjBcMDA3IFwwMDEoXDAxMzJcMDM0LnByb3RvYnVmX3VuaXR0ZXN0LkFnIiArCiAgICAgICJncmVnYXRlOlBcblwwMDZtc2dvcHRcMDIyXDAzNy5nb29nbGUucHJvdG9idWYuTWVzcyIgKwogICAgICAiYWdlT3B0aW9uc1wwMzBcMjMwXDM1MlwyNjBcMDA3IFwwMDEoXDAxMzJcMDM0LnByb3RvYnVmX3VuaXR0ZXN0LiIgKwogICAgICAiQWdncmVnYXRlOlBcblwwMTBmaWVsZG9wdFwwMjJcMDM1Lmdvb2dsZS5wcm90b2J1Zi4iICsKICAgICAgIkZpZWxkT3B0aW9uc1wwMzBcMjM2XDM2NFwyNjBcMDA3IFwwMDEoXDAxMzJcMDM0LnByb3RvYnVmX3VuaXR0ZXMiICsKICAgICAgInQuQWdncmVnYXRlOk5cblwwMDdlbnVtb3B0XDAyMlwwMzQuZ29vZ2xlLnByb3RvYnVmIiArCiAgICAgICIuRW51bU9wdGlvbnNcMDMwXDMyMlwyMDJcMjYxXDAwNyBcMDAxKFwwMTMyXDAzNC5wcm90b2J1Zl91bml0dGVzIiArCiAgICAgICJ0LkFnZ3JlZ2F0ZTpWXG5cbmVudW12YWxvcHRcMDIyIS5nb29nbGUucHJvdG8iICsKICAgICAgImJ1Zi5FbnVtVmFsdWVPcHRpb25zXDAzMFwzMTFcMjM3XDI2MVwwMDcgXDAwMShcMDEzMlwwMzQucHJvdG9idWYiICsKICAgICAgIl91bml0dGVzdC5BZ2dyZWdhdGU6VFxuXG5zZXJ2aWNlb3B0XDAyMlwwMzcuZ29vZyIgKwogICAgICAibGUucHJvdG9idWYuU2VydmljZU9wdGlvbnNcMDMwXDI3MVwzNTdcMjYxXDAwNyBcMDAxKFwwMTMyXDAzNC5wciIgKwogICAgICAib3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZTpSXG5cdG1ldGhvZG9wdFwwMjJcMDM2IiArCiAgICAgICIuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnNcMDMwXDIxMVwzNTFcMjYyXDAwNyBcMDAxKFwwMTMyIiArCiAgICAgICJcMDM0LnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZTpfXG5cMDIxcmVxdWlyZSIgKwogICAgICAiZF9lbnVtX29wdFwwMjJcMDM3Lmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aSIgKwogICAgICAib25zXDAzMFwyMTdcMzE1XDMxNzIgXDAwMShcMDEzMiAucHJvdG9idWZfdW5pdHRlc3QuT2xkT3B0aSIgKwogICAgICAib25UeXBlQlwzNTFcMDAxXDIwMFwwMDFcMDAxXDIxMFwwMDFcMDAxXDIyMFwwMDFcMDAxXDM2MFwzNTBcMzAxXDAzNVwzNTJcMjU1XDMwMFwzNDUkXDM3MlwzNTRcMjA1O1wzMjFcMDAxXDAxMGRcMDIyXDAxNkZpbCIgKwogICAgICAiZUFubm90YXRpb25cMDMyXDAyNlwwMjJcMDI0TmVzdGVkRmlsZUFubm90YXRpb25cIlwwMzZcMzcyXDM1NFwyMDUiICsKICAgICAgIjtcMDMxXDAyMlwwMjdGaWxlRXh0ZW5zaW9uQW5ub3RhdGlvbiokXDAxM1wwMjBcMzY2XDM1M1wyNTZcMDA3XDAzMlwwMzNcblwwMzFFIiArCiAgICAgICJtYmVkZGVkTWVzc2FnZVNldEVsZW1lbnRcMDE0Ml9cbkB0eXBlLmdvb2dsZSIgKwogICAgICAiYXBpcy5jb20vcHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVzcyIgKwogICAgICAiYWdlU2V0RWxlbWVudFwwMjJcMDMzXG5cMDMxRW1iZWRkZWRNZXNzYWdlU2V0RWxlbWUiICsKICAgICAgIm50IgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFueVByb3RvLmdldERlc2NyaXB0b3IoKSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5nZXREZXNjcmlwdG9yKCksCiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkZpZWxkMSIsICJPbmVvZkZpZWxkIiwgIk1hcEZpZWxkIiwgIkFuT25lb2YiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zX01hcEZpZWxkRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9uc19NYXBGaWVsZEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aEN1c3RvbU9wdGlvbnNfTWFwRmllbGRFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vUmVxdWVzdF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29SZXF1ZXN0X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbkZvb1JlcXVlc3RfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29DbGllbnRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbkZvb0NsaWVudE1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uRm9vU2VydmVyTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25Gb29TZXJ2ZXJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbkZvb1NlcnZlck1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW1fZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW1fZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW1fZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9EdW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0R1bW15TWVzc2FnZUludmFsaWRBc09wdGlvblR5cGVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uTWluSW50ZWdlclZhbHVlc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25NaW5JbnRlZ2VyVmFsdWVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbk1pbkludGVnZXJWYWx1ZXNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9DdXN0b21PcHRpb25NYXhJbnRlZ2VyVmFsdWVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0N1c3RvbU9wdGlvbk1heEludGVnZXJWYWx1ZXNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoOSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50c19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU2V0dGluZ1JlYWxzRnJvbVBvc2l0aXZlSW50c19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9TZXR0aW5nUmVhbHNGcm9tUG9zaXRpdmVJbnRzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMTEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NldHRpbmdSZWFsc0Zyb21OZWdhdGl2ZUludHNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU2V0dGluZ1JlYWxzRnJvbU5lZ2F0aXZlSW50c19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTFfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMTIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlMV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTFfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkZvbyIsICJGb28yIiwgIkZvbzMiLCAiRm9vNCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlMl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUyX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlMl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQmFyIiwgIkJheiIsICJGcmVkIiwgIkJhcm5leSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlMl9Db21wbGV4T3B0aW9uVHlwZTRfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTJfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTJfQ29tcGxleE9wdGlvblR5cGU0X2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlMl9Db21wbGV4T3B0aW9uVHlwZTRfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIldhbGRvIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDE0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0aW9uVHlwZTNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJNb28iLCAiQ29tcGxleE9wdGlvblR5cGU1IiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUzX0NvbXBsZXhPcHRpb25UeXBlNV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlM19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0NvbXBsZXhPcHRpb25UeXBlM19Db21wbGV4T3B0aW9uVHlwZTVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdGlvblR5cGUzX0NvbXBsZXhPcHRpb25UeXBlNV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUGx1Z2giLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Db21wbGV4T3B0Nl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdDZfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQ29tcGxleE9wdDZfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlh5enp5IiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVmFyaW91c0NvbXBsZXhPcHRpb25zX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDE2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9WYXJpb3VzQ29tcGxleE9wdGlvbnNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVmFyaW91c0NvbXBsZXhPcHRpb25zX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZU1lc3NhZ2VTZXRfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMTcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZU1lc3NhZ2VTZXRfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZVNldF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9BZ2dyZWdhdGVNZXNzYWdlU2V0RWxlbWVudF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxOCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnRfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZVNldEVsZW1lbnRfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlMiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9BZ2dyZWdhdGVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMTkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9BZ2dyZWdhdGVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkkiLCAiUyIsICJTdWIiLCAiRmlsZSIsICJNc2V0IiwgIkFueSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZU1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMjApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0FnZ3JlZ2F0ZU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQWdncmVnYXRlTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRmllbGRuYW1lIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkT3B0aW9uVHlwZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgyMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkT3B0aW9uVHlwZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRPcHRpb25UeXBlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZE9wdGlvblR5cGVfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZE9wdGlvblR5cGVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRPcHRpb25UeXBlX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkT3B0aW9uVHlwZV9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJOZXN0ZWRGaWVsZCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09sZE9wdGlvblR5cGVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMjIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09sZE9wdGlvblR5cGVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT2xkT3B0aW9uVHlwZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXdPcHRpb25UeXBlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDIzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXdPcHRpb25UeXBlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05ld09wdGlvblR5cGVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDI0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhSZXF1aXJlZEVudW1PcHRpb25fZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoUmVxdWlyZWRFbnVtT3B0aW9uX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgZmlsZU9wdDEuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgwKSk7CiAgICBtZXNzYWdlT3B0MS5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDEpKTsKICAgIGZpZWxkT3B0MS5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDIpKTsKICAgIGZpZWxkT3B0Mi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDMpKTsKICAgIG9uZW9mT3B0MS5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQpKTsKICAgIGVudW1PcHQxLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNSkpOwogICAgZW51bVZhbHVlT3B0MS5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDYpKTsKICAgIHNlcnZpY2VPcHQxLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNykpOwogICAgbWV0aG9kT3B0MS5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDgpKTsKICAgIGJvb2xPcHQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg5KSk7CiAgICBpbnQzMk9wdC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDEwKSk7CiAgICBpbnQ2NE9wdC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDExKSk7CiAgICB1aW50MzJPcHQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxMikpOwogICAgdWludDY0T3B0LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTMpKTsKICAgIHNpbnQzMk9wdC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDE0KSk7CiAgICBzaW50NjRPcHQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxNSkpOwogICAgZml4ZWQzMk9wdC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDE2KSk7CiAgICBmaXhlZDY0T3B0LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTcpKTsKICAgIHNmaXhlZDMyT3B0LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTgpKTsKICAgIHNmaXhlZDY0T3B0LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTkpKTsKICAgIGZsb2F0T3B0LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjApKTsKICAgIGRvdWJsZU9wdC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDIxKSk7CiAgICBzdHJpbmdPcHQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgyMikpOwogICAgYnl0ZXNPcHQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgyMykpOwogICAgZW51bU9wdC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDI0KSk7CiAgICBtZXNzYWdlVHlwZU9wdC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDI1KSk7CiAgICBtb29vLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjYpKTsKICAgIGNvcmdlLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjcpKTsKICAgIGdyYXVsdC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDI4KSk7CiAgICBnYXJwbHkuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgyOSkpOwogICAgY29tcGxleE9wdDEuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzMCkpOwogICAgY29tcGxleE9wdDIuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzMSkpOwogICAgY29tcGxleE9wdDMuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzMikpOwogICAgY29tcGxleE9wdDYuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzMykpOwogICAgZmlsZW9wdC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDM0KSk7CiAgICBtc2dvcHQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzNSkpOwogICAgZmllbGRvcHQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzNikpOwogICAgZW51bW9wdC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDM3KSk7CiAgICBlbnVtdmFsb3B0LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMzgpKTsKICAgIHNlcnZpY2VvcHQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzOSkpOwogICAgbWV0aG9kb3B0LmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNDApKTsKICAgIHJlcXVpcmVkRW51bU9wdC5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQxKSk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5ID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5Lm5ld0luc3RhbmNlKCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLkFnZ3JlZ2F0ZU1lc3NhZ2VTZXRFbGVtZW50Lm1lc3NhZ2VTZXRFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0LmNvbXBsZXhPcHQ0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuYm9vbE9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmJ5dGVzT3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuY29tcGxleE9wdDEpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5jb21wbGV4T3B0Mik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmNvbXBsZXhPcHQzKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuY29tcGxleE9wdDYpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5jb3JnZSk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmRvdWJsZU9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmVudW1PcHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5lbnVtT3B0MSk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmVudW1WYWx1ZU9wdDEpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5lbnVtb3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuZW51bXZhbG9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmZpZWxkT3B0MSk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmZpZWxkT3B0Mik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmZpZWxkb3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuZmlsZU9wdDEpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5maWxlb3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuZml4ZWQzMk9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmZpeGVkNjRPcHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5mbG9hdE9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmdhcnBseSk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmdyYXVsdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLmludDMyT3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuaW50NjRPcHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5tZXNzYWdlT3B0MSk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLm1ldGhvZE9wdDEpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5tZXRob2RvcHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5tb29vKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMubXNnb3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMub25lb2ZPcHQxKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMucmVxdWlyZWRFbnVtT3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuc2VydmljZU9wdDEpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5zZXJ2aWNlb3B0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEN1c3RvbU9wdGlvbnMuc2ZpeGVkMzJPcHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5zZml4ZWQ2NE9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLnNpbnQzMk9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLnNpbnQ2NE9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLnN0cmluZ09wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLnVpbnQzMk9wdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RDdXN0b21PcHRpb25zLnVpbnQ2NE9wdCk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgICAgLmludGVybmFsVXBkYXRlRmlsZURlc2NyaXB0b3IoZGVzY3JpcHRvciwgcmVnaXN0cnkpOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BbnlQcm90by5nZXREZXNjcmlwdG9yKCk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuZ2V0RGVzY3JpcHRvcigpOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEAmx1vccm2AADJtgAALwAAAHByb3RvYnVmX3VuaXR0ZXN0L1VuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfZW1iZWRfb3B0aW1pemVfZm9yLnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKCnB1YmxpYyBmaW5hbCBjbGFzcyBVbml0dGVzdEVtYmVkT3B0aW1pemVGb3IgewogIHByaXZhdGUgVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RFbWJlZE9wdGltaXplZEZvclNpemVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0IHRoYXQgZW1iZWRkaW5nIGEgbWVzc2FnZSB3aGljaCBoYXMgb3B0aW1pemVfZm9yID0gQ09ERV9TSVpFIGludG8KICAgICAqIG9uZSBvcHRpbWl6ZWQgZm9yIHNwZWVkIHdvcmtzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRlc3QgdGhhdCBlbWJlZGRpbmcgYSBtZXNzYWdlIHdoaWNoIGhhcyBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkUgaW50bwogICAgICogb25lIG9wdGltaXplZCBmb3Igc3BlZWQgd29ya3MuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxNZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplIGdldE9wdGlvbmFsTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdCB0aGF0IGVtYmVkZGluZyBhIG1lc3NhZ2Ugd2hpY2ggaGFzIG9wdGltaXplX2ZvciA9IENPREVfU0laRSBpbnRvCiAgICAgKiBvbmUgb3B0aW1pemVkIGZvciBzcGVlZCB3b3Jrcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemVPckJ1aWxkZXIgZ2V0T3B0aW9uYWxNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplPiAKICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgZ2V0UmVwZWF0ZWRNZXNzYWdlKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZE1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplT3JCdWlsZGVyIGdldFJlcGVhdGVkTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplKQogICAgICBUZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RFbWJlZE9wdGltaXplZEZvclNpemUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplKCkgewogICAgICByZXBlYXRlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RFbWJlZE9wdGltaXplZEZvclNpemUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbWJlZE9wdGltaXplZEZvclNpemVfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbWJlZE9wdGltaXplZEZvclNpemVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yLlRlc3RFbWJlZE9wdGltaXplZEZvclNpemUuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSBvcHRpb25hbE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdCB0aGF0IGVtYmVkZGluZyBhIG1lc3NhZ2Ugd2hpY2ggaGFzIG9wdGltaXplX2ZvciA9IENPREVfU0laRSBpbnRvCiAgICAgKiBvbmUgb3B0aW1pemVkIGZvciBzcGVlZCB3b3Jrcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdCB0aGF0IGVtYmVkZGluZyBhIG1lc3NhZ2Ugd2hpY2ggaGFzIG9wdGltaXplX2ZvciA9IENPREVfU0laRSBpbnRvCiAgICAgKiBvbmUgb3B0aW1pemVkIGZvciBzcGVlZCB3b3Jrcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplIGdldE9wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdCB0aGF0IGVtYmVkZGluZyBhIG1lc3NhZ2Ugd2hpY2ggaGFzIG9wdGltaXplX2ZvciA9IENPREVfU0laRSBpbnRvCiAgICAgKiBvbmUgb3B0aW1pemVkIGZvciBzcGVlZCB3b3Jrcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplT3JCdWlsZGVyIGdldE9wdGlvbmFsTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplPiByZXBlYXRlZE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZT4gZ2V0UmVwZWF0ZWRNZXNzYWdlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRNZXNzYWdlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgZ2V0UmVwZWF0ZWRNZXNzYWdlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZU9yQnVpbGRlciBnZXRSZXBlYXRlZE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKGhhc09wdGlvbmFsTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbE1lc3NhZ2UoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ2V0UmVwZWF0ZWRNZXNzYWdlQ291bnQoKTsgaSsrKSB7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZE1lc3NhZ2UoaSkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgZ2V0T3B0aW9uYWxNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMiwgcmVwZWF0ZWRNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0T3B0aW9uYWxNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCByZXBlYXRlZE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yLlRlc3RFbWJlZE9wdGltaXplZEZvclNpemUpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplKSBvYmo7CgogICAgICBpZiAoaGFzT3B0aW9uYWxNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbE1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRNZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkTWVzc2FnZUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzT3B0aW9uYWxNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbE1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZE1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkTWVzc2FnZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yLlRlc3RFbWJlZE9wdGltaXplZEZvclNpemUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yLlRlc3RFbWJlZE9wdGltaXplZEZvclNpemUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbWJlZE9wdGltaXplZEZvclNpemV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbWJlZE9wdGltaXplZEZvclNpemVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yLlRlc3RFbWJlZE9wdGltaXplZEZvclNpemUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yLlRlc3RFbWJlZE9wdGltaXplZEZvclNpemUubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIG9wdGlvbmFsTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yLlRlc3RFbWJlZE9wdGltaXplZEZvclNpemUodGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yLlRlc3RFbWJlZE9wdGltaXplZEZvclNpemUgcmVzdWx0KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRNZXNzYWdlXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZE1lc3NhZ2VfID0gcmVwZWF0ZWRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkTWVzc2FnZV8gPSByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yLlRlc3RFbWJlZE9wdGltaXplZEZvclNpemUgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxNZXNzYWdlXyA9IG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsTWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yLlRlc3RFbWJlZE9wdGltaXplZEZvclNpemUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yLlRlc3RFbWJlZE9wdGltaXplZEZvclNpemUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RFbWJlZE9wdGltaXplRm9yLlRlc3RFbWJlZE9wdGltaXplZEZvclNpemUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbE1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbE1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkTWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKGhhc09wdGlvbmFsTWVzc2FnZSgpKSB7CiAgICAgICAgICBpZiAoIWdldE9wdGlvbmFsTWVzc2FnZSgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ2V0UmVwZWF0ZWRNZXNzYWdlQ291bnQoKTsgaSsrKSB7CiAgICAgICAgICBpZiAoIWdldFJlcGVhdGVkTWVzc2FnZShpKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgb3B0aW9uYWxNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplT3JCdWlsZGVyPiBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRlc3QgdGhhdCBlbWJlZGRpbmcgYSBtZXNzYWdlIHdoaWNoIGhhcyBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkUgaW50bwogICAgICAgKiBvbmUgb3B0aW1pemVkIGZvciBzcGVlZCB3b3Jrcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRlc3QgdGhhdCBlbWJlZGRpbmcgYSBtZXNzYWdlIHdoaWNoIGhhcyBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkUgaW50bwogICAgICAgKiBvbmUgb3B0aW1pemVkIGZvciBzcGVlZCB3b3Jrcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplIGdldE9wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGVzdCB0aGF0IGVtYmVkZGluZyBhIG1lc3NhZ2Ugd2hpY2ggaGFzIG9wdGltaXplX2ZvciA9IENPREVfU0laRSBpbnRvCiAgICAgICAqIG9uZSBvcHRpbWl6ZWQgZm9yIHNwZWVkIHdvcmtzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUZXN0IHRoYXQgZW1iZWRkaW5nIGEgbWVzc2FnZSB3aGljaCBoYXMgb3B0aW1pemVfZm9yID0gQ09ERV9TSVpFIGludG8KICAgICAgICogb25lIG9wdGltaXplZCBmb3Igc3BlZWQgd29ya3MuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxNZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRlc3QgdGhhdCBlbWJlZGRpbmcgYSBtZXNzYWdlIHdoaWNoIGhhcyBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkUgaW50bwogICAgICAgKiBvbmUgb3B0aW1pemVkIGZvciBzcGVlZCB3b3Jrcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRlc3QgdGhhdCBlbWJlZGRpbmcgYSBtZXNzYWdlIHdoaWNoIGhhcyBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkUgaW50bwogICAgICAgKiBvbmUgb3B0aW1pemVkIGZvciBzcGVlZCB3b3Jrcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRlc3QgdGhhdCBlbWJlZGRpbmcgYSBtZXNzYWdlIHdoaWNoIGhhcyBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkUgaW50bwogICAgICAgKiBvbmUgb3B0aW1pemVkIGZvciBzcGVlZCB3b3Jrcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZS5CdWlsZGVyIGdldE9wdGlvbmFsTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRlc3QgdGhhdCBlbWJlZGRpbmcgYSBtZXNzYWdlIHdoaWNoIGhhcyBvcHRpbWl6ZV9mb3IgPSBDT0RFX1NJWkUgaW50bwogICAgICAgKiBvbmUgb3B0aW1pemVkIGZvciBzcGVlZCB3b3Jrcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZU9yQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGVzdCB0aGF0IGVtYmVkZGluZyBhIG1lc3NhZ2Ugd2hpY2ggaGFzIG9wdGltaXplX2ZvciA9IENPREVfU0laRSBpbnRvCiAgICAgICAqIG9uZSBvcHRpbWl6ZWQgZm9yIHNwZWVkIHdvcmtzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemU+IHJlcGVhdGVkTWVzc2FnZV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZT4ocmVwZWF0ZWRNZXNzYWdlXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemVPckJ1aWxkZXI+IHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZT4gZ2V0UmVwZWF0ZWRNZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTWVzc2FnZV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTWVzc2FnZUNvdW50KCkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplIGdldFJlcGVhdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRNZXNzYWdlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZE1lc3NhZ2VfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplT3JCdWlsZGVyIGdldFJlcGVhdGVkTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemVPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRNZXNzYWdlXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUuQnVpbGRlciBhZGRSZXBlYXRlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLkJ1aWxkZXIgYWRkUmVwZWF0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemVPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdEVtYmVkT3B0aW1pemVGb3IuVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFbWJlZE9wdGltaXplZEZvclNpemU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RFbWJlZE9wdGltaXplZEZvclNpemUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFbWJlZE9wdGltaXplZEZvclNpemU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbWJlZE9wdGltaXplZEZvclNpemVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZV9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuMWdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9lbWJlZF9vcHRpbWl6IiArCiAgICAgICJlX2Zvci5wcm90b1wwMjJcMDIxcHJvdG9idWZfdW5pdHRlc3RcMDMyK2dvb2dsZS9wIiArCiAgICAgICJyb3RvYnVmL3VuaXR0ZXN0X29wdGltaXplX2Zvci5wcm90b1wiXDI0MVwwMDFcblwwMzEiICsKICAgICAgIlRlc3RFbWJlZE9wdGltaXplZEZvclNpemVcMDIyQVxuXDAyMG9wdGlvbmFsX21lIiArCiAgICAgICJzc2FnZVwwMzBcMDAxIFwwMDEoXDAxMzJcJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aSIgKwogICAgICAibWl6ZWRGb3JTaXplXDAyMkFcblwwMjByZXBlYXRlZF9tZXNzYWdlXDAzMFwwMDIgXDAwMyhcMDEzMlwnIiArCiAgICAgICIucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemVCIiArCiAgICAgICJcMDAySFwwMDEiCiAgICB9OwogICAgZGVzY3JpcHRvciA9IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgLmludGVybmFsQnVpbGRHZW5lcmF0ZWRGaWxlRnJvbShkZXNjcmlwdG9yRGF0YSwKICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcltdIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuZ2V0RGVzY3JpcHRvcigpLAogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbWJlZE9wdGltaXplZEZvclNpemVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVtYmVkT3B0aW1pemVkRm9yU2l6ZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW1iZWRPcHRpbWl6ZWRGb3JTaXplX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbE1lc3NhZ2UiLCAiUmVwZWF0ZWRNZXNzYWdlIiwgfSk7CiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLmdldERlc2NyaXB0b3IoKTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAEYv16pukAAAbpAAADEAAABwcm90b2J1Zl91bml0dGVzdC9Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfbGl0ZV9pbXBvcnRzX25vbmxpdGUucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIFVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlIHsKICBwcml2YXRlIFVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RMaXRlSW1wb3J0c05vbmxpdGVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdExpdGVJbXBvcnRzTm9ubGl0ZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbWVzc2FnZS4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFZlcmlmaWVzIHRoYXQgdHJhbnNpdGl2ZSByZXF1aXJlZCBmaWVsZHMgZ2VuZXJhdGVzIHZhbGlkIGNvZGUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG1lc3NhZ2Vfd2l0aF9yZXF1aXJlZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtZXNzYWdlV2l0aFJlcXVpcmVkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNNZXNzYWdlV2l0aFJlcXVpcmVkKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBWZXJpZmllcyB0aGF0IHRyYW5zaXRpdmUgcmVxdWlyZWQgZmllbGRzIGdlbmVyYXRlcyB2YWxpZCBjb2RlLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBtZXNzYWdlX3dpdGhfcmVxdWlyZWQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VXaXRoUmVxdWlyZWQuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldE1lc3NhZ2VXaXRoUmVxdWlyZWQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFZlcmlmaWVzIHRoYXQgdHJhbnNpdGl2ZSByZXF1aXJlZCBmaWVsZHMgZ2VuZXJhdGVzIHZhbGlkIGNvZGUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG1lc3NhZ2Vfd2l0aF9yZXF1aXJlZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciBnZXRNZXNzYWdlV2l0aFJlcXVpcmVkT3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMaXRlSW1wb3J0c05vbmxpdGV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0TGl0ZUltcG9ydHNOb25saXRlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMaXRlSW1wb3J0c05vbmxpdGUpCiAgICAgIFRlc3RMaXRlSW1wb3J0c05vbmxpdGVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RMaXRlSW1wb3J0c05vbmxpdGUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdExpdGVJbXBvcnRzTm9ubGl0ZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RMaXRlSW1wb3J0c05vbmxpdGUoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdExpdGVJbXBvcnRzTm9ubGl0ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TGl0ZUltcG9ydHNOb25saXRlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RMaXRlSW1wb3J0c05vbmxpdGUuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RMaXRlSW1wb3J0c05vbmxpdGVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5UZXN0TGl0ZUltcG9ydHNOb25saXRlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5UZXN0TGl0ZUltcG9ydHNOb25saXRlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc01lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBtZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBtZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX1dJVEhfUkVRVUlSRURfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgbWVzc2FnZVdpdGhSZXF1aXJlZF87CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBWZXJpZmllcyB0aGF0IHRyYW5zaXRpdmUgcmVxdWlyZWQgZmllbGRzIGdlbmVyYXRlcyB2YWxpZCBjb2RlLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBtZXNzYWdlX3dpdGhfcmVxdWlyZWQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZVdpdGhSZXF1aXJlZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc01lc3NhZ2VXaXRoUmVxdWlyZWQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFZlcmlmaWVzIHRoYXQgdHJhbnNpdGl2ZSByZXF1aXJlZCBmaWVsZHMgZ2VuZXJhdGVzIHZhbGlkIGNvZGUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG1lc3NhZ2Vfd2l0aF9yZXF1aXJlZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbWVzc2FnZVdpdGhSZXF1aXJlZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldE1lc3NhZ2VXaXRoUmVxdWlyZWQoKSB7CiAgICAgIHJldHVybiBtZXNzYWdlV2l0aFJlcXVpcmVkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlV2l0aFJlcXVpcmVkXzsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFZlcmlmaWVzIHRoYXQgdHJhbnNpdGl2ZSByZXF1aXJlZCBmaWVsZHMgZ2VuZXJhdGVzIHZhbGlkIGNvZGUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG1lc3NhZ2Vfd2l0aF9yZXF1aXJlZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXIgZ2V0TWVzc2FnZVdpdGhSZXF1aXJlZE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG1lc3NhZ2VXaXRoUmVxdWlyZWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1lc3NhZ2VXaXRoUmVxdWlyZWRfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmIChoYXNNZXNzYWdlV2l0aFJlcXVpcmVkKCkpIHsKICAgICAgICBpZiAoIWdldE1lc3NhZ2VXaXRoUmVxdWlyZWQoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMiwgZ2V0TWVzc2FnZVdpdGhSZXF1aXJlZCgpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGdldE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIsIGdldE1lc3NhZ2VXaXRoUmVxdWlyZWQoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RMaXRlSW1wb3J0c05vbmxpdGUuVGVzdExpdGVJbXBvcnRzTm9ubGl0ZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RMaXRlSW1wb3J0c05vbmxpdGUuVGVzdExpdGVJbXBvcnRzTm9ubGl0ZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5UZXN0TGl0ZUltcG9ydHNOb25saXRlKSBvYmo7CgogICAgICBpZiAoaGFzTWVzc2FnZSgpICE9IG90aGVyLmhhc01lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc01lc3NhZ2VXaXRoUmVxdWlyZWQoKSAhPSBvdGhlci5oYXNNZXNzYWdlV2l0aFJlcXVpcmVkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc01lc3NhZ2VXaXRoUmVxdWlyZWQoKSkgewogICAgICAgIGlmICghZ2V0TWVzc2FnZVdpdGhSZXF1aXJlZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TWVzc2FnZVdpdGhSZXF1aXJlZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc01lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNNZXNzYWdlV2l0aFJlcXVpcmVkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNRVNTQUdFX1dJVEhfUkVRVUlSRURfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE1lc3NhZ2VXaXRoUmVxdWlyZWQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5UZXN0TGl0ZUltcG9ydHNOb25saXRlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5UZXN0TGl0ZUltcG9ydHNOb25saXRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5UZXN0TGl0ZUltcG9ydHNOb25saXRlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RMaXRlSW1wb3J0c05vbmxpdGUuVGVzdExpdGVJbXBvcnRzTm9ubGl0ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5UZXN0TGl0ZUltcG9ydHNOb25saXRlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdExpdGVJbXBvcnRzTm9ubGl0ZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMaXRlSW1wb3J0c05vbmxpdGUpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RMaXRlSW1wb3J0c05vbmxpdGUuVGVzdExpdGVJbXBvcnRzTm9ubGl0ZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdExpdGVJbXBvcnRzTm9ubGl0ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdExpdGVJbXBvcnRzTm9ubGl0ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5UZXN0TGl0ZUltcG9ydHNOb25saXRlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5UZXN0TGl0ZUltcG9ydHNOb25saXRlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RMaXRlSW1wb3J0c05vbmxpdGUuVGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRNZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBtZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBtZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgbWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgbWVzc2FnZVdpdGhSZXF1aXJlZF8gPSBudWxsOwogICAgICAgIGlmIChtZXNzYWdlV2l0aFJlcXVpcmVkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZVdpdGhSZXF1aXJlZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG1lc3NhZ2VXaXRoUmVxdWlyZWRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdExpdGVJbXBvcnRzTm9ubGl0ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5UZXN0TGl0ZUltcG9ydHNOb25saXRlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RMaXRlSW1wb3J0c05vbmxpdGUuVGVzdExpdGVJbXBvcnRzTm9ubGl0ZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RMaXRlSW1wb3J0c05vbmxpdGUuVGVzdExpdGVJbXBvcnRzTm9ubGl0ZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5tZXNzYWdlXyA9IG1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBtZXNzYWdlXwogICAgICAgICAgICAgIDogbWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubWVzc2FnZVdpdGhSZXF1aXJlZF8gPSBtZXNzYWdlV2l0aFJlcXVpcmVkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gbWVzc2FnZVdpdGhSZXF1aXJlZF8KICAgICAgICAgICAgICA6IG1lc3NhZ2VXaXRoUmVxdWlyZWRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RMaXRlSW1wb3J0c05vbmxpdGUuVGVzdExpdGVJbXBvcnRzTm9ubGl0ZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RMaXRlSW1wb3J0c05vbmxpdGUuVGVzdExpdGVJbXBvcnRzTm9ubGl0ZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5UZXN0TGl0ZUltcG9ydHNOb25saXRlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlTWVzc2FnZShvdGhlci5nZXRNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzTWVzc2FnZVdpdGhSZXF1aXJlZCgpKSB7CiAgICAgICAgICBtZXJnZU1lc3NhZ2VXaXRoUmVxdWlyZWQob3RoZXIuZ2V0TWVzc2FnZVdpdGhSZXF1aXJlZCgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmIChoYXNNZXNzYWdlV2l0aFJlcXVpcmVkKCkpIHsKICAgICAgICAgIGlmICghZ2V0TWVzc2FnZVdpdGhSZXF1aXJlZCgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRNZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IG1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBtZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE1lc3NhZ2UoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChtZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgbWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBtZXNzYWdlXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBtZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBtZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAobWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBtZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBtZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChtZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgbWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIG1lc3NhZ2VXaXRoUmVxdWlyZWRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+IG1lc3NhZ2VXaXRoUmVxdWlyZWRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFZlcmlmaWVzIHRoYXQgdHJhbnNpdGl2ZSByZXF1aXJlZCBmaWVsZHMgZ2VuZXJhdGVzIHZhbGlkIGNvZGUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG1lc3NhZ2Vfd2l0aF9yZXF1aXJlZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1lc3NhZ2VXaXRoUmVxdWlyZWQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTWVzc2FnZVdpdGhSZXF1aXJlZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFZlcmlmaWVzIHRoYXQgdHJhbnNpdGl2ZSByZXF1aXJlZCBmaWVsZHMgZ2VuZXJhdGVzIHZhbGlkIGNvZGUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG1lc3NhZ2Vfd2l0aF9yZXF1aXJlZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlV2l0aFJlcXVpcmVkLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldE1lc3NhZ2VXaXRoUmVxdWlyZWQoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VXaXRoUmVxdWlyZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZVdpdGhSZXF1aXJlZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZVdpdGhSZXF1aXJlZF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlV2l0aFJlcXVpcmVkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVmVyaWZpZXMgdGhhdCB0cmFuc2l0aXZlIHJlcXVpcmVkIGZpZWxkcyBnZW5lcmF0ZXMgdmFsaWQgY29kZS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgbWVzc2FnZV93aXRoX3JlcXVpcmVkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNZXNzYWdlV2l0aFJlcXVpcmVkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VXaXRoUmVxdWlyZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG1lc3NhZ2VXaXRoUmVxdWlyZWRfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VXaXRoUmVxdWlyZWRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBWZXJpZmllcyB0aGF0IHRyYW5zaXRpdmUgcmVxdWlyZWQgZmllbGRzIGdlbmVyYXRlcyB2YWxpZCBjb2RlLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBtZXNzYWdlX3dpdGhfcmVxdWlyZWQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE1lc3NhZ2VXaXRoUmVxdWlyZWQoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChtZXNzYWdlV2l0aFJlcXVpcmVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZVdpdGhSZXF1aXJlZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZVdpdGhSZXF1aXJlZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFZlcmlmaWVzIHRoYXQgdHJhbnNpdGl2ZSByZXF1aXJlZCBmaWVsZHMgZ2VuZXJhdGVzIHZhbGlkIGNvZGUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG1lc3NhZ2Vfd2l0aF9yZXF1aXJlZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VNZXNzYWdlV2l0aFJlcXVpcmVkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VXaXRoUmVxdWlyZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkgJiYKICAgICAgICAgICAgbWVzc2FnZVdpdGhSZXF1aXJlZF8gIT0gbnVsbCAmJgogICAgICAgICAgICBtZXNzYWdlV2l0aFJlcXVpcmVkXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRNZXNzYWdlV2l0aFJlcXVpcmVkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBtZXNzYWdlV2l0aFJlcXVpcmVkXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlV2l0aFJlcXVpcmVkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG1lc3NhZ2VXaXRoUmVxdWlyZWRfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVmVyaWZpZXMgdGhhdCB0cmFuc2l0aXZlIHJlcXVpcmVkIGZpZWxkcyBnZW5lcmF0ZXMgdmFsaWQgY29kZS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgbWVzc2FnZV93aXRoX3JlcXVpcmVkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1lc3NhZ2VXaXRoUmVxdWlyZWQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG1lc3NhZ2VXaXRoUmVxdWlyZWRfID0gbnVsbDsKICAgICAgICBpZiAobWVzc2FnZVdpdGhSZXF1aXJlZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VXaXRoUmVxdWlyZWRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBtZXNzYWdlV2l0aFJlcXVpcmVkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVmVyaWZpZXMgdGhhdCB0cmFuc2l0aXZlIHJlcXVpcmVkIGZpZWxkcyBnZW5lcmF0ZXMgdmFsaWQgY29kZS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgbWVzc2FnZV93aXRoX3JlcXVpcmVkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciBnZXRNZXNzYWdlV2l0aFJlcXVpcmVkQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE1lc3NhZ2VXaXRoUmVxdWlyZWRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFZlcmlmaWVzIHRoYXQgdHJhbnNpdGl2ZSByZXF1aXJlZCBmaWVsZHMgZ2VuZXJhdGVzIHZhbGlkIGNvZGUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG1lc3NhZ2Vfd2l0aF9yZXF1aXJlZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyIGdldE1lc3NhZ2VXaXRoUmVxdWlyZWRPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VXaXRoUmVxdWlyZWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZVdpdGhSZXF1aXJlZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VXaXRoUmVxdWlyZWRfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZVdpdGhSZXF1aXJlZF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBWZXJpZmllcyB0aGF0IHRyYW5zaXRpdmUgcmVxdWlyZWQgZmllbGRzIGdlbmVyYXRlcyB2YWxpZCBjb2RlLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBtZXNzYWdlX3dpdGhfcmVxdWlyZWQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRNZXNzYWdlV2l0aFJlcXVpcmVkRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChtZXNzYWdlV2l0aFJlcXVpcmVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZVdpdGhSZXF1aXJlZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZVdpdGhSZXF1aXJlZCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgbWVzc2FnZVdpdGhSZXF1aXJlZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWVzc2FnZVdpdGhSZXF1aXJlZEJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMaXRlSW1wb3J0c05vbmxpdGUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMaXRlSW1wb3J0c05vbmxpdGUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5UZXN0TGl0ZUltcG9ydHNOb25saXRlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLlRlc3RMaXRlSW1wb3J0c05vbmxpdGUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TGl0ZUltcG9ydHNOb25saXRlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RMaXRlSW1wb3J0c05vbmxpdGU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TGl0ZUltcG9ydHNOb25saXRlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdExpdGVJbXBvcnRzTm9ubGl0ZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TGl0ZUltcG9ydHNOb25saXRlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdExpdGVJbXBvcnRzTm9ubGl0ZS5UZXN0TGl0ZUltcG9ydHNOb25saXRlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RMaXRlSW1wb3J0c05vbmxpdGVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdExpdGVJbXBvcnRzTm9ubGl0ZV9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuM2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9saXRlX2ltcG9ydHNfIiArCiAgICAgICJub25saXRlLnByb3RvXDAyMlwwMjFwcm90b2J1Zl91bml0dGVzdFwwMzJcMDM2Z29vZ2xlIiArCiAgICAgICIvcHJvdG9idWYvdW5pdHRlc3QucHJvdG9cIlwyMTJcMDAxXG5cMDI2VGVzdExpdGVJbXAiICsKICAgICAgIm9ydHNOb25saXRlXDAyMjBcblwwMDdtZXNzYWdlXDAzMFwwMDEgXDAwMShcMDEzMlwwMzcucHJvdG9idWZfIiArCiAgICAgICJ1bml0dGVzdC5UZXN0QWxsVHlwZXNcMDIyPlxuXDAyNW1lc3NhZ2Vfd2l0aF9yZSIgKwogICAgICAicXVpcmVkXDAzMFwwMDIgXDAwMShcMDEzMlwwMzcucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcSIgKwogICAgICAidWlyZWRCXDAwMkhcMDAzIgogICAgfTsKICAgIGRlc2NyaXB0b3IgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIC5pbnRlcm5hbEJ1aWxkR2VuZXJhdGVkRmlsZUZyb20oZGVzY3JpcHRvckRhdGEsCiAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3JbXSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmdldERlc2NyaXB0b3IoKSwKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TGl0ZUltcG9ydHNOb25saXRlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RMaXRlSW1wb3J0c05vbmxpdGVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdExpdGVJbXBvcnRzTm9ubGl0ZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiTWVzc2FnZSIsICJNZXNzYWdlV2l0aFJlcXVpcmVkIiwgfSk7CiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmdldERlc2NyaXB0b3IoKTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAEuPDsX4nwMA+J8DACMAAABwcm90b2J1Zl91bml0dGVzdC9Vbml0dGVzdE1zZXQuamF2YS8vIEdlbmVyYXRlZCBieSB0aGUgcHJvdG9jb2wgYnVmZmVyIGNvbXBpbGVyLiAgRE8gTk9UIEVESVQhCi8vIHNvdXJjZTogZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0X21zZXQucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIFVuaXR0ZXN0TXNldCB7CiAgcHJpdmF0ZSBVbml0dGVzdE1zZXQoKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMS5tZXNzYWdlU2V0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yLm1lc3NhZ2VTZXRFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMubWVzc2FnZVNldEV4dGVuc2lvbik7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE1lc3NhZ2VTZXRDb250YWluZXJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZVNldCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTWVzc2FnZVNldCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VTZXQuCiAgICAgKi8KICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgZ2V0TWVzc2FnZVNldCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldE9yQnVpbGRlciBnZXRNZXNzYWdlU2V0T3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIpCiAgICAgIFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TWVzc2FnZVNldENvbnRhaW5lci5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TWVzc2FnZVNldENvbnRhaW5lcihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNldENvbnRhaW5lcl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRDb250YWluZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lci5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUVTU0FHRV9TRVRfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCBtZXNzYWdlU2V0XzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1lc3NhZ2VTZXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNNZXNzYWdlU2V0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCBtZXNzYWdlX3NldCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbWVzc2FnZVNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgZ2V0TWVzc2FnZVNldCgpIHsKICAgICAgcmV0dXJuIG1lc3NhZ2VTZXRfID09IG51bGwgPyBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZVNldF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCBtZXNzYWdlX3NldCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldE9yQnVpbGRlciBnZXRNZXNzYWdlU2V0T3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gbWVzc2FnZVNldF8gPT0gbnVsbCA/IHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlU2V0XzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoaGFzTWVzc2FnZVNldCgpKSB7CiAgICAgICAgaWYgKCFnZXRNZXNzYWdlU2V0KCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgZ2V0TWVzc2FnZVNldCgpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGdldE1lc3NhZ2VTZXQoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyKSBvYmo7CgogICAgICBpZiAoaGFzTWVzc2FnZVNldCgpICE9IG90aGVyLmhhc01lc3NhZ2VTZXQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTWVzc2FnZVNldCgpKSB7CiAgICAgICAgaWYgKCFnZXRNZXNzYWdlU2V0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRNZXNzYWdlU2V0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzTWVzc2FnZVNldCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUVTU0FHRV9TRVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE1lc3NhZ2VTZXQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldENvbnRhaW5lcn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lck9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0Q29udGFpbmVyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRDb250YWluZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0TWVzc2FnZVNldEZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgbWVzc2FnZVNldF8gPSBudWxsOwogICAgICAgIGlmIChtZXNzYWdlU2V0QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZVNldEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG1lc3NhZ2VTZXRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0Q29udGFpbmVyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5tZXNzYWdlU2V0XyA9IG1lc3NhZ2VTZXRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBtZXNzYWdlU2V0XwogICAgICAgICAgICAgIDogbWVzc2FnZVNldEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lcilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzTWVzc2FnZVNldCgpKSB7CiAgICAgICAgICBtZXJnZU1lc3NhZ2VTZXQob3RoZXIuZ2V0TWVzc2FnZVNldCgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmIChoYXNNZXNzYWdlU2V0KCkpIHsKICAgICAgICAgIGlmICghZ2V0TWVzc2FnZVNldCgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZVNldEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2VTZXRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LCBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LkJ1aWxkZXIsIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRPckJ1aWxkZXI+IG1lc3NhZ2VTZXRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCBtZXNzYWdlX3NldCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1lc3NhZ2VTZXQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTWVzc2FnZVNldCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCBtZXNzYWdlX3NldCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlU2V0LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgZ2V0TWVzc2FnZVNldCgpIHsKICAgICAgICBpZiAobWVzc2FnZVNldEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlU2V0XyA9PSBudWxsID8gcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1lc3NhZ2VTZXRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZVNldEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCBtZXNzYWdlX3NldCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TWVzc2FnZVNldChwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0IHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VTZXRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG1lc3NhZ2VTZXRfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VTZXRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE1lc3NhZ2VTZXQoCiAgICAgICAgICBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VTZXRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBtZXNzYWdlU2V0XyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlU2V0QnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU1lc3NhZ2VTZXQocHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCB2YWx1ZSkgewogICAgICAgIGlmIChtZXNzYWdlU2V0QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICAgIG1lc3NhZ2VTZXRfICE9IG51bGwgJiYKICAgICAgICAgICAgbWVzc2FnZVNldF8gIT0gcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRNZXNzYWdlU2V0QnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBtZXNzYWdlU2V0XyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlU2V0QnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG1lc3NhZ2VTZXRfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1lc3NhZ2VTZXQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG1lc3NhZ2VTZXRfID0gbnVsbDsKICAgICAgICBpZiAobWVzc2FnZVNldEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VTZXRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBtZXNzYWdlU2V0QnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5CdWlsZGVyIGdldE1lc3NhZ2VTZXRCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0TWVzc2FnZVNldEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IG1lc3NhZ2Vfc2V0ID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldE9yQnVpbGRlciBnZXRNZXNzYWdlU2V0T3JCdWlsZGVyKCkgewogICAgICAgIGlmIChtZXNzYWdlU2V0QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VTZXRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlU2V0XyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZVNldF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgbWVzc2FnZV9zZXQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQsIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQuQnVpbGRlciwgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRNZXNzYWdlU2V0RmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChtZXNzYWdlU2V0QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZVNldEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCwgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5CdWlsZGVyLCBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0T3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZVNldCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgbWVzc2FnZVNldF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWVzc2FnZVNldEJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldENvbnRhaW5lcikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZVNldENvbnRhaW5lcj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZVNldENvbnRhaW5lcj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgY29udGFpbmVyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNvbnRhaW5lciBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQ29udGFpbmVyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBjb250YWluZXIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvbnRhaW5lci4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGdldENvbnRhaW5lcigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgY29udGFpbmVyID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lck9yQnVpbGRlciBnZXRDb250YWluZXJPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBjaGlsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQ2hpbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGNoaWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGdldENoaWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBjaGlsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXJPckJ1aWxkZXIgZ2V0Q2hpbGRPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBsYXp5X2NoaWxkID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbGF6eUNoaWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMYXp5Q2hpbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGxhenlfY2hpbGQgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbGF6eUNoaWxkLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgZ2V0TGF6eUNoaWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBsYXp5X2NoaWxkID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyT3JCdWlsZGVyIGdldExhenlDaGlsZE9yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyKQogICAgICBOZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lck9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBOZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBOZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPTlRBSU5FUl9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgY29udGFpbmVyXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGNvbnRhaW5lciA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjb250YWluZXIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNDb250YWluZXIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGNvbnRhaW5lciA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY29udGFpbmVyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGdldENvbnRhaW5lcigpIHsKICAgICAgcmV0dXJuIGNvbnRhaW5lcl8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lci5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNvbnRhaW5lcl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBjb250YWluZXIgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lck9yQnVpbGRlciBnZXRDb250YWluZXJPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBjb250YWluZXJfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjb250YWluZXJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENISUxEX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBjaGlsZF87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBjaGlsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0NoaWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBjaGlsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY2hpbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgZ2V0Q2hpbGQoKSB7CiAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lci5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGNoaWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXJPckJ1aWxkZXIgZ2V0Q2hpbGRPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lci5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMQVpZX0NISUxEX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBsYXp5Q2hpbGRfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgbGF6eV9jaGlsZCA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxhenlDaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0xhenlDaGlsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgbGF6eV9jaGlsZCA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsYXp5Q2hpbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgZ2V0TGF6eUNoaWxkKCkgewogICAgICByZXR1cm4gbGF6eUNoaWxkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbGF6eUNoaWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGxhenlfY2hpbGQgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyT3JCdWlsZGVyIGdldExhenlDaGlsZE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGxhenlDaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lci5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGxhenlDaGlsZF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKGhhc0NvbnRhaW5lcigpKSB7CiAgICAgICAgaWYgKCFnZXRDb250YWluZXIoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChoYXNDaGlsZCgpKSB7CiAgICAgICAgaWYgKCFnZXRDaGlsZCgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGhhc0xhenlDaGlsZCgpKSB7CiAgICAgICAgaWYgKCFnZXRMYXp5Q2hpbGQoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRDb250YWluZXIoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyLCBnZXRDaGlsZCgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDMsIGdldExhenlDaGlsZCgpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGdldENvbnRhaW5lcigpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgZ2V0Q2hpbGQoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGdldExhenlDaGlsZCgpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIpIG9iajsKCiAgICAgIGlmIChoYXNDb250YWluZXIoKSAhPSBvdGhlci5oYXNDb250YWluZXIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQ29udGFpbmVyKCkpIHsKICAgICAgICBpZiAoIWdldENvbnRhaW5lcigpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Q29udGFpbmVyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0NoaWxkKCkgIT0gb3RoZXIuaGFzQ2hpbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQ2hpbGQoKSkgewogICAgICAgIGlmICghZ2V0Q2hpbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldENoaWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0xhenlDaGlsZCgpICE9IG90aGVyLmhhc0xhenlDaGlsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNMYXp5Q2hpbGQoKSkgewogICAgICAgIGlmICghZ2V0TGF6eUNoaWxkKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRMYXp5Q2hpbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNDb250YWluZXIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIENPTlRBSU5FUl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Q29udGFpbmVyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzQ2hpbGQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIENISUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRDaGlsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0xhenlDaGlsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTEFaWV9DSElMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TGF6eUNoaWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lci5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldENvbnRhaW5lckZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0Q2hpbGRGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldExhenlDaGlsZEZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgY29udGFpbmVyXyA9IG51bGw7CiAgICAgICAgaWYgKGNvbnRhaW5lckJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGNvbnRhaW5lckJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGNvbnRhaW5lckJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgY2hpbGRfID0gbnVsbDsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBsYXp5Q2hpbGRfID0gbnVsbDsKICAgICAgICBpZiAobGF6eUNoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbGF6eUNoaWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgbGF6eUNoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY29udGFpbmVyXyA9IGNvbnRhaW5lckJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGNvbnRhaW5lcl8KICAgICAgICAgICAgICA6IGNvbnRhaW5lckJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuY2hpbGRfID0gY2hpbGRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBjaGlsZF8KICAgICAgICAgICAgICA6IGNoaWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sYXp5Q2hpbGRfID0gbGF6eUNoaWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gbGF6eUNoaWxkXwogICAgICAgICAgICAgIDogbGF6eUNoaWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNDb250YWluZXIoKSkgewogICAgICAgICAgbWVyZ2VDb250YWluZXIob3RoZXIuZ2V0Q29udGFpbmVyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzQ2hpbGQoKSkgewogICAgICAgICAgbWVyZ2VDaGlsZChvdGhlci5nZXRDaGlsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0xhenlDaGlsZCgpKSB7CiAgICAgICAgICBtZXJnZUxhenlDaGlsZChvdGhlci5nZXRMYXp5Q2hpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoaGFzQ29udGFpbmVyKCkpIHsKICAgICAgICAgIGlmICghZ2V0Q29udGFpbmVyKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGhhc0NoaWxkKCkpIHsKICAgICAgICAgIGlmICghZ2V0Q2hpbGQoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoaGFzTGF6eUNoaWxkKCkpIHsKICAgICAgICAgIGlmICghZ2V0TGF6eUNoaWxkKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRDb250YWluZXJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0Q2hpbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0TGF6eUNoaWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBjb250YWluZXJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lci5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXJPckJ1aWxkZXI+IGNvbnRhaW5lckJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGNvbnRhaW5lciA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNvbnRhaW5lciBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNDb250YWluZXIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgY29udGFpbmVyID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvbnRhaW5lci4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgZ2V0Q29udGFpbmVyKCkgewogICAgICAgIGlmIChjb250YWluZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29udGFpbmVyXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLmdldERlZmF1bHRJbnN0YW5jZSgpIDogY29udGFpbmVyXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGNvbnRhaW5lckJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBjb250YWluZXIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENvbnRhaW5lcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgdmFsdWUpIHsKICAgICAgICBpZiAoY29udGFpbmVyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBjb250YWluZXJfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNvbnRhaW5lckJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBjb250YWluZXIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENvbnRhaW5lcigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lci5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChjb250YWluZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBjb250YWluZXJfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNvbnRhaW5lckJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBjb250YWluZXIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlQ29udGFpbmVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciB2YWx1ZSkgewogICAgICAgIGlmIChjb250YWluZXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgY29udGFpbmVyXyAhPSBudWxsICYmCiAgICAgICAgICAgIGNvbnRhaW5lcl8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldENvbnRhaW5lckJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY29udGFpbmVyXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjb250YWluZXJCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoY29udGFpbmVyXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBjb250YWluZXIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ29udGFpbmVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBjb250YWluZXJfID0gbnVsbDsKICAgICAgICBpZiAoY29udGFpbmVyQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgY29udGFpbmVyQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgY29udGFpbmVyQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGNvbnRhaW5lciA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lci5CdWlsZGVyIGdldENvbnRhaW5lckJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRDb250YWluZXJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldENvbnRhaW5lciBjb250YWluZXIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXJPckJ1aWxkZXIgZ2V0Q29udGFpbmVyT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChjb250YWluZXJCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY29udGFpbmVyQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gY29udGFpbmVyXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjb250YWluZXJfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGNvbnRhaW5lciA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0Q29udGFpbmVyT3JCdWlsZGVyPiAKICAgICAgICAgIGdldENvbnRhaW5lckZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoY29udGFpbmVyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgY29udGFpbmVyQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldENvbnRhaW5lci5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRDb250YWluZXJPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRDb250YWluZXIoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGNvbnRhaW5lcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29udGFpbmVyQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGNoaWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyT3JCdWlsZGVyPiBjaGlsZEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGNoaWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2hpbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzQ2hpbGQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgY2hpbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY2hpbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGdldENoaWxkKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lci5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGNoaWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGNoaWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDaGlsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgdmFsdWUpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGNoaWxkXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBjaGlsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Q2hpbGQoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBjaGlsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgY2hpbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlQ2hpbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHZhbHVlKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApICYmCiAgICAgICAgICAgIGNoaWxkXyAhPSBudWxsICYmCiAgICAgICAgICAgIGNoaWxkXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0Q2hpbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNoaWxkXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChjaGlsZF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgY2hpbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ2hpbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGNoaWxkXyA9IG51bGw7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBjaGlsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lci5CdWlsZGVyIGdldENoaWxkQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldENoaWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgY2hpbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXJPckJ1aWxkZXIgZ2V0Q2hpbGRPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNoaWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gY2hpbGRfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lci5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBjaGlsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyT3JCdWlsZGVyPiAKICAgICAgICAgIGdldENoaWxkRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lci5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXJPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRDaGlsZCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgY2hpbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNoaWxkQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGxhenlDaGlsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lck9yQnVpbGRlcj4gbGF6eUNoaWxkQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgbGF6eV9jaGlsZCA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbGF6eUNoaWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xhenlDaGlsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBsYXp5X2NoaWxkID0gMyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbGF6eUNoaWxkLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBnZXRMYXp5Q2hpbGQoKSB7CiAgICAgICAgaWYgKGxhenlDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBsYXp5Q2hpbGRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBsYXp5Q2hpbGRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbGF6eUNoaWxkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGxhenlfY2hpbGQgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TGF6eUNoaWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciB2YWx1ZSkgewogICAgICAgIGlmIChsYXp5Q2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGxhenlDaGlsZF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGF6eUNoaWxkQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGxhenlfY2hpbGQgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TGF6eUNoaWxkKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGxhenlDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGxhenlDaGlsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGF6eUNoaWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGxhenlfY2hpbGQgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VMYXp5Q2hpbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHZhbHVlKSB7CiAgICAgICAgaWYgKGxhenlDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSAmJgogICAgICAgICAgICBsYXp5Q2hpbGRfICE9IG51bGwgJiYKICAgICAgICAgICAgbGF6eUNoaWxkXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0TGF6eUNoaWxkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsYXp5Q2hpbGRfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGxhenlDaGlsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChsYXp5Q2hpbGRfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGxhenlfY2hpbGQgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMYXp5Q2hpbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGxhenlDaGlsZF8gPSBudWxsOwogICAgICAgIGlmIChsYXp5Q2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBsYXp5Q2hpbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBsYXp5Q2hpbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgbGF6eV9jaGlsZCA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLkJ1aWxkZXIgZ2V0TGF6eUNoaWxkQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldExhenlDaGlsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIGxhenlfY2hpbGQgPSAzIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lck9yQnVpbGRlciBnZXRMYXp5Q2hpbGRPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGxhenlDaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBsYXp5Q2hpbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBsYXp5Q2hpbGRfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lci5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGxhenlDaGlsZF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgbGF6eV9jaGlsZCA9IDMgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lci5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXJPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0TGF6eUNoaWxkRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChsYXp5Q2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBsYXp5Q2hpbGRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lck9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldExhenlDaGlsZCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgbGF6eUNoaWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBsYXp5Q2hpbGRCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXIgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxOZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE5lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIE5lc3RlZFRlc3RJbnRPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEludCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNBKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgaW50IGdldEEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGIgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICovCiAgICBpbnQgZ2V0QigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RJbnQgY2hpbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2hpbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0NoaWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50IGNoaWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQgZ2V0Q2hpbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RJbnQgY2hpbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnRPckJ1aWxkZXIgZ2V0Q2hpbGRPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEludH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZFRlc3RJbnQgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEludCkKICAgICAgTmVzdGVkVGVzdEludE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgTmVzdGVkVGVzdEludC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBOZXN0ZWRUZXN0SW50KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgTmVzdGVkVGVzdEludCgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBOZXN0ZWRUZXN0SW50KCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRUZXN0SW50X2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRUZXN0SW50X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBhXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0QSgpIHsKICAgICAgcmV0dXJuIGFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgaW50IGJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYiA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEIoKSB7CiAgICAgIHJldHVybiBiXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDSElMRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCBjaGlsZF87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50IGNoaWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNoaWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQ2hpbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RJbnQgY2hpbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNoaWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQgZ2V0Q2hpbGQoKSB7CiAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LmdldERlZmF1bHRJbnN0YW5jZSgpIDogY2hpbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEludCBjaGlsZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnRPckJ1aWxkZXIgZ2V0Q2hpbGRPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LmdldERlZmF1bHRJbnN0YW5jZSgpIDogY2hpbGRfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMigxLCBhXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyLCBnZXRDaGlsZCgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigzLCBiXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGaXhlZDMyU2l6ZSgxLCBhXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIsIGdldENoaWxkKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMywgYl8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50KSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCkgb2JqOwoKICAgICAgaWYgKGhhc0EoKSAhPSBvdGhlci5oYXNBKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgIGlmIChnZXRBKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0IoKSAhPSBvdGhlci5oYXNCKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0IoKSkgewogICAgICAgIGlmIChnZXRCKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0NoaWxkKCkgIT0gb3RoZXIuaGFzQ2hpbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQ2hpbGQoKSkgewogICAgICAgIGlmICghZ2V0Q2hpbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldENoaWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzQSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QSgpOwogICAgICB9CiAgICAgIGlmIChoYXNCKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0NoaWxkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDSElMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Q2hpbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RJbnR9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50KQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50T3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkVGVzdEludF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZFRlc3RJbnRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0Q2hpbGRGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGFfID0gMDsKICAgICAgICBiXyA9IDA7CiAgICAgICAgY2hpbGRfID0gbnVsbDsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRUZXN0SW50X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuYV8gPSBhXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5iXyA9IGJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNoaWxkXyA9IGNoaWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gY2hpbGRfCiAgICAgICAgICAgICAgOiBjaGlsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNBKCkpIHsKICAgICAgICAgIHNldEEob3RoZXIuZ2V0QSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0IoKSkgewogICAgICAgICAgc2V0QihvdGhlci5nZXRCKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzQ2hpbGQoKSkgewogICAgICAgICAgbWVyZ2VDaGlsZChvdGhlci5nZXRDaGlsZCgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMzogewogICAgICAgICAgICAgICAgYV8gPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0Q2hpbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgYl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBhXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEEoKSB7CiAgICAgICAgcmV0dXJuIGFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIGEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBhIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QShpbnQgdmFsdWUpIHsKCiAgICAgICAgYV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGFfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYiA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNCKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYiA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEIoKSB7CiAgICAgICAgcmV0dXJuIGJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEIoaW50IHZhbHVlKSB7CgogICAgICAgIGJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgYl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IGNoaWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50T3JCdWlsZGVyPiBjaGlsZEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RJbnQgY2hpbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50IGNoaWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNoaWxkLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IGdldENoaWxkKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LmdldERlZmF1bHRJbnN0YW5jZSgpIDogY2hpbGRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gY2hpbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEludCBjaGlsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Q2hpbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQgdmFsdWUpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGNoaWxkXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50IGNoaWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDaGlsZCgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgY2hpbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RJbnQgY2hpbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlQ2hpbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQgdmFsdWUpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkgJiYKICAgICAgICAgICAgY2hpbGRfICE9IG51bGwgJiYKICAgICAgICAgICAgY2hpbGRfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldENoaWxkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjaGlsZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoY2hpbGRfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RJbnQgY2hpbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ2hpbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGNoaWxkXyA9IG51bGw7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50IGNoaWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQuQnVpbGRlciBnZXRDaGlsZEJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRDaGlsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RJbnQgY2hpbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludE9yQnVpbGRlciBnZXRDaGlsZE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY2hpbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEludCBjaGlsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50T3JCdWlsZGVyPiAKICAgICAgICAgIGdldENoaWxkRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnRPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRDaGlsZCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgY2hpbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNoaWxkQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEludCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEludCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50KCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZFRlc3RJbnQ+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkVGVzdEludD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE5lc3RlZFRlc3RJbnQgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRUZXN0SW50PiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZFRlc3RJbnQ+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGkgPSAxNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0koKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGkuCiAgICAgKi8KICAgIGludCBnZXRJKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgcmVjdXJzaXZlID0gMTY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZWN1cnNpdmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1JlY3Vyc2l2ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgcmVjdXJzaXZlID0gMTY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVjdXJzaXZlLgogICAgICovCiAgICBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0IGdldFJlY3Vyc2l2ZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgcmVjdXJzaXZlID0gMTY7PC9jb2RlPgogICAgICovCiAgICBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0T3JCdWlsZGVyIGdldFJlY3Vyc2l2ZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHRlc3RfYWxpYXNpbmcgPSAxNyBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdGVzdEFsaWFzaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNUZXN0QWxpYXNpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHRlc3RfYWxpYXNpbmcgPSAxNyBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHRlc3RBbGlhc2luZy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRUZXN0QWxpYXNpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHRlc3RfYWxpYXNpbmcgPSAxNyBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciB0ZXN0QWxpYXNpbmcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFRlc3RBbGlhc2luZ0J5dGVzKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEpCiAgICAgIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSgpIHsKICAgICAgdGVzdEFsaWFzaW5nXyA9ICIiOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjFfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJX0ZJRUxEX05VTUJFUiA9IDE1OwogICAgcHJpdmF0ZSBpbnQgaV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzSSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJKCkgewogICAgICByZXR1cm4gaV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVDVVJTSVZFX0ZJRUxEX05VTUJFUiA9IDE2OwogICAgcHJpdmF0ZSBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0IHJlY3Vyc2l2ZV87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCByZWN1cnNpdmUgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlY3Vyc2l2ZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1JlY3Vyc2l2ZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgcmVjdXJzaXZlID0gMTY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVjdXJzaXZlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCBnZXRSZWN1cnNpdmUoKSB7CiAgICAgIHJldHVybiByZWN1cnNpdmVfID09IG51bGwgPyBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LmdldERlZmF1bHRJbnN0YW5jZSgpIDogcmVjdXJzaXZlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IHJlY3Vyc2l2ZSA9IDE2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXRPckJ1aWxkZXIgZ2V0UmVjdXJzaXZlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gcmVjdXJzaXZlXyA9PSBudWxsID8gcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHJlY3Vyc2l2ZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEVTVF9BTElBU0lOR19GSUVMRF9OVU1CRVIgPSAxNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHRlc3RBbGlhc2luZ18gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHRlc3RfYWxpYXNpbmcgPSAxNyBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdGVzdEFsaWFzaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzVGVzdEFsaWFzaW5nKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyB0ZXN0X2FsaWFzaW5nID0gMTcgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSB0ZXN0QWxpYXNpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFRlc3RBbGlhc2luZygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSB0ZXN0QWxpYXNpbmdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHRlc3RBbGlhc2luZ18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgdGVzdF9hbGlhc2luZyA9IDE3IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHRlc3RBbGlhc2luZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFRlc3RBbGlhc2luZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHRlc3RBbGlhc2luZ187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIHRlc3RBbGlhc2luZ18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoaGFzUmVjdXJzaXZlKCkpIHsKICAgICAgICBpZiAoIWdldFJlY3Vyc2l2ZSgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxNSwgaV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTYsIGdldFJlY3Vyc2l2ZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDE3LCB0ZXN0QWxpYXNpbmdfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxNSwgaV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxNiwgZ2V0UmVjdXJzaXZlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMTcsIHRlc3RBbGlhc2luZ18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSkgb2JqOwoKICAgICAgaWYgKGhhc0koKSAhPSBvdGhlci5oYXNJKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0koKSkgewogICAgICAgIGlmIChnZXRJKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0SSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1JlY3Vyc2l2ZSgpICE9IG90aGVyLmhhc1JlY3Vyc2l2ZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNSZWN1cnNpdmUoKSkgewogICAgICAgIGlmICghZ2V0UmVjdXJzaXZlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZWN1cnNpdmUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzVGVzdEFsaWFzaW5nKCkgIT0gb3RoZXIuaGFzVGVzdEFsaWFzaW5nKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1Rlc3RBbGlhc2luZygpKSB7CiAgICAgICAgaWYgKCFnZXRUZXN0QWxpYXNpbmcoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFRlc3RBbGlhc2luZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0koKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEkoKTsKICAgICAgfQogICAgICBpZiAoaGFzUmVjdXJzaXZlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRUNVUlNJVkVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlY3Vyc2l2ZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1Rlc3RBbGlhc2luZygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVEVTVF9BTElBU0lOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VGVzdEFsaWFzaW5nKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldFJlY3Vyc2l2ZUZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgaV8gPSAwOwogICAgICAgIHJlY3Vyc2l2ZV8gPSBudWxsOwogICAgICAgIGlmIChyZWN1cnNpdmVCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZWN1cnNpdmVCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICByZWN1cnNpdmVCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHRlc3RBbGlhc2luZ18gPSAiIjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjFfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuaV8gPSBpXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5yZWN1cnNpdmVfID0gcmVjdXJzaXZlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gcmVjdXJzaXZlXwogICAgICAgICAgICAgIDogcmVjdXJzaXZlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC50ZXN0QWxpYXNpbmdfID0gdGVzdEFsaWFzaW5nXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzSSgpKSB7CiAgICAgICAgICBzZXRJKG90aGVyLmdldEkoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNSZWN1cnNpdmUoKSkgewogICAgICAgICAgbWVyZ2VSZWN1cnNpdmUob3RoZXIuZ2V0UmVjdXJzaXZlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzVGVzdEFsaWFzaW5nKCkpIHsKICAgICAgICAgIHRlc3RBbGlhc2luZ18gPSBvdGhlci50ZXN0QWxpYXNpbmdfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoaGFzUmVjdXJzaXZlKCkpIHsKICAgICAgICAgIGlmICghZ2V0UmVjdXJzaXZlKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEyMDogewogICAgICAgICAgICAgICAgaV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjAKICAgICAgICAgICAgICBjYXNlIDEzMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0UmVjdXJzaXZlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzAKICAgICAgICAgICAgICBjYXNlIDEzODogewogICAgICAgICAgICAgICAgdGVzdEFsaWFzaW5nXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBpXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMTU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNJKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgaS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRJKCkgewogICAgICAgIHJldHVybiBpXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBpIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SShpbnQgdmFsdWUpIHsKCiAgICAgICAgaV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGkgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQgcmVjdXJzaXZlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCwgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5CdWlsZGVyLCBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0T3JCdWlsZGVyPiByZWN1cnNpdmVCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCByZWN1cnNpdmUgPSAxNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVjdXJzaXZlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1JlY3Vyc2l2ZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCByZWN1cnNpdmUgPSAxNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHJlY3Vyc2l2ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0IGdldFJlY3Vyc2l2ZSgpIHsKICAgICAgICBpZiAocmVjdXJzaXZlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlY3Vyc2l2ZV8gPT0gbnVsbCA/IHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZWN1cnNpdmVfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVjdXJzaXZlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IHJlY3Vyc2l2ZSA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlY3Vyc2l2ZShwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0IHZhbHVlKSB7CiAgICAgICAgaWYgKHJlY3Vyc2l2ZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgcmVjdXJzaXZlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZWN1cnNpdmVCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgcmVjdXJzaXZlID0gMTY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVjdXJzaXZlKAogICAgICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZWN1cnNpdmVCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZWN1cnNpdmVfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlY3Vyc2l2ZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCByZWN1cnNpdmUgPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVJlY3Vyc2l2ZShwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0IHZhbHVlKSB7CiAgICAgICAgaWYgKHJlY3Vyc2l2ZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSAmJgogICAgICAgICAgICByZWN1cnNpdmVfICE9IG51bGwgJiYKICAgICAgICAgICAgcmVjdXJzaXZlXyAhPSBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldFJlY3Vyc2l2ZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVjdXJzaXZlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZWN1cnNpdmVCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAocmVjdXJzaXZlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCByZWN1cnNpdmUgPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlY3Vyc2l2ZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgcmVjdXJzaXZlXyA9IG51bGw7CiAgICAgICAgaWYgKHJlY3Vyc2l2ZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJlY3Vyc2l2ZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHJlY3Vyc2l2ZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCByZWN1cnNpdmUgPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5CdWlsZGVyIGdldFJlY3Vyc2l2ZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRSZWN1cnNpdmVGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCByZWN1cnNpdmUgPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldE9yQnVpbGRlciBnZXRSZWN1cnNpdmVPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlY3Vyc2l2ZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZWN1cnNpdmVCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZWN1cnNpdmVfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZWN1cnNpdmVfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IHJlY3Vyc2l2ZSA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQsIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQuQnVpbGRlciwgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZWN1cnNpdmVGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlY3Vyc2l2ZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlY3Vyc2l2ZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCwgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldC5CdWlsZGVyLCBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0T3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0UmVjdXJzaXZlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZWN1cnNpdmVfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlY3Vyc2l2ZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgdGVzdEFsaWFzaW5nXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHRlc3RfYWxpYXNpbmcgPSAxNyBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB0ZXN0QWxpYXNpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzVGVzdEFsaWFzaW5nKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHRlc3RfYWxpYXNpbmcgPSAxNyBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgdGVzdEFsaWFzaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0VGVzdEFsaWFzaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gdGVzdEFsaWFzaW5nXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIHRlc3RBbGlhc2luZ18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHRlc3RfYWxpYXNpbmcgPSAxNyBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHRlc3RBbGlhc2luZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFRlc3RBbGlhc2luZ0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gdGVzdEFsaWFzaW5nXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgdGVzdEFsaWFzaW5nXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyB0ZXN0X2FsaWFzaW5nID0gMTcgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdGVzdEFsaWFzaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VGVzdEFsaWFzaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgdGVzdEFsaWFzaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHRlc3RfYWxpYXNpbmcgPSAxNyBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJUZXN0QWxpYXNpbmcoKSB7CiAgICAgICAgdGVzdEFsaWFzaW5nXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFRlc3RBbGlhc2luZygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHRlc3RfYWxpYXNpbmcgPSAxNyBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgdGVzdEFsaWFzaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VGVzdEFsaWFzaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHRlc3RBbGlhc2luZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjEgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjE+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX1NFVF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTU0NTAwODsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5UZXN0TWVzc2FnZVNldCwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xPiBtZXNzYWdlU2V0RXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMS5nZXREZWZhdWx0SW5zdGFuY2UoKSwKICAgICAgICAgIDAsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xLmNsYXNzLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMk9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyID0gMjU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyID0gMjU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyID0gMjU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0ci4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyQnl0ZXMoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMikKICAgICAgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yKCkgewogICAgICBzdHJfID0gIiI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUl9GSUVMRF9OVU1CRVIgPSAyNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cl8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0ciA9IDI1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIgPSAyNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyID0gMjU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0ci4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0ckJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIHN0cl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjUsIHN0cl8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDI1LCBzdHJfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIpIG9iajsKCiAgICAgIGlmIChoYXNTdHIoKSAhPSBvdGhlci5oYXNTdHIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzU3RyKCkpIHsKICAgICAgICBpZiAoIWdldFN0cigpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzU3RyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMi5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgc3RyXyA9ICIiOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHJfID0gc3RyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzU3RyKCkpIHsKICAgICAgICAgIHN0cl8gPSBvdGhlci5zdHJfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMjAyOiB7CiAgICAgICAgICAgICAgICBzdHJfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjAyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBzdHJfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyID0gMjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0ciBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyID0gMjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzdHIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgc3RyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyID0gMjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0U3RyQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0ciA9IDI1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzdHIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyID0gMjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cigpIHsKICAgICAgICBzdHJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0U3RyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyID0gMjU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBzdHIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMiBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjI+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1FU1NBR0VfU0VUX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAxNTQ3NzY5OwogICAgLyoqCiAgICAgKiA8Y29kZT5leHRlbmQgLnByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5Vbml0dGVzdE1zZXRXaXJlRm9ybWF0LlRlc3RNZXNzYWdlU2V0LAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjI+IG1lc3NhZ2VTZXRFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMCwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjIuY2xhc3MsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50IG1zZyA9IDM1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbXNnIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNNc2coKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RJbnQgbXNnID0gMzU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbXNnLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludCBnZXRNc2coKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RJbnQgbXNnID0gMzU7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludE9yQnVpbGRlciBnZXRNc2dPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHJlcXVpcmVkX2ludCA9IDM2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRJbnQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1JlcXVpcmVkSW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHJlcXVpcmVkX2ludCA9IDM2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkSW50LgogICAgICovCiAgICBpbnQgZ2V0UmVxdWlyZWRJbnQoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMykKICAgICAgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNU0dfRklFTERfTlVNQkVSID0gMzU7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IG1zZ187CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50IG1zZyA9IDM1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbXNnIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTXNnKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50IG1zZyA9IDM1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG1zZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IGdldE1zZygpIHsKICAgICAgcmV0dXJuIG1zZ18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LmdldERlZmF1bHRJbnN0YW5jZSgpIDogbXNnXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RJbnQgbXNnID0gMzU7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnRPckJ1aWxkZXIgZ2V0TXNnT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gbXNnXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtc2dfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUVVJUkVEX0lOVF9GSUVMRF9OVU1CRVIgPSAzNjsKICAgIHByaXZhdGUgaW50IHJlcXVpcmVkSW50XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHJlcXVpcmVkX2ludCA9IDM2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRJbnQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZEludCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiByZXF1aXJlZF9pbnQgPSAzNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEludC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXF1aXJlZEludCgpIHsKICAgICAgcmV0dXJuIHJlcXVpcmVkSW50XzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWhhc1JlcXVpcmVkSW50KCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMzUsIGdldE1zZygpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigzNiwgcmVxdWlyZWRJbnRfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDM1LCBnZXRNc2coKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgzNiwgcmVxdWlyZWRJbnRfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMpIG9iajsKCiAgICAgIGlmIChoYXNNc2coKSAhPSBvdGhlci5oYXNNc2coKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTXNnKCkpIHsKICAgICAgICBpZiAoIWdldE1zZygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TXNnKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1JlcXVpcmVkSW50KCkgIT0gb3RoZXIuaGFzUmVxdWlyZWRJbnQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUmVxdWlyZWRJbnQoKSkgewogICAgICAgIGlmIChnZXRSZXF1aXJlZEludCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldFJlcXVpcmVkSW50KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNNc2coKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1TR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TXNnKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWRJbnQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUVVJUkVEX0lOVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVxdWlyZWRJbnQoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uM30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldE1zZ0ZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgbXNnXyA9IG51bGw7CiAgICAgICAgaWYgKG1zZ0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1zZ0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG1zZ0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmVxdWlyZWRJbnRfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubXNnXyA9IG1zZ0J1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG1zZ18KICAgICAgICAgICAgICA6IG1zZ0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucmVxdWlyZWRJbnRfID0gcmVxdWlyZWRJbnRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNNc2coKSkgewogICAgICAgICAgbWVyZ2VNc2cob3RoZXIuZ2V0TXNnKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUmVxdWlyZWRJbnQoKSkgewogICAgICAgICAgc2V0UmVxdWlyZWRJbnQob3RoZXIuZ2V0UmVxdWlyZWRJbnQoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWhhc1JlcXVpcmVkSW50KCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDI4MjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0TXNnRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODIKICAgICAgICAgICAgICBjYXNlIDI4ODogewogICAgICAgICAgICAgICAgcmVxdWlyZWRJbnRfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjg4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQgbXNnXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50T3JCdWlsZGVyPiBtc2dCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50IG1zZyA9IDM1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtc2cgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTXNnKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RJbnQgbXNnID0gMzU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBtc2cuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQgZ2V0TXNnKCkgewogICAgICAgIGlmIChtc2dCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbXNnXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtc2dfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbXNnQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RJbnQgbXNnID0gMzU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TXNnKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IHZhbHVlKSB7CiAgICAgICAgaWYgKG1zZ0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgbXNnXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtc2dCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEludCBtc2cgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNc2coCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChtc2dCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBtc2dfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1zZ0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50IG1zZyA9IDM1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlTXNnKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50IHZhbHVlKSB7CiAgICAgICAgaWYgKG1zZ0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBtc2dfICE9IG51bGwgJiYKICAgICAgICAgICAgbXNnXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRNc2dCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1zZ18gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgbXNnQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG1zZ18gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEludCBtc2cgPSAzNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1zZygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgbXNnXyA9IG51bGw7CiAgICAgICAgaWYgKG1zZ0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1zZ0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG1zZ0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50IG1zZyA9IDM1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludC5CdWlsZGVyIGdldE1zZ0J1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRNc2dGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50IG1zZyA9IDM1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludE9yQnVpbGRlciBnZXRNc2dPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1zZ0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBtc2dCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtc2dfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LmdldERlZmF1bHRJbnN0YW5jZSgpIDogbXNnXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0SW50IG1zZyA9IDM1OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuTmVzdGVkVGVzdEludE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRNc2dGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1zZ0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1zZ0J1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0Lk5lc3RlZFRlc3RJbnQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50LkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5OZXN0ZWRUZXN0SW50T3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TXNnKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBtc2dfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1zZ0J1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGludCByZXF1aXJlZEludF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgcmVxdWlyZWRfaW50ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkSW50IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUmVxdWlyZWRJbnQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiByZXF1aXJlZF9pbnQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkSW50LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFJlcXVpcmVkSW50KCkgewogICAgICAgIHJldHVybiByZXF1aXJlZEludF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHJlcXVpcmVkX2ludCA9IDM2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXF1aXJlZEludCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcXVpcmVkSW50KGludCB2YWx1ZSkgewoKICAgICAgICByZXF1aXJlZEludF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHJlcXVpcmVkX2ludCA9IDM2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXF1aXJlZEludCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgcmVxdWlyZWRJbnRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZVNldEV4dGVuc2lvbjM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1FU1NBR0VfU0VUX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAxOTUyNzMxMjk7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXQgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlVuaXR0ZXN0TXNldFdpcmVGb3JtYXQuVGVzdE1lc3NhZ2VTZXQsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMz4gbWVzc2FnZVNldEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAwLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMy5jbGFzcywKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIH0KCiAgcHVibGljIGludGVyZmFjZSBSYXdNZXNzYWdlU2V0T3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlJhd01lc3NhZ2VTZXQpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBJdGVtID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtPiAKICAgICAgICBnZXRJdGVtTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBJdGVtID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIGdldEl0ZW0oaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgaW50IGdldEl0ZW1Db3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBJdGVtID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0SXRlbU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbU9yQnVpbGRlciBnZXRJdGVtT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogTWVzc2FnZVNldCB3aXJlIGZvcm1hdCBpcyBlcXVpdmFsZW50IHRvIHRoaXMuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5SYXdNZXNzYWdlU2V0fQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUmF3TWVzc2FnZVNldCBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5SYXdNZXNzYWdlU2V0KQogICAgICBSYXdNZXNzYWdlU2V0T3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBSYXdNZXNzYWdlU2V0Lm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFJhd01lc3NhZ2VTZXQoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBSYXdNZXNzYWdlU2V0KCkgewogICAgICBpdGVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBSYXdNZXNzYWdlU2V0KCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SYXdNZXNzYWdlU2V0X2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SYXdNZXNzYWdlU2V0X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0LkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgSXRlbU9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlJhd01lc3NhZ2VTZXQuSXRlbSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHR5cGVfaWQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB0eXBlSWQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNUeXBlSWQoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHR5cGVfaWQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgdHlwZUlkLgogICAgICAgKi8KICAgICAgaW50IGdldFR5cGVJZCgpOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIG1lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzTWVzc2FnZSgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlLgogICAgICAgKi8KICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE1lc3NhZ2UoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuUmF3TWVzc2FnZVNldC5JdGVtfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEl0ZW0gZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlJhd01lc3NhZ2VTZXQuSXRlbSkKICAgICAgICBJdGVtT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgSXRlbS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIEl0ZW0oY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBJdGVtKCkgewogICAgICAgIG1lc3NhZ2VfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IEl0ZW0oKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmF3TWVzc2FnZVNldF9JdGVtX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmF3TWVzc2FnZVNldF9JdGVtX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0uY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0uQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRZUEVfSURfRklFTERfTlVNQkVSID0gMjsKICAgICAgcHJpdmF0ZSBpbnQgdHlwZUlkXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiB0eXBlX2lkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdHlwZUlkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzVHlwZUlkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgdHlwZV9pZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB0eXBlSWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0VHlwZUlkKCkgewogICAgICAgIHJldHVybiB0eXBlSWRfOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDM7CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIG1lc3NhZ2VfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuIG1lc3NhZ2VfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBpZiAoIWhhc1R5cGVJZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWhhc01lc3NhZ2UoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIHR5cGVJZF8pOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDMsIG1lc3NhZ2VfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMiwgdHlwZUlkXyk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplKDMsIG1lc3NhZ2VfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtKSBvYmo7CgogICAgICAgIGlmIChoYXNUeXBlSWQoKSAhPSBvdGhlci5oYXNUeXBlSWQoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNUeXBlSWQoKSkgewogICAgICAgICAgaWYgKGdldFR5cGVJZCgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0VHlwZUlkKCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc01lc3NhZ2UoKSAhPSBvdGhlci5oYXNNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzTWVzc2FnZSgpKSB7CiAgICAgICAgICBpZiAoIWdldE1lc3NhZ2UoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaWYgKGhhc1R5cGVJZCgpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBUWVBFX0lEX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFR5cGVJZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzTWVzc2FnZSgpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0gcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlJhd01lc3NhZ2VTZXQuSXRlbX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuUmF3TWVzc2FnZVNldC5JdGVtKQogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbU9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Jhd01lc3NhZ2VTZXRfSXRlbV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SYXdNZXNzYWdlU2V0X0l0ZW1fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0uY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0uQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbS5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIHR5cGVJZF8gPSAwOwogICAgICAgICAgbWVzc2FnZV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmF3TWVzc2FnZVNldF9JdGVtX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIGJ1aWxkKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQudHlwZUlkXyA9IHR5cGVJZF87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5tZXNzYWdlXyA9IG1lc3NhZ2VfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0gb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5oYXNUeXBlSWQoKSkgewogICAgICAgICAgICBzZXRUeXBlSWQob3RoZXIuZ2V0VHlwZUlkKCkpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKG90aGVyLmhhc01lc3NhZ2UoKSkgewogICAgICAgICAgICBzZXRNZXNzYWdlKG90aGVyLmdldE1lc3NhZ2UoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgaWYgKCFoYXNUeXBlSWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIWhhc01lc3NhZ2UoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgICAgdHlwZUlkXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICAgIG1lc3NhZ2VfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IHR5cGVJZF8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHR5cGVfaWQgPSAyOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHR5cGVJZCBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1R5cGVJZCgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgdHlwZV9pZCA9IDI7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIHR5cGVJZC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRUeXBlSWQoKSB7CiAgICAgICAgICByZXR1cm4gdHlwZUlkXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgdHlwZV9pZCA9IDI7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdHlwZUlkIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VHlwZUlkKGludCB2YWx1ZSkgewoKICAgICAgICAgIHR5cGVJZF8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHR5cGVfaWQgPSAyOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJUeXBlSWQoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICB0eXBlSWRfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBtZXNzYWdlXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXF1aXJlZCBieXRlcyBtZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzTWVzc2FnZSgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2UuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0TWVzc2FnZSgpIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVxdWlyZWQgYnl0ZXMgbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbWVzc2FnZSB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgICAgbWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGJ5dGVzIG1lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNZXNzYWdlKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgbWVzc2FnZV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRNZXNzYWdlKCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlJhd01lc3NhZ2VTZXQuSXRlbSkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlJhd01lc3NhZ2VTZXQuSXRlbSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0gZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxJdGVtPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8SXRlbT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBJdGVtIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8SXRlbT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEl0ZW0+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElURU1fRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtPiBpdGVtXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0+IGdldEl0ZW1MaXN0KCkgewogICAgICByZXR1cm4gaXRlbV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEl0ZW0gPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0SXRlbU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiBpdGVtXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJdGVtQ291bnQoKSB7CiAgICAgIHJldHVybiBpdGVtXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEl0ZW0gPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIGdldEl0ZW0oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBpdGVtXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBJdGVtID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbU9yQnVpbGRlciBnZXRJdGVtT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gaXRlbV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdldEl0ZW1Db3VudCgpOyBpKyspIHsKICAgICAgICBpZiAoIWdldEl0ZW0oaSkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgaXRlbV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVHcm91cCgxLCBpdGVtXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGl0ZW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUdyb3VwU2l6ZSgxLCBpdGVtXy5nZXQoaSkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0KSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldCkgb2JqOwoKICAgICAgaWYgKCFnZXRJdGVtTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEl0ZW1MaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGdldEl0ZW1Db3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElURU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEl0ZW1MaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldCBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0IHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTWVzc2FnZVNldCB3aXJlIGZvcm1hdCBpcyBlcXVpdmFsZW50IHRvIHRoaXMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5SYXdNZXNzYWdlU2V0fQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuUmF3TWVzc2FnZVNldCkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Jhd01lc3NhZ2VTZXRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SYXdNZXNzYWdlU2V0X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0LmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoaXRlbUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGl0ZW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpdGVtXyA9IG51bGw7CiAgICAgICAgICBpdGVtQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Jhd01lc3NhZ2VTZXRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0IGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0IHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0IHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldCh0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldCByZXN1bHQpIHsKICAgICAgICBpZiAoaXRlbUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICBpdGVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGl0ZW1fKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0Lml0ZW1fID0gaXRlbV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5pdGVtXyA9IGl0ZW1CdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldCkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChpdGVtQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5pdGVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKGl0ZW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGl0ZW1fID0gb3RoZXIuaXRlbV87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZUl0ZW1Jc011dGFibGUoKTsKICAgICAgICAgICAgICBpdGVtXy5hZGRBbGwob3RoZXIuaXRlbV8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLml0ZW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAoaXRlbUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGl0ZW1CdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgaXRlbUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICBpdGVtXyA9IG90aGVyLml0ZW1fOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgICAgICBpdGVtQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgZ2V0SXRlbUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBpdGVtQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIuaXRlbV8pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdldEl0ZW1Db3VudCgpOyBpKyspIHsKICAgICAgICAgIGlmICghZ2V0SXRlbShpKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTE6IHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0gbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZEdyb3VwKDEsCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0uUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAoaXRlbUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlSXRlbUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBpdGVtXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBpdGVtQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMQogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0+IGl0ZW1fID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVJdGVtSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIGl0ZW1fID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbT4oaXRlbV8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtT3JCdWlsZGVyPiBpdGVtQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtPiBnZXRJdGVtTGlzdCgpIHsKICAgICAgICBpZiAoaXRlbUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChpdGVtXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBpdGVtQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEl0ZW0gPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEl0ZW1Db3VudCgpIHsKICAgICAgICBpZiAoaXRlbUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBpdGVtXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBpdGVtQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEl0ZW0gPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSBnZXRJdGVtKGludCBpbmRleCkgewogICAgICAgIGlmIChpdGVtQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGl0ZW1fLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBpdGVtQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBJdGVtID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SXRlbSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSB2YWx1ZSkgewogICAgICAgIGlmIChpdGVtQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVJdGVtSXNNdXRhYmxlKCk7CiAgICAgICAgICBpdGVtXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpdGVtQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEl0ZW0oCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0uQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoaXRlbUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUl0ZW1Jc011dGFibGUoKTsKICAgICAgICAgIGl0ZW1fLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGl0ZW1CdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBJdGVtID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkSXRlbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtIHZhbHVlKSB7CiAgICAgICAgaWYgKGl0ZW1CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZUl0ZW1Jc011dGFibGUoKTsKICAgICAgICAgIGl0ZW1fLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaXRlbUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEl0ZW0oCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0gdmFsdWUpIHsKICAgICAgICBpZiAoaXRlbUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlSXRlbUlzTXV0YWJsZSgpOwogICAgICAgICAgaXRlbV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaXRlbUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEl0ZW0gPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRJdGVtKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChpdGVtQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlSXRlbUlzTXV0YWJsZSgpOwogICAgICAgICAgaXRlbV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpdGVtQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBJdGVtID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkSXRlbSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChpdGVtQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlSXRlbUlzTXV0YWJsZSgpOwogICAgICAgICAgaXRlbV8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaXRlbUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEl0ZW0gPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxJdGVtKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtPiB2YWx1ZXMpIHsKICAgICAgICBpZiAoaXRlbUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZUl0ZW1Jc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIGl0ZW1fKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpdGVtQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEl0ZW0gPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckl0ZW0oKSB7CiAgICAgICAgaWYgKGl0ZW1CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpdGVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpdGVtQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEl0ZW0gPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVJdGVtKGludCBpbmRleCkgewogICAgICAgIGlmIChpdGVtQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlSXRlbUlzTXV0YWJsZSgpOwogICAgICAgICAgaXRlbV8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpdGVtQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEl0ZW0gPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbS5CdWlsZGVyIGdldEl0ZW1CdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldEl0ZW1GaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgSXRlbSA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtT3JCdWlsZGVyIGdldEl0ZW1PckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICBpZiAoaXRlbUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBpdGVtXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBpdGVtQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBJdGVtID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRJdGVtT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAoaXRlbUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBpdGVtQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGl0ZW1fKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEl0ZW0gPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbS5CdWlsZGVyIGFkZEl0ZW1CdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRJdGVtRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEl0ZW0gPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbS5CdWlsZGVyIGFkZEl0ZW1CdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldEl0ZW1GaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEl0ZW0gPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRJdGVtQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldEl0ZW1GaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE1zZXQuUmF3TWVzc2FnZVNldC5JdGVtT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEl0ZW1GaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGl0ZW1CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpdGVtQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0sIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0Lkl0ZW0uQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQuSXRlbU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGl0ZW1fLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGl0ZW1fID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGl0ZW1CdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5SYXdNZXNzYWdlU2V0KQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5SYXdNZXNzYWdlU2V0KQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0TXNldC5SYXdNZXNzYWdlU2V0IGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmF3TWVzc2FnZVNldD4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxSYXdNZXNzYWdlU2V0PigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgUmF3TWVzc2FnZVNldCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJhd01lc3NhZ2VTZXQ+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmF3TWVzc2FnZVNldD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RNc2V0LlJhd01lc3NhZ2VTZXQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRDb250YWluZXJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRDb250YWluZXJfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZFRlc3RNZXNzYWdlU2V0Q29udGFpbmVyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRUZXN0SW50X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZFRlc3RJbnRfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjFfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjJfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uM19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Jhd01lc3NhZ2VTZXRfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmF3TWVzc2FnZVNldF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmF3TWVzc2FnZVNldF9JdGVtX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Jhd01lc3NhZ2VTZXRfSXRlbV9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuI2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9tc2V0LnByb3RvXDAyMlwwMjFwIiArCiAgICAgICJyb3RvYnVmX3VuaXR0ZXN0XDAzMi9nb29nbGUvcHJvdG9idWYvdW5pdHRlIiArCiAgICAgICJzdF9tc2V0X3dpcmVfZm9ybWF0LnByb3RvXCJaXG5cMDI3VGVzdE1lc3NhZ2UiICsKICAgICAgIlNldENvbnRhaW5lclwwMjI/XG5cMDEzbWVzc2FnZV9zZXRcMDMwXDAwMSBcMDAxKFwwMTMyKi5wcm90IiArCiAgICAgICJvMl93aXJlZm9ybWF0X3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2V0XCJcMzUxXDAwMSIgKwogICAgICAiXG5cMDM1TmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXJcMDIyPVxuXHRjb250YSIgKwogICAgICAiaW5lclwwMzBcMDAxIFwwMDEoXDAxMzIqLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYSIgKwogICAgICAiZ2VTZXRDb250YWluZXJcMDIyP1xuXDAwNWNoaWxkXDAzMFwwMDIgXDAwMShcMDEzMjAucHJvdG9idWYiICsKICAgICAgIl91bml0dGVzdC5OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lclwwMjIiICsKICAgICAgIkhcblxubGF6eV9jaGlsZFwwMzBcMDAzIFwwMDEoXDAxMzIwLnByb3RvYnVmX3VuaXR0ZXN0LiIgKwogICAgICAiTmVzdGVkVGVzdE1lc3NhZ2VTZXRDb250YWluZXJCXDAwMihcMDAxXCJWXG5cck5lcyIgKwogICAgICAidGVkVGVzdEludFwwMjJcdFxuXDAwMWFcMDMwXDAwMSBcMDAxKFwwMDdcMDIyXHRcblwwMDFiXDAzMFwwMDMgXDAwMShcMDA1XDAyMi9cblwwMDVjaGlsIiArCiAgICAgICJkXDAzMFwwMDIgXDAwMShcMDEzMiAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEluIiArCiAgICAgICJ0XCJcMzcxXDAwMVxuXDAzMFRlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMVwwMjJcdFxuXDAwMWlcMDMwXDAxNyBcMDAxKCIgKwogICAgICAiXDAwNVwwMjI9XG5cdHJlY3Vyc2l2ZVwwMzBcMDIwIFwwMDEoXDAxMzIqLnByb3RvMl93aXJlZm9ybWF0IiArCiAgICAgICJfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRcMDIyXDAzMVxuXHJ0ZXN0X2FsaWFzaW4iICsKICAgICAgImdcMDMwXDAyMSBcMDAxKFx0QlwwMDJcMDEwXDAwMjJ4XG5cMDI1bWVzc2FnZV9zZXRfZXh0ZW5zaW9uXDAyMioucCIgKwogICAgICAicm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnZVNldCIgKwogICAgICAiXDAzMFwyNjBcMjQ2XiBcMDAxKFwwMTMyKy5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZSIgKwogICAgICAiU2V0RXh0ZW5zaW9uMVwiXDI0MVwwMDFcblwwMzBUZXN0TWVzc2FnZVNldEV4dGVuc2lvIiArCiAgICAgICJuMlwwMjJcMDEzXG5cMDAzc3RyXDAzMFwwMzEgXDAwMShcdDJ4XG5cMDI1bWVzc2FnZV9zZXRfZXh0ZW5zaW9uIiArCiAgICAgICJcMDIyKi5wcm90bzJfd2lyZWZvcm1hdF91bml0dGVzdC5UZXN0TWVzc2FnIiArCiAgICAgICJlU2V0XDAzMFwzNzFcMjczXiBcMDAxKFwwMTMyKy5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzIiArCiAgICAgICJzYWdlU2V0RXh0ZW5zaW9uMlwiXDMzMlwwMDFcblwwMzBUZXN0TWVzc2FnZVNldEV4dGUiICsKICAgICAgIm5zaW9uM1wwMjItXG5cMDAzbXNnXDAzMCMgXDAwMShcMDEzMiAucHJvdG9idWZfdW5pdHRlc3QuIiArCiAgICAgICJOZXN0ZWRUZXN0SW50XDAyMlwwMjRcblwwMTRyZXF1aXJlZF9pbnRcMDMwJCBcMDAyKFwwMDUyeVxuXDAyNW0iICsKICAgICAgImVzc2FnZV9zZXRfZXh0ZW5zaW9uXDAyMioucHJvdG8yX3dpcmVmb3JtYXQiICsKICAgICAgIl91bml0dGVzdC5UZXN0TWVzc2FnZVNldFwwMzBcMjUxXDMwM1wyMTZdIFwwMDEoXDAxMzIrLnByb3QiICsKICAgICAgIm9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zXCJuIiArCiAgICAgICJcblxyUmF3TWVzc2FnZVNldFwwMjIzXG5cMDA0aXRlbVwwMzBcMDAxIFwwMDMoXG4yJS5wcm90b2J1ZiIgKwogICAgICAiX3VuaXR0ZXN0LlJhd01lc3NhZ2VTZXQuSXRlbVwwMzIoXG5cMDA0SXRlbVwwMjJcMDE3XG5cMDA3IiArCiAgICAgICJ0eXBlX2lkXDAzMFwwMDIgXDAwMihcMDA1XDAyMlwwMTdcblwwMDdtZXNzYWdlXDAzMFwwMDMgXDAwMihcMDE0QlwwMDVIXDAwMVwzNzBcMDAxXDAwMSIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5nZXREZXNjcmlwdG9yKCksCiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRDb250YWluZXJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRDb250YWluZXJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRDb250YWluZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk1lc3NhZ2VTZXQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRUZXN0TWVzc2FnZVNldENvbnRhaW5lcl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQ29udGFpbmVyIiwgIkNoaWxkIiwgIkxhenlDaGlsZCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZFRlc3RJbnRfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkVGVzdEludF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRUZXN0SW50X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJBIiwgIkIiLCAiQ2hpbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjFfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24xX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSSIsICJSZWN1cnNpdmUiLCAiVGVzdEFsaWFzaW5nIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24yX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uMl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlN0ciIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2V0RXh0ZW5zaW9uM19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNldEV4dGVuc2lvbjNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTZXRFeHRlbnNpb24zX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJNc2ciLCAiUmVxdWlyZWRJbnQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SYXdNZXNzYWdlU2V0X2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Jhd01lc3NhZ2VTZXRfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmF3TWVzc2FnZVNldF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSXRlbSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Jhd01lc3NhZ2VTZXRfSXRlbV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Jhd01lc3NhZ2VTZXRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SYXdNZXNzYWdlU2V0X0l0ZW1fZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmF3TWVzc2FnZVNldF9JdGVtX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJUeXBlSWQiLCAiTWVzc2FnZSIsIH0pOwogICAgcHJvdG8yX3dpcmVmb3JtYXRfdW5pdHRlc3QuVW5pdHRlc3RNc2V0V2lyZUZvcm1hdC5nZXREZXNjcmlwdG9yKCk7CiAgfQoKICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQob3V0ZXJfY2xhc3Nfc2NvcGUpCn0KUEsDBAoAAAAAAAAAIQCK/8oD/RUBAP0VAQAqAAAAcHJvdG9idWZfdW5pdHRlc3QvVW5pdHRlc3RPcHRpbWl6ZUZvci5qYXZhLy8gR2VuZXJhdGVkIGJ5IHRoZSBwcm90b2NvbCBidWZmZXIgY29tcGlsZXIuICBETyBOT1QgRURJVCEKLy8gc291cmNlOiBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfb3B0aW1pemVfZm9yLnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdDsKCnB1YmxpYyBmaW5hbCBjbGFzcyBVbml0dGVzdE9wdGltaXplRm9yIHsKICBwcml2YXRlIFVuaXR0ZXN0T3B0aW1pemVGb3IoKSB7fQogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZS50ZXN0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLnRlc3RFeHRlbnNpb24yKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgcHVibGljIGludGVyZmFjZSBUZXN0T3B0aW1pemVkRm9yU2l6ZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxUZXN0T3B0aW1pemVkRm9yU2l6ZT4gewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNJKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGkgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGkuCiAgICAgKi8KICAgIGludCBnZXRJKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbXNnID0gMTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtc2cgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc01zZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbXNnID0gMTk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbXNnLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIGdldE1zZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbXNnID0gMTk7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldE1zZ09yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgaW50ZWdlcl9maWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbnRlZ2VyRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ludGVnZXJGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBpbnRlZ2VyX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbnRlZ2VyRmllbGQuCiAgICAgKi8KICAgIGludCBnZXRJbnRlZ2VyRmllbGQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBzdHJpbmdfZmllbGQgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyaW5nRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cmluZ0ZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBzdHJpbmdfZmllbGQgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ0ZpZWxkLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ0ZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBzdHJpbmdfZmllbGQgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHJpbmdGaWVsZC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyaW5nRmllbGRCeXRlcygpOwoKICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUuRm9vQ2FzZSBnZXRGb29DYXNlKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE9wdGltaXplZEZvclNpemUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgICBUZXN0T3B0aW1pemVkRm9yU2l6ZT4gaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplKQogICAgICBUZXN0T3B0aW1pemVkRm9yU2l6ZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE9wdGltaXplZEZvclNpemUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdE9wdGltaXplZEZvclNpemUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSwgPz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE9wdGltaXplZEZvclNpemUoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdE9wdGltaXplZEZvclNpemUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T3B0aW1pemVkRm9yU2l6ZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPcHRpbWl6ZWRGb3JTaXplX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHJpdmF0ZSBpbnQgZm9vQ2FzZV8gPSAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgZm9vXzsKICAgIHB1YmxpYyBlbnVtIEZvb0Nhc2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkludGVybmFsT25lT2ZFbnVtIHsKICAgICAgSU5URUdFUl9GSUVMRCgyKSwKICAgICAgU1RSSU5HX0ZJRUxEKDMpLAogICAgICBGT09fTk9UX1NFVCgwKTsKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CiAgICAgIHByaXZhdGUgRm9vQ2FzZShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtYmVyIG9mIHRoZSBlbnVtIHRvIGxvb2sgZm9yLgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtYmVyLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIEZvb0Nhc2UgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBGb29DYXNlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDI6IHJldHVybiBJTlRFR0VSX0ZJRUxEOwogICAgICAgICAgY2FzZSAzOiByZXR1cm4gU1RSSU5HX0ZJRUxEOwogICAgICAgICAgY2FzZSAwOiByZXR1cm4gRk9PX05PVF9TRVQ7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIEZvb0Nhc2UKICAgIGdldEZvb0Nhc2UoKSB7CiAgICAgIHJldHVybiBGb29DYXNlLmZvck51bWJlcigKICAgICAgICAgIGZvb0Nhc2VfKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBpXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGkgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0koKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJKCkgewogICAgICByZXR1cm4gaV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTVNHX0ZJRUxEX05VTUJFUiA9IDE5OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIG1zZ187CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBtc2cgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1zZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc01zZygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbXNnID0gMTk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbXNnLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRNc2coKSB7CiAgICAgIHJldHVybiBtc2dfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbXNnXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG1zZyA9IDE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0TXNnT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gbXNnXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1zZ187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5URUdFUl9GSUVMRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBpbnRlZ2VyX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludGVnZXJGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ludGVnZXJGaWVsZCgpIHsKICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDI7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGludGVnZXJfZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGludGVnZXJGaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRJbnRlZ2VyRmllbGQoKSB7CiAgICAgIGlmIChmb29DYXNlXyA9PSAyKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgZm9vXzsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJTkdfRklFTERfRklFTERfTlVNQkVSID0gMzsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIHN0cmluZ19maWVsZCA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cmluZ0ZpZWxkKCkgewogICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gMzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIHN0cmluZ19maWVsZCA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyaW5nRmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ0ZpZWxkKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAoZm9vQ2FzZV8gPT0gMykgewogICAgICAgIHJlZiA9IGZvb187CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpICYmIChmb29DYXNlXyA9PSAzKSkgewogICAgICAgICAgZm9vXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBzdHJpbmdfZmllbGQgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHJpbmdGaWVsZC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cmluZ0ZpZWxkQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgcmVmID0gZm9vXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMykgewogICAgICAgICAgZm9vXyA9IGI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUsIEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9wdGltaXplZEZvclNpemVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9wdGltaXplZEZvclNpemVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0TXNnRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpXyA9IDA7CiAgICAgICAgbXNnXyA9IG51bGw7CiAgICAgICAgaWYgKG1zZ0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1zZ0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG1zZ0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZm9vQ2FzZV8gPSAwOwogICAgICAgIGZvb18gPSBudWxsOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T3B0aW1pemVkRm9yU2l6ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBidWlsZFBhcnRpYWxPbmVvZnMocmVzdWx0KTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5pXyA9IGlfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1zZ18gPSBtc2dCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBtc2dfCiAgICAgICAgICAgICAgOiBtc2dCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsT25lb2ZzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgcmVzdWx0KSB7CiAgICAgICAgcmVzdWx0LmZvb0Nhc2VfID0gZm9vQ2FzZV87CiAgICAgICAgcmVzdWx0LmZvb18gPSB0aGlzLmZvb187CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUsIFR5cGU+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLCBUPiBleHRlbnNpb24pIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgICAgfQogICAgICBwcml2YXRlIGludCBmb29DYXNlXyA9IDA7CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBmb29fOwogICAgICBwdWJsaWMgRm9vQ2FzZQogICAgICAgICAgZ2V0Rm9vQ2FzZSgpIHsKICAgICAgICByZXR1cm4gRm9vQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICAgIGZvb0Nhc2VfKTsKICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb28oKSB7CiAgICAgICAgZm9vQ2FzZV8gPSAwOwogICAgICAgIGZvb18gPSBudWxsOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgaV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNJKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBpLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEkoKSB7CiAgICAgICAgcmV0dXJuIGlfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgaSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEkoaW50IHZhbHVlKSB7CgogICAgICAgIGlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgaV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgbXNnXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiBtc2dCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBtc2cgPSAxOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbXNnIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc01zZygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBtc2cgPSAxOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG1zZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIGdldE1zZygpIHsKICAgICAgICBpZiAobXNnQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG1zZ18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtc2dfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbXNnQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG1zZyA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE1zZyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG1zZ0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgbXNnXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtc2dCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbXNnID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TXNnKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChtc2dCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBtc2dfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1zZ0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBtc2cgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU1zZyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG1zZ0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSAmJgogICAgICAgICAgICBtc2dfICE9IG51bGwgJiYKICAgICAgICAgICAgbXNnXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE1zZ0J1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbXNnXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtc2dCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAobXNnXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBtc2cgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1zZygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgbXNnXyA9IG51bGw7CiAgICAgICAgaWYgKG1zZ0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1zZ0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG1zZ0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBtc2cgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGdldE1zZ0J1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRNc2dGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBtc2cgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRNc2dPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1zZ0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBtc2dCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtc2dfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtc2dfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG1zZyA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRNc2dGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1zZ0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1zZ0J1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TXNnKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBtc2dfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1zZ0J1aWxkZXJfOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgaW50ZWdlcl9maWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGludGVnZXJGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbnRlZ2VyRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGludGVnZXJfZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgaW50ZWdlckZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRJbnRlZ2VyRmllbGQoKSB7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIGZvb187CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBpbnRlZ2VyX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgaW50ZWdlckZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SW50ZWdlckZpZWxkKGludCB2YWx1ZSkgewoKICAgICAgICBmb29DYXNlXyA9IDI7CiAgICAgICAgZm9vXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBpbnRlZ2VyX2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW50ZWdlckZpZWxkKCkgewogICAgICAgIGlmIChmb29DYXNlXyA9PSAyKSB7CiAgICAgICAgICBmb29DYXNlXyA9IDA7CiAgICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBzdHJpbmdfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cmluZ0ZpZWxkKCkgewogICAgICAgIHJldHVybiBmb29DYXNlXyA9PSAzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgc3RyaW5nX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ0ZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHJpbmdGaWVsZCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgICByZWYgPSBmb29fOwogICAgICAgIH0KICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgICAgZm9vXyA9IHM7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBzdHJpbmdfZmllbGQgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cmluZ0ZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHJpbmdGaWVsZEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDMpIHsKICAgICAgICAgIHJlZiA9IGZvb187CiAgICAgICAgfQogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMykgewogICAgICAgICAgICBmb29fID0gYjsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIHN0cmluZ19maWVsZCA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cmluZ0ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyaW5nRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBmb29DYXNlXyA9IDM7CiAgICAgICAgZm9vXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgc3RyaW5nX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyaW5nRmllbGQoKSB7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDMpIHsKICAgICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgc3RyaW5nX2ZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cmluZ0ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyaW5nRmllbGRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZm9vQ2FzZV8gPSAzOwogICAgICAgIGZvb18gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGltaXplZEZvclNpemUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0T3B0aW1pemVkRm9yU2l6ZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0T3B0aW1pemVkRm9yU2l6ZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RPcHRpbWl6ZWRGb3JTaXplIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE9wdGltaXplZEZvclNpemU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE9wdGltaXplZEZvclNpemU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEVTVF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTIzNDsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW1pemVkRm9yU2l6ZSwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gdGVzdEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGltaXplZEZvclNpemUuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAwLAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgICBudWxsKTsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRFU1RfRVhURU5TSU9OMl9GSUVMRF9OVU1CRVIgPSAxMjM1OwogICAgLyoqCiAgICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGb3JTaXplIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZT4gdGVzdEV4dGVuc2lvbjIgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpbWl6ZWRGb3JTaXplLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZS5jbGFzcywKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHggPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgeCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzWCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiB4ID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSB4LgogICAgICovCiAgICBpbnQgZ2V0WCgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplKQogICAgICBUZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBYX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCB4XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIHggPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgeCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1goKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgeCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgeC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRYKCkgewogICAgICByZXR1cm4geF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICB4XyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnhfID0geF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgeF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgeCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNYKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgeCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB4LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFgoKSB7CiAgICAgICAgcmV0dXJuIHhfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiB4ID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgeCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFgoaW50IHZhbHVlKSB7CgogICAgICAgIHhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiB4ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyWCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgeF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemUpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSBvID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG8gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc08oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgbyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgby4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIGdldE8oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgbyA9IDE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemVPckJ1aWxkZXIgZ2V0T09yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplKQogICAgICBUZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSBvXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgbyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSBvID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIGdldE8oKSB7CiAgICAgIHJldHVybiBvXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIG8gPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZU9yQnVpbGRlciBnZXRPT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemUgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemUgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemUgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemUpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRPRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvXyA9IG51bGw7CiAgICAgICAgaWYgKG9CdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemUodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9fID0gb0J1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9fCiAgICAgICAgICAgICAgOiBvQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSBvXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplT3JCdWlsZGVyPiBvQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSBvID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgbyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSBnZXRPKCkgewogICAgICAgIGlmIChvQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9fID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9CdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSBvID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSB2YWx1ZSkgewogICAgICAgIGlmIChvQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgbyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TygKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIG8gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlTyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgdmFsdWUpIHsKICAgICAgICBpZiAob0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBvXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9fICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9fICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUgbyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvXyA9IG51bGw7CiAgICAgICAgaWYgKG9CdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIG8gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUuQnVpbGRlciBnZXRPQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9GaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplIG8gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemVPckJ1aWxkZXIgZ2V0T09yQnVpbGRlcigpIHsKICAgICAgICBpZiAob0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb18gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb187CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSBvID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdE9wdGltaXplRm9yLlRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemVPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9CdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE8oKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9fID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9CdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0T3B0aW1pemVGb3IuVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RPcHRpbWl6ZUZvci5UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPcHRpbWl6ZWRGb3JTaXplX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPcHRpbWl6ZWRGb3JTaXplX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemVfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZV9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuK2dvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9vcHRpbWl6ZV9mb3IuIiArCiAgICAgICJwcm90b1wwMjJcMDIxcHJvdG9idWZfdW5pdHRlc3RcMDMyXDAzNmdvb2dsZS9wcm90b2J1IiArCiAgICAgICJmL3VuaXR0ZXN0LnByb3RvXCJcMzEyXDAwMlxuXDAyNFRlc3RPcHRpbWl6ZWRGb3JTaXoiICsKICAgICAgImVcMDIyXHRcblwwMDFpXDAzMFwwMDEgXDAwMShcMDA1XDAyMi5cblwwMDNtc2dcMDMwXDAyMyBcMDAxKFwwMTMyIS5wcm90b2J1Zl91bmkiICsKICAgICAgInR0ZXN0LkZvcmVpZ25NZXNzYWdlXDAyMlwwMjdcblxyaW50ZWdlcl9maWVsZFwwMzBcMDAyICIgKwogICAgICAiXDAwMShcMDA1SFwwMDBcMDIyXDAyNlxuXDAxNHN0cmluZ19maWVsZFwwMzBcMDAzIFwwMDEoXHRIXDAwMCpcdFwwMTBcMzUwXDAwN1wwMjBcMjAwXDIwMFwyMDBcMjAwXDAwMiIgKwogICAgICAiMkBcblwwMTZ0ZXN0X2V4dGVuc2lvblwwMjJcJy5wcm90b2J1Zl91bml0dGVzdC5UIiArCiAgICAgICJlc3RPcHRpbWl6ZWRGb3JTaXplXDAzMFwzMjJcdCBcMDAxKFwwMDUyclxuXDAxN3Rlc3RfZXh0ZW4iICsKICAgICAgInNpb24yXDAyMlwnLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPcHRpbWl6ZWRGIiArCiAgICAgICJvclNpemVcMDMwXDMyM1x0IFwwMDEoXDAxMzIvLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZSIgKwogICAgICAicXVpcmVkT3B0aW1pemVkRm9yU2l6ZUJcMDA1XG5cMDAzZm9vXCIpXG5cMDM0VGVzdFJlcSIgKwogICAgICAidWlyZWRPcHRpbWl6ZWRGb3JTaXplXDAyMlx0XG5cMDAxeFwwMzBcMDAxIFwwMDIoXDAwNVwiWlxuXDAzNFRlc3QiICsKICAgICAgIk9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZVwwMjI6XG5cMDAxb1wwMzBcMDAxIFwwMDEoXDAxMzIvLnByIiArCiAgICAgICJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yIiArCiAgICAgICJTaXplQlwwMDJIXDAwMiIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5nZXREZXNjcmlwdG9yKCksCiAgICAgICAgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9wdGltaXplZEZvclNpemVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9wdGltaXplZEZvclNpemVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9wdGltaXplZEZvclNpemVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkkiLCAiTXNnIiwgIkludGVnZXJGaWVsZCIsICJTdHJpbmdGaWVsZCIsICJGb28iLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRPcHRpbWl6ZWRGb3JTaXplX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkT3B0aW1pemVkRm9yU2l6ZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiWCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPcHRpb25hbE9wdGltaXplZEZvclNpemVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9wdGlvbmFsT3B0aW1pemVkRm9yU2l6ZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPIiwgfSk7CiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmdldERlc2NyaXB0b3IoKTsKICB9CgogIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChvdXRlcl9jbGFzc19zY29wZSkKfQpQSwMECgAAAAAAAAAhAPE0A9/OhWgAzoVoACQAAABwcm90b2J1Zl91bml0dGVzdC9Vbml0dGVzdFByb3RvLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bwoKLy8gUHJvdG9idWYgSmF2YSBWZXJzaW9uOiAzLjI1LjQtZGV2CnBhY2thZ2UgcHJvdG9idWZfdW5pdHRlc3Q7CgpwdWJsaWMgZmluYWwgY2xhc3MgVW5pdHRlc3RQcm90byB7CiAgcHJpdmF0ZSBVbml0dGVzdFByb3RvKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxJbnQzMkV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbEludDY0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsVWludDMyRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsVWludDY0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsU2ludDMyRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsU2ludDY0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsRml4ZWQzMkV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbEZpeGVkNjRFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxTZml4ZWQzMkV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbFNmaXhlZDY0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsRmxvYXRFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxEb3VibGVFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxCb29sRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsU3RyaW5nRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsQnl0ZXNFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxHcm91cEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbE5lc3RlZE1lc3NhZ2VFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxGb3JlaWduTWVzc2FnZUV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbEltcG9ydE1lc3NhZ2VFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxOZXN0ZWRFbnVtRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsRm9yZWlnbkVudW1FeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxJbXBvcnRFbnVtRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsU3RyaW5nUGllY2VFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub3B0aW9uYWxDb3JkRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5vcHRpb25hbExhenlNZXNzYWdlRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkSW50MzJFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWRJbnQ2NEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZFVpbnQzMkV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZFNpbnQzMkV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZFNpbnQ2NEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZEZpeGVkMzJFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWRGaXhlZDY0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkU2ZpeGVkMzJFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWRTZml4ZWQ2NEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZEZsb2F0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkRG91YmxlRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkQm9vbEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZFN0cmluZ0V4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZEJ5dGVzRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkR3JvdXBFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucmVwZWF0ZWRJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkTmVzdGVkRW51bUV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZEZvcmVpZ25FbnVtRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkSW1wb3J0RW51bUV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZFN0cmluZ1BpZWNlRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnJlcGVhdGVkQ29yZEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5yZXBlYXRlZExhenlNZXNzYWdlRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHRJbnQzMkV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0SW50NjRFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZGVmYXVsdFVpbnQzMkV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0VWludDY0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHRTaW50MzJFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZGVmYXVsdFNpbnQ2NEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0Rml4ZWQzMkV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0Rml4ZWQ2NEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0U2ZpeGVkMzJFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZGVmYXVsdFNmaXhlZDY0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHRGbG9hdEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0RG91YmxlRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHRCb29sRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHRTdHJpbmdFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZGVmYXVsdEJ5dGVzRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHROZXN0ZWRFbnVtRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmRlZmF1bHRGb3JlaWduRW51bUV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0SW1wb3J0RW51bUV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5kZWZhdWx0U3RyaW5nUGllY2VFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZGVmYXVsdENvcmRFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub25lb2ZVaW50MzJFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ub25lb2ZOZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9uZW9mU3RyaW5nRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLm9uZW9mQnl0ZXNFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ubXlFeHRlbnNpb25TdHJpbmcpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ubXlFeHRlbnNpb25JbnQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucGFja2VkSW50MzJFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucGFja2VkSW50NjRFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucGFja2VkVWludDMyRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnBhY2tlZFVpbnQ2NEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5wYWNrZWRTaW50MzJFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucGFja2VkU2ludDY0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnBhY2tlZEZpeGVkMzJFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucGFja2VkRml4ZWQ2NEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5wYWNrZWRTZml4ZWQzMkV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5wYWNrZWRTZml4ZWQ2NEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5wYWNrZWRGbG9hdEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5wYWNrZWREb3VibGVFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8ucGFja2VkQm9vbEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5wYWNrZWRFbnVtRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnVucGFja2VkSW50MzJFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8udW5wYWNrZWRJbnQ2NEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by51bnBhY2tlZFVpbnQzMkV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by51bnBhY2tlZFVpbnQ2NEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by51bnBhY2tlZFNpbnQzMkV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by51bnBhY2tlZFNpbnQ2NEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by51bnBhY2tlZEZpeGVkMzJFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8udW5wYWNrZWRGaXhlZDY0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnVucGFja2VkU2ZpeGVkMzJFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8udW5wYWNrZWRTZml4ZWQ2NEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by51bnBhY2tlZEZsb2F0RXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnVucGFja2VkRG91YmxlRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnVucGFja2VkQm9vbEV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by51bnBhY2tlZEVudW1FeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8udGVzdEFsbFR5cGVzKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLnRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZUV4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbm5lcik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zLmMpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucy5kKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24udGVzdCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLm5lc3RlZFN0cmluZ0V4dGVuc2lvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLm9wdGlvbmFsR3JvdXBFeHRlbnNpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbi5vcHRpb25hbEZvcmVpZ25FbnVtRXh0ZW5zaW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5zaW5nbGUpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLm11bHRpKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxLnRlc3RFeHRPcmRlcmluZ3MxKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLnRlc3RFeHRPcmRlcmluZ3MyKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzLnRlc3RFeHRPcmRlcmluZ3MzKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2Uub3B0aW9uYWxFeHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5yZXBlYXRlZEV4dCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUuYmFyT25lKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZS5iYXJUd28pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplLmJhclRocmVlKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZS5iYXJGb3VyKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZS5iYXJGaXZlKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5vcHRpb25hbEFyYml0cmFyeUV4dCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIucmVwZWF0ZWRBcmJpdHJhcnlFeHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLnBhY2tlZEFyYml0cmFyeUV4dCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIub3B0aW9uYWxCb29sRXh0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3Rlci5yZXBlYXRlZEJvb2xFeHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyLnBhY2tlZEJvb2xFeHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3Rlci5vcHRpb25hbEludDMyRXh0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXIucmVwZWF0ZWRJbnQzMkV4dCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyLnBhY2tlZEludDMyRXh0KTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXIub3B0aW9uYWxJbnQ2NEV4dCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyLnJlcGVhdGVkSW50NjRFeHQpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3Rlci5wYWNrZWRJbnQ2NEV4dCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3Rlci5vcHRpb25hbFN0cmluZ0V4dCk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3Rlci5yZXBlYXRlZFN0cmluZ0V4dCk7CiAgfQoKICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5IHJlZ2lzdHJ5KSB7CiAgICByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlKSByZWdpc3RyeSk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtfQogICAqLwogIHB1YmxpYyBlbnVtIEZvcmVpZ25FbnVtCiAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgIC8qKgogICAgICogPGNvZGU+Rk9SRUlHTl9GT08gPSA0OzwvY29kZT4KICAgICAqLwogICAgRk9SRUlHTl9GT08oNCksCiAgICAvKioKICAgICAqIDxjb2RlPkZPUkVJR05fQkFSID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEZPUkVJR05fQkFSKDUpLAogICAgLyoqCiAgICAgKiA8Y29kZT5GT1JFSUdOX0JBWiA9IDY7PC9jb2RlPgogICAgICovCiAgICBGT1JFSUdOX0JBWig2KSwKICAgIC8qKgogICAgICogPHByZT4KICAgICAqICgxICZsdDsmbHQ7IDMyKSB0byBnZW5lcmF0ZSBhIDY0YiBiaXRtYXNrIHdvdWxkIGJlIGluY29ycmVjdC4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPkZPUkVJR05fQkFYID0gMzI7PC9jb2RlPgogICAgICovCiAgICBGT1JFSUdOX0JBWCgzMiksCiAgICA7CgogICAgLyoqCiAgICAgKiA8Y29kZT5GT1JFSUdOX0ZPTyA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT1JFSUdOX0ZPT19WQUxVRSA9IDQ7CiAgICAvKioKICAgICAqIDxjb2RlPkZPUkVJR05fQkFSID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPUkVJR05fQkFSX1ZBTFVFID0gNTsKICAgIC8qKgogICAgICogPGNvZGU+Rk9SRUlHTl9CQVogPSA2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9SRUlHTl9CQVpfVkFMVUUgPSA2OwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogKDEgJmx0OyZsdDsgMzIpIHRvIGdlbmVyYXRlIGEgNjRiIGJpdG1hc2sgd291bGQgYmUgaW5jb3JyZWN0LgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+Rk9SRUlHTl9CQVggPSAzMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPUkVJR05fQkFYX1ZBTFVFID0gMzI7CgoKICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICByZXR1cm4gdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBzdGF0aWMgRm9yZWlnbkVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBGb3JlaWduRW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICBjYXNlIDQ6IHJldHVybiBGT1JFSUdOX0ZPTzsKICAgICAgICBjYXNlIDU6IHJldHVybiBGT1JFSUdOX0JBUjsKICAgICAgICBjYXNlIDY6IHJldHVybiBGT1JFSUdOX0JBWjsKICAgICAgICBjYXNlIDMyOiByZXR1cm4gRk9SRUlHTl9CQVg7CiAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8Rm9yZWlnbkVudW0+CiAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgIEZvcmVpZ25FbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPEZvcmVpZ25FbnVtPigpIHsKICAgICAgICAgICAgcHVibGljIEZvcmVpZ25FbnVtIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gRm9yZWlnbkVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgIH0KICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEZvcmVpZ25FbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgcHVibGljIHN0YXRpYyBGb3JlaWduRW51bSB2YWx1ZU9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICB9CiAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICBwcml2YXRlIEZvcmVpZ25FbnVtKGludCB2YWx1ZSkgewogICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0pCiAgfQoKICAvKioKICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVzZXJ2ZWRFbnVtRmllbGRzfQogICAqLwogIHB1YmxpYyBlbnVtIFRlc3RSZXNlcnZlZEVudW1GaWVsZHMKICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgLyoqCiAgICAgKiA8Y29kZT5VTktOT1dOID0gMDs8L2NvZGU+CiAgICAgKi8KICAgIFVOS05PV04oMCksCiAgICA7CgogICAgLyoqCiAgICAgKiA8Y29kZT5VTktOT1dOID0gMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOS05PV05fVkFMVUUgPSAwOwoKCiAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgcmV0dXJuIHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgc3RhdGljIFRlc3RSZXNlcnZlZEVudW1GaWVsZHMgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUZXN0UmVzZXJ2ZWRFbnVtRmllbGRzIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgIGNhc2UgMDogcmV0dXJuIFVOS05PV047CiAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8VGVzdFJlc2VydmVkRW51bUZpZWxkcz4KICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgVGVzdFJlc2VydmVkRW51bUZpZWxkcz4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxUZXN0UmVzZXJ2ZWRFbnVtRmllbGRzPigpIHsKICAgICAgICAgICAgcHVibGljIFRlc3RSZXNlcnZlZEVudW1GaWVsZHMgZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgIHJldHVybiBUZXN0UmVzZXJ2ZWRFbnVtRmllbGRzLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwoKICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICB9CiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgxKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUZXN0UmVzZXJ2ZWRFbnVtRmllbGRzW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgcHVibGljIHN0YXRpYyBUZXN0UmVzZXJ2ZWRFbnVtRmllbGRzIHZhbHVlT2YoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgIH0KICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgfQoKICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgIHByaXZhdGUgVGVzdFJlc2VydmVkRW51bUZpZWxkcyhpbnQgdmFsdWUpIHsKICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXNlcnZlZEVudW1GaWVsZHMpCiAgfQoKICAvKioKICAgKiA8cHJlPgogICAqIFRlc3QgYW4gZW51bSB0aGF0IGhhcyBtdWx0aXBsZSB2YWx1ZXMgd2l0aCB0aGUgc2FtZSBudW1iZXIuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RW51bVdpdGhEdXBWYWx1ZX0KICAgKi8KICBwdWJsaWMgZW51bSBUZXN0RW51bVdpdGhEdXBWYWx1ZQogICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAvKioKICAgICAqIDxjb2RlPkZPTzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgRk9PMSgxKSwKICAgIC8qKgogICAgICogPGNvZGU+QkFSMSA9IDI7PC9jb2RlPgogICAgICovCiAgICBCQVIxKDIpLAogICAgLyoqCiAgICAgKiA8Y29kZT5CQVogPSAzOzwvY29kZT4KICAgICAqLwogICAgQkFaKDMpLAogICAgOwoKICAgIC8qKgogICAgICogPGNvZGU+Rk9PMiA9IDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFRlc3RFbnVtV2l0aER1cFZhbHVlIEZPTzIgPSBGT08xOwogICAgLyoqCiAgICAgKiA8Y29kZT5CQVIyID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgVGVzdEVudW1XaXRoRHVwVmFsdWUgQkFSMiA9IEJBUjE7CiAgICAvKioKICAgICAqIDxjb2RlPkZPTzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PMV9WQUxVRSA9IDE7CiAgICAvKioKICAgICAqIDxjb2RlPkJBUjEgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSMV9WQUxVRSA9IDI7CiAgICAvKioKICAgICAqIDxjb2RlPkJBWiA9IDM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVpfVkFMVUUgPSAzOwogICAgLyoqCiAgICAgKiA8Y29kZT5GT08yID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPTzJfVkFMVUUgPSAxOwogICAgLyoqCiAgICAgKiA8Y29kZT5CQVIyID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUjJfVkFMVUUgPSAyOwoKCiAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgcmV0dXJuIHZhbHVlOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgc3RhdGljIFRlc3RFbnVtV2l0aER1cFZhbHVlIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVGVzdEVudW1XaXRoRHVwVmFsdWUgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgY2FzZSAxOiByZXR1cm4gRk9PMTsKICAgICAgICBjYXNlIDI6IHJldHVybiBCQVIxOwogICAgICAgIGNhc2UgMzogcmV0dXJuIEJBWjsKICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxUZXN0RW51bVdpdGhEdXBWYWx1ZT4KICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgVGVzdEVudW1XaXRoRHVwVmFsdWU+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8VGVzdEVudW1XaXRoRHVwVmFsdWU+KCkgewogICAgICAgICAgICBwdWJsaWMgVGVzdEVudW1XaXRoRHVwVmFsdWUgZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgIHJldHVybiBUZXN0RW51bVdpdGhEdXBWYWx1ZS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKCiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgfQogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMik7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgVGVzdEVudW1XaXRoRHVwVmFsdWVbXSBWQUxVRVMgPSBnZXRTdGF0aWNWYWx1ZXNBcnJheSgpOwogICAgcHJpdmF0ZSBzdGF0aWMgVGVzdEVudW1XaXRoRHVwVmFsdWVbXSBnZXRTdGF0aWNWYWx1ZXNBcnJheSgpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0RW51bVdpdGhEdXBWYWx1ZVtdIHsKICAgICAgRk9PMSwgQkFSMSwgQkFaLCBGT08yLCBCQVIyLCAKICAgICAgfTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgVGVzdEVudW1XaXRoRHVwVmFsdWUgdmFsdWVPZigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgfQogICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgcHJpdmF0ZSBUZXN0RW51bVdpdGhEdXBWYWx1ZShpbnQgdmFsdWUpIHsKICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbnVtV2l0aER1cFZhbHVlKQogIH0KCiAgLyoqCiAgICogPHByZT4KICAgKiBUZXN0IGFuIGVudW0gd2l0aCBsYXJnZSwgdW5vcmRlcmVkIHZhbHVlcy4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTcGFyc2VFbnVtfQogICAqLwogIHB1YmxpYyBlbnVtIFRlc3RTcGFyc2VFbnVtCiAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgIC8qKgogICAgICogPGNvZGU+U1BBUlNFX0EgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBTUEFSU0VfQSgxMjMpLAogICAgLyoqCiAgICAgKiA8Y29kZT5TUEFSU0VfQiA9IDYyMzc0OzwvY29kZT4KICAgICAqLwogICAgU1BBUlNFX0IoNjIzNzQpLAogICAgLyoqCiAgICAgKiA8Y29kZT5TUEFSU0VfQyA9IDEyNTg5MjM0OzwvY29kZT4KICAgICAqLwogICAgU1BBUlNFX0MoMTI1ODkyMzQpLAogICAgLyoqCiAgICAgKiA8Y29kZT5TUEFSU0VfRCA9IC0xNTs8L2NvZGU+CiAgICAgKi8KICAgIFNQQVJTRV9EKC0xNSksCiAgICAvKioKICAgICAqIDxjb2RlPlNQQVJTRV9FID0gLTUzNDUyOzwvY29kZT4KICAgICAqLwogICAgU1BBUlNFX0UoLTUzNDUyKSwKICAgIC8qKgogICAgICogPGNvZGU+U1BBUlNFX0YgPSAwOzwvY29kZT4KICAgICAqLwogICAgU1BBUlNFX0YoMCksCiAgICAvKioKICAgICAqIDxjb2RlPlNQQVJTRV9HID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIFNQQVJTRV9HKDIpLAogICAgOwoKICAgIC8qKgogICAgICogPGNvZGU+U1BBUlNFX0EgPSAxMjM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTUEFSU0VfQV9WQUxVRSA9IDEyMzsKICAgIC8qKgogICAgICogPGNvZGU+U1BBUlNFX0IgPSA2MjM3NDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNQQVJTRV9CX1ZBTFVFID0gNjIzNzQ7CiAgICAvKioKICAgICAqIDxjb2RlPlNQQVJTRV9DID0gMTI1ODkyMzQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTUEFSU0VfQ19WQUxVRSA9IDEyNTg5MjM0OwogICAgLyoqCiAgICAgKiA8Y29kZT5TUEFSU0VfRCA9IC0xNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNQQVJTRV9EX1ZBTFVFID0gLTE1OwogICAgLyoqCiAgICAgKiA8Y29kZT5TUEFSU0VfRSA9IC01MzQ1Mjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNQQVJTRV9FX1ZBTFVFID0gLTUzNDUyOwogICAgLyoqCiAgICAgKiA8Y29kZT5TUEFSU0VfRiA9IDA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTUEFSU0VfRl9WQUxVRSA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPlNQQVJTRV9HID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNQQVJTRV9HX1ZBTFVFID0gMjsKCgogICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIHN0YXRpYyBUZXN0U3BhcnNlRW51bSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIFRlc3RTcGFyc2VFbnVtIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgIGNhc2UgMTIzOiByZXR1cm4gU1BBUlNFX0E7CiAgICAgICAgY2FzZSA2MjM3NDogcmV0dXJuIFNQQVJTRV9COwogICAgICAgIGNhc2UgMTI1ODkyMzQ6IHJldHVybiBTUEFSU0VfQzsKICAgICAgICBjYXNlIC0xNTogcmV0dXJuIFNQQVJTRV9EOwogICAgICAgIGNhc2UgLTUzNDUyOiByZXR1cm4gU1BBUlNFX0U7CiAgICAgICAgY2FzZSAwOiByZXR1cm4gU1BBUlNFX0Y7CiAgICAgICAgY2FzZSAyOiByZXR1cm4gU1BBUlNFX0c7CiAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8VGVzdFNwYXJzZUVudW0+CiAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgIFRlc3RTcGFyc2VFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFRlc3RTcGFyc2VFbnVtPigpIHsKICAgICAgICAgICAgcHVibGljIFRlc3RTcGFyc2VFbnVtIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gVGVzdFNwYXJzZUVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgIH0KICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDMpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFRlc3RTcGFyc2VFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgcHVibGljIHN0YXRpYyBUZXN0U3BhcnNlRW51bSB2YWx1ZU9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICB9CiAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICBwcml2YXRlIFRlc3RTcGFyc2VFbnVtKGludCB2YWx1ZSkgewogICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFNwYXJzZUVudW0pCiAgfQoKICAvKioKICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5WZXJ5TGFyZ2VFbnVtfQogICAqLwogIHB1YmxpYyBlbnVtIFZlcnlMYXJnZUVudW0KICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMX0RFRkFVTFQgPSAwOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF9ERUZBVUxUKDApLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzEgPSAxOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF8xKDEpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzIgPSAyOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF8yKDIpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzMgPSAzOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF8zKDMpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzQgPSA0OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF80KDQpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzUgPSA1OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF81KDUpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF82KDYpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzcgPSA3OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF83KDcpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzggPSA4OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF84KDgpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF85KDkpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzEwID0gMTA7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzEwKDEwKSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8xMSA9IDExOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF8xMSgxMSksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfMTIoMTIpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzEzID0gMTM7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzEzKDEzKSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8xNCA9IDE0OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF8xNCgxNCksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfMTUoMTUpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzE2ID0gMTY7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzE2KDE2KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8xNyA9IDE3OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF8xNygxNyksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMTggPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfMTgoMTgpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzE5ID0gMTk7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzE5KDE5KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8yMCA9IDIwOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF8yMCgyMCksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMjEgPSAyMTs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfMjEoMjEpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzIyID0gMjI7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzIyKDIyKSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8yMyA9IDIzOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF8yMygyMyksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfMjQoMjQpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzI1ID0gMjU7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzI1KDI1KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8yNiA9IDI2OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF8yNigyNiksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfMjcoMjcpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzI4ID0gMjg7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzI4KDI4KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8yOSA9IDI5OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF8yOSgyOSksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMzAgPSAzMDs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfMzAoMzApLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzMxID0gMzE7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzMxKDMxKSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8zMiA9IDMyOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF8zMigzMiksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMzMgPSAzMzs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfMzMoMzMpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzM0ID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzM0KDM0KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8zNSA9IDM1OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF8zNSgzNSksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfMzYoMzYpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzM3ID0gMzc7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzM3KDM3KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8zOCA9IDM4OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF8zOCgzOCksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfMzkoMzkpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzQwID0gNDA7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzQwKDQwKSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF80MSA9IDQxOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF80MSg0MSksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfNDIoNDIpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzQzID0gNDM7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzQzKDQzKSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF80NCA9IDQ0OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF80NCg0NCksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNDUgPSA0NTs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfNDUoNDUpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzQ2ID0gNDY7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzQ2KDQ2KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF80NyA9IDQ3OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF80Nyg0NyksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNDggPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfNDgoNDgpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzQ5ID0gNDk7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzQ5KDQ5KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF81MCA9IDUwOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF81MCg1MCksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfNTEoNTEpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzUyID0gNTI7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzUyKDUyKSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF81MyA9IDUzOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF81Myg1MyksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNTQgPSA1NDs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfNTQoNTQpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzU1ID0gNTU7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzU1KDU1KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF81NiA9IDU2OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF81Nig1NiksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfNTcoNTcpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzU4ID0gNTg7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzU4KDU4KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF81OSA9IDU5OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF81OSg1OSksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNjAgPSA2MDs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfNjAoNjApLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzYxID0gNjE7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzYxKDYxKSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF82MiA9IDYyOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF82Mig2MiksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfNjMoNjMpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzY0ID0gNjQ7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzY0KDY0KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF82NSA9IDY1OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF82NSg2NSksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfNjYoNjYpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzY3ID0gNjc7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzY3KDY3KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF82OCA9IDY4OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF82OCg2OCksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfNjkoNjkpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzcwID0gNzA7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzcwKDcwKSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF83MSA9IDcxOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF83MSg3MSksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfNzIoNzIpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzczID0gNzM7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzczKDczKSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF83NCA9IDc0OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF83NCg3NCksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNzUgPSA3NTs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfNzUoNzUpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzc2ID0gNzY7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzc2KDc2KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF83NyA9IDc3OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF83Nyg3NyksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNzggPSA3ODs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfNzgoNzgpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzc5ID0gNzk7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzc5KDc5KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF84MCA9IDgwOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF84MCg4MCksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfODEoODEpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzgyID0gODI7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzgyKDgyKSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF84MyA9IDgzOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF84Myg4MyksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfODQoODQpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzg1ID0gODU7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzg1KDg1KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF84NiA9IDg2OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF84Nig4NiksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfODcoODcpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzg4ID0gODg7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzg4KDg4KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF84OSA9IDg5OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF84OSg4OSksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfOTAoOTApLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzkxID0gOTE7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzkxKDkxKSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF85MiA9IDkyOzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF85Mig5MiksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfOTMoOTMpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzk0ID0gOTQ7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzk0KDk0KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF85NSA9IDk1OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF85NSg5NSksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfOTYoOTYpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzk3ID0gOTc7PC9jb2RlPgogICAgICovCiAgICBFTlVNX0xBQkVMXzk3KDk3KSwKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF85OCA9IDk4OzwvY29kZT4KICAgICAqLwogICAgRU5VTV9MQUJFTF85OCg5OCksCiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfOTkgPSA5OTs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfOTkoOTkpLAogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzEwMCA9IDEwMDs8L2NvZGU+CiAgICAgKi8KICAgIEVOVU1fTEFCRUxfMTAwKDEwMCksCiAgICA7CgogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMX0RFRkFVTFQgPSAwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF9ERUZBVUxUX1ZBTFVFID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8xID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfMV9WQUxVRSA9IDE7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMiA9IDI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzJfVkFMVUUgPSAyOwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzMgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF8zX1ZBTFVFID0gMzsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF80ID0gNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNF9WQUxVRSA9IDQ7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNSA9IDU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzVfVkFMVUUgPSA1OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzYgPSA2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF82X1ZBTFVFID0gNjsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF83ID0gNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfN19WQUxVRSA9IDc7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfOCA9IDg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzhfVkFMVUUgPSA4OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzkgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF85X1ZBTFVFID0gOTsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8xMCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF8xMF9WQUxVRSA9IDEwOwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzExID0gMTE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzExX1ZBTFVFID0gMTE7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMTIgPSAxMjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfMTJfVkFMVUUgPSAxMjsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8xMyA9IDEzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF8xM19WQUxVRSA9IDEzOwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzE0ID0gMTQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzE0X1ZBTFVFID0gMTQ7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMTUgPSAxNTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfMTVfVkFMVUUgPSAxNTsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8xNiA9IDE2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF8xNl9WQUxVRSA9IDE2OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzE3ID0gMTc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzE3X1ZBTFVFID0gMTc7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMTggPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfMThfVkFMVUUgPSAxODsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8xOSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF8xOV9WQUxVRSA9IDE5OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzIwID0gMjA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzIwX1ZBTFVFID0gMjA7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMjEgPSAyMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfMjFfVkFMVUUgPSAyMTsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8yMiA9IDIyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF8yMl9WQUxVRSA9IDIyOwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzIzID0gMjM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzIzX1ZBTFVFID0gMjM7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMjQgPSAyNDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfMjRfVkFMVUUgPSAyNDsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8yNSA9IDI1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF8yNV9WQUxVRSA9IDI1OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzI2ID0gMjY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzI2X1ZBTFVFID0gMjY7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMjcgPSAyNzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfMjdfVkFMVUUgPSAyNzsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8yOCA9IDI4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF8yOF9WQUxVRSA9IDI4OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzI5ID0gMjk7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzI5X1ZBTFVFID0gMjk7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMzAgPSAzMDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfMzBfVkFMVUUgPSAzMDsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8zMSA9IDMxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF8zMV9WQUxVRSA9IDMxOwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzMyID0gMzI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzMyX1ZBTFVFID0gMzI7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMzMgPSAzMzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfMzNfVkFMVUUgPSAzMzsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8zNCA9IDM0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF8zNF9WQUxVRSA9IDM0OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzM1ID0gMzU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzM1X1ZBTFVFID0gMzU7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMzYgPSAzNjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfMzZfVkFMVUUgPSAzNjsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8zNyA9IDM3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF8zN19WQUxVRSA9IDM3OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzM4ID0gMzg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzM4X1ZBTFVFID0gMzg7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfMzkgPSAzOTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfMzlfVkFMVUUgPSAzOTsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF80MCA9IDQwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF80MF9WQUxVRSA9IDQwOwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzQxID0gNDE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzQxX1ZBTFVFID0gNDE7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNDIgPSA0Mjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNDJfVkFMVUUgPSA0MjsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF80MyA9IDQzOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF80M19WQUxVRSA9IDQzOwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzQ0ID0gNDQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzQ0X1ZBTFVFID0gNDQ7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNDUgPSA0NTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNDVfVkFMVUUgPSA0NTsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF80NiA9IDQ2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF80Nl9WQUxVRSA9IDQ2OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzQ3ID0gNDc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzQ3X1ZBTFVFID0gNDc7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNDggPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNDhfVkFMVUUgPSA0ODsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF80OSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF80OV9WQUxVRSA9IDQ5OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzUwID0gNTA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzUwX1ZBTFVFID0gNTA7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNTEgPSA1MTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNTFfVkFMVUUgPSA1MTsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF81MiA9IDUyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF81Ml9WQUxVRSA9IDUyOwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzUzID0gNTM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzUzX1ZBTFVFID0gNTM7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNTQgPSA1NDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNTRfVkFMVUUgPSA1NDsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF81NSA9IDU1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF81NV9WQUxVRSA9IDU1OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzU2ID0gNTY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzU2X1ZBTFVFID0gNTY7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNTcgPSA1Nzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNTdfVkFMVUUgPSA1NzsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF81OCA9IDU4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF81OF9WQUxVRSA9IDU4OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzU5ID0gNTk7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzU5X1ZBTFVFID0gNTk7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNjAgPSA2MDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNjBfVkFMVUUgPSA2MDsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF82MSA9IDYxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF82MV9WQUxVRSA9IDYxOwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzYyID0gNjI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzYyX1ZBTFVFID0gNjI7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNjNfVkFMVUUgPSA2MzsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF82NCA9IDY0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF82NF9WQUxVRSA9IDY0OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzY1ID0gNjU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzY1X1ZBTFVFID0gNjU7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNjYgPSA2Njs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNjZfVkFMVUUgPSA2NjsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF82NyA9IDY3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF82N19WQUxVRSA9IDY3OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzY4ID0gNjg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzY4X1ZBTFVFID0gNjg7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNjkgPSA2OTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNjlfVkFMVUUgPSA2OTsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF83MCA9IDcwOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF83MF9WQUxVRSA9IDcwOwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzcxID0gNzE7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzcxX1ZBTFVFID0gNzE7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNzIgPSA3Mjs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNzJfVkFMVUUgPSA3MjsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF83MyA9IDczOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF83M19WQUxVRSA9IDczOwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzc0ID0gNzQ7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzc0X1ZBTFVFID0gNzQ7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNzUgPSA3NTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNzVfVkFMVUUgPSA3NTsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF83NiA9IDc2OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF83Nl9WQUxVRSA9IDc2OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzc3ID0gNzc7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzc3X1ZBTFVFID0gNzc7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfNzggPSA3ODs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfNzhfVkFMVUUgPSA3ODsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF83OSA9IDc5OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF83OV9WQUxVRSA9IDc5OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzgwID0gODA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzgwX1ZBTFVFID0gODA7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfODEgPSA4MTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfODFfVkFMVUUgPSA4MTsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF84MiA9IDgyOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF84Ml9WQUxVRSA9IDgyOwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzgzID0gODM7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzgzX1ZBTFVFID0gODM7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfODQgPSA4NDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfODRfVkFMVUUgPSA4NDsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF84NSA9IDg1OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF84NV9WQUxVRSA9IDg1OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzg2ID0gODY7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzg2X1ZBTFVFID0gODY7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfODcgPSA4Nzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfODdfVkFMVUUgPSA4NzsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF84OCA9IDg4OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF84OF9WQUxVRSA9IDg4OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzg5ID0gODk7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzg5X1ZBTFVFID0gODk7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfOTAgPSA5MDs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfOTBfVkFMVUUgPSA5MDsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF85MSA9IDkxOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF85MV9WQUxVRSA9IDkxOwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzkyID0gOTI7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzkyX1ZBTFVFID0gOTI7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfOTMgPSA5Mzs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfOTNfVkFMVUUgPSA5MzsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF85NCA9IDk0OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF85NF9WQUxVRSA9IDk0OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzk1ID0gOTU7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzk1X1ZBTFVFID0gOTU7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfOTYgPSA5Njs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfOTZfVkFMVUUgPSA5NjsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF85NyA9IDk3OzwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9MQUJFTF85N19WQUxVRSA9IDk3OwogICAgLyoqCiAgICAgKiA8Y29kZT5FTlVNX0xBQkVMXzk4ID0gOTg7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzk4X1ZBTFVFID0gOTg7CiAgICAvKioKICAgICAqIDxjb2RlPkVOVU1fTEFCRUxfOTkgPSA5OTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEVOVU1fTEFCRUxfOTlfVkFMVUUgPSA5OTsKICAgIC8qKgogICAgICogPGNvZGU+RU5VTV9MQUJFTF8xMDAgPSAxMDA7PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX0xBQkVMXzEwMF9WQUxVRSA9IDEwMDsKCgogICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgIHJldHVybiB2YWx1ZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgcHVibGljIHN0YXRpYyBWZXJ5TGFyZ2VFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVmVyeUxhcmdlRW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICBjYXNlIDA6IHJldHVybiBFTlVNX0xBQkVMX0RFRkFVTFQ7CiAgICAgICAgY2FzZSAxOiByZXR1cm4gRU5VTV9MQUJFTF8xOwogICAgICAgIGNhc2UgMjogcmV0dXJuIEVOVU1fTEFCRUxfMjsKICAgICAgICBjYXNlIDM6IHJldHVybiBFTlVNX0xBQkVMXzM7CiAgICAgICAgY2FzZSA0OiByZXR1cm4gRU5VTV9MQUJFTF80OwogICAgICAgIGNhc2UgNTogcmV0dXJuIEVOVU1fTEFCRUxfNTsKICAgICAgICBjYXNlIDY6IHJldHVybiBFTlVNX0xBQkVMXzY7CiAgICAgICAgY2FzZSA3OiByZXR1cm4gRU5VTV9MQUJFTF83OwogICAgICAgIGNhc2UgODogcmV0dXJuIEVOVU1fTEFCRUxfODsKICAgICAgICBjYXNlIDk6IHJldHVybiBFTlVNX0xBQkVMXzk7CiAgICAgICAgY2FzZSAxMDogcmV0dXJuIEVOVU1fTEFCRUxfMTA7CiAgICAgICAgY2FzZSAxMTogcmV0dXJuIEVOVU1fTEFCRUxfMTE7CiAgICAgICAgY2FzZSAxMjogcmV0dXJuIEVOVU1fTEFCRUxfMTI7CiAgICAgICAgY2FzZSAxMzogcmV0dXJuIEVOVU1fTEFCRUxfMTM7CiAgICAgICAgY2FzZSAxNDogcmV0dXJuIEVOVU1fTEFCRUxfMTQ7CiAgICAgICAgY2FzZSAxNTogcmV0dXJuIEVOVU1fTEFCRUxfMTU7CiAgICAgICAgY2FzZSAxNjogcmV0dXJuIEVOVU1fTEFCRUxfMTY7CiAgICAgICAgY2FzZSAxNzogcmV0dXJuIEVOVU1fTEFCRUxfMTc7CiAgICAgICAgY2FzZSAxODogcmV0dXJuIEVOVU1fTEFCRUxfMTg7CiAgICAgICAgY2FzZSAxOTogcmV0dXJuIEVOVU1fTEFCRUxfMTk7CiAgICAgICAgY2FzZSAyMDogcmV0dXJuIEVOVU1fTEFCRUxfMjA7CiAgICAgICAgY2FzZSAyMTogcmV0dXJuIEVOVU1fTEFCRUxfMjE7CiAgICAgICAgY2FzZSAyMjogcmV0dXJuIEVOVU1fTEFCRUxfMjI7CiAgICAgICAgY2FzZSAyMzogcmV0dXJuIEVOVU1fTEFCRUxfMjM7CiAgICAgICAgY2FzZSAyNDogcmV0dXJuIEVOVU1fTEFCRUxfMjQ7CiAgICAgICAgY2FzZSAyNTogcmV0dXJuIEVOVU1fTEFCRUxfMjU7CiAgICAgICAgY2FzZSAyNjogcmV0dXJuIEVOVU1fTEFCRUxfMjY7CiAgICAgICAgY2FzZSAyNzogcmV0dXJuIEVOVU1fTEFCRUxfMjc7CiAgICAgICAgY2FzZSAyODogcmV0dXJuIEVOVU1fTEFCRUxfMjg7CiAgICAgICAgY2FzZSAyOTogcmV0dXJuIEVOVU1fTEFCRUxfMjk7CiAgICAgICAgY2FzZSAzMDogcmV0dXJuIEVOVU1fTEFCRUxfMzA7CiAgICAgICAgY2FzZSAzMTogcmV0dXJuIEVOVU1fTEFCRUxfMzE7CiAgICAgICAgY2FzZSAzMjogcmV0dXJuIEVOVU1fTEFCRUxfMzI7CiAgICAgICAgY2FzZSAzMzogcmV0dXJuIEVOVU1fTEFCRUxfMzM7CiAgICAgICAgY2FzZSAzNDogcmV0dXJuIEVOVU1fTEFCRUxfMzQ7CiAgICAgICAgY2FzZSAzNTogcmV0dXJuIEVOVU1fTEFCRUxfMzU7CiAgICAgICAgY2FzZSAzNjogcmV0dXJuIEVOVU1fTEFCRUxfMzY7CiAgICAgICAgY2FzZSAzNzogcmV0dXJuIEVOVU1fTEFCRUxfMzc7CiAgICAgICAgY2FzZSAzODogcmV0dXJuIEVOVU1fTEFCRUxfMzg7CiAgICAgICAgY2FzZSAzOTogcmV0dXJuIEVOVU1fTEFCRUxfMzk7CiAgICAgICAgY2FzZSA0MDogcmV0dXJuIEVOVU1fTEFCRUxfNDA7CiAgICAgICAgY2FzZSA0MTogcmV0dXJuIEVOVU1fTEFCRUxfNDE7CiAgICAgICAgY2FzZSA0MjogcmV0dXJuIEVOVU1fTEFCRUxfNDI7CiAgICAgICAgY2FzZSA0MzogcmV0dXJuIEVOVU1fTEFCRUxfNDM7CiAgICAgICAgY2FzZSA0NDogcmV0dXJuIEVOVU1fTEFCRUxfNDQ7CiAgICAgICAgY2FzZSA0NTogcmV0dXJuIEVOVU1fTEFCRUxfNDU7CiAgICAgICAgY2FzZSA0NjogcmV0dXJuIEVOVU1fTEFCRUxfNDY7CiAgICAgICAgY2FzZSA0NzogcmV0dXJuIEVOVU1fTEFCRUxfNDc7CiAgICAgICAgY2FzZSA0ODogcmV0dXJuIEVOVU1fTEFCRUxfNDg7CiAgICAgICAgY2FzZSA0OTogcmV0dXJuIEVOVU1fTEFCRUxfNDk7CiAgICAgICAgY2FzZSA1MDogcmV0dXJuIEVOVU1fTEFCRUxfNTA7CiAgICAgICAgY2FzZSA1MTogcmV0dXJuIEVOVU1fTEFCRUxfNTE7CiAgICAgICAgY2FzZSA1MjogcmV0dXJuIEVOVU1fTEFCRUxfNTI7CiAgICAgICAgY2FzZSA1MzogcmV0dXJuIEVOVU1fTEFCRUxfNTM7CiAgICAgICAgY2FzZSA1NDogcmV0dXJuIEVOVU1fTEFCRUxfNTQ7CiAgICAgICAgY2FzZSA1NTogcmV0dXJuIEVOVU1fTEFCRUxfNTU7CiAgICAgICAgY2FzZSA1NjogcmV0dXJuIEVOVU1fTEFCRUxfNTY7CiAgICAgICAgY2FzZSA1NzogcmV0dXJuIEVOVU1fTEFCRUxfNTc7CiAgICAgICAgY2FzZSA1ODogcmV0dXJuIEVOVU1fTEFCRUxfNTg7CiAgICAgICAgY2FzZSA1OTogcmV0dXJuIEVOVU1fTEFCRUxfNTk7CiAgICAgICAgY2FzZSA2MDogcmV0dXJuIEVOVU1fTEFCRUxfNjA7CiAgICAgICAgY2FzZSA2MTogcmV0dXJuIEVOVU1fTEFCRUxfNjE7CiAgICAgICAgY2FzZSA2MjogcmV0dXJuIEVOVU1fTEFCRUxfNjI7CiAgICAgICAgY2FzZSA2MzogcmV0dXJuIEVOVU1fTEFCRUxfNjM7CiAgICAgICAgY2FzZSA2NDogcmV0dXJuIEVOVU1fTEFCRUxfNjQ7CiAgICAgICAgY2FzZSA2NTogcmV0dXJuIEVOVU1fTEFCRUxfNjU7CiAgICAgICAgY2FzZSA2NjogcmV0dXJuIEVOVU1fTEFCRUxfNjY7CiAgICAgICAgY2FzZSA2NzogcmV0dXJuIEVOVU1fTEFCRUxfNjc7CiAgICAgICAgY2FzZSA2ODogcmV0dXJuIEVOVU1fTEFCRUxfNjg7CiAgICAgICAgY2FzZSA2OTogcmV0dXJuIEVOVU1fTEFCRUxfNjk7CiAgICAgICAgY2FzZSA3MDogcmV0dXJuIEVOVU1fTEFCRUxfNzA7CiAgICAgICAgY2FzZSA3MTogcmV0dXJuIEVOVU1fTEFCRUxfNzE7CiAgICAgICAgY2FzZSA3MjogcmV0dXJuIEVOVU1fTEFCRUxfNzI7CiAgICAgICAgY2FzZSA3MzogcmV0dXJuIEVOVU1fTEFCRUxfNzM7CiAgICAgICAgY2FzZSA3NDogcmV0dXJuIEVOVU1fTEFCRUxfNzQ7CiAgICAgICAgY2FzZSA3NTogcmV0dXJuIEVOVU1fTEFCRUxfNzU7CiAgICAgICAgY2FzZSA3NjogcmV0dXJuIEVOVU1fTEFCRUxfNzY7CiAgICAgICAgY2FzZSA3NzogcmV0dXJuIEVOVU1fTEFCRUxfNzc7CiAgICAgICAgY2FzZSA3ODogcmV0dXJuIEVOVU1fTEFCRUxfNzg7CiAgICAgICAgY2FzZSA3OTogcmV0dXJuIEVOVU1fTEFCRUxfNzk7CiAgICAgICAgY2FzZSA4MDogcmV0dXJuIEVOVU1fTEFCRUxfODA7CiAgICAgICAgY2FzZSA4MTogcmV0dXJuIEVOVU1fTEFCRUxfODE7CiAgICAgICAgY2FzZSA4MjogcmV0dXJuIEVOVU1fTEFCRUxfODI7CiAgICAgICAgY2FzZSA4MzogcmV0dXJuIEVOVU1fTEFCRUxfODM7CiAgICAgICAgY2FzZSA4NDogcmV0dXJuIEVOVU1fTEFCRUxfODQ7CiAgICAgICAgY2FzZSA4NTogcmV0dXJuIEVOVU1fTEFCRUxfODU7CiAgICAgICAgY2FzZSA4NjogcmV0dXJuIEVOVU1fTEFCRUxfODY7CiAgICAgICAgY2FzZSA4NzogcmV0dXJuIEVOVU1fTEFCRUxfODc7CiAgICAgICAgY2FzZSA4ODogcmV0dXJuIEVOVU1fTEFCRUxfODg7CiAgICAgICAgY2FzZSA4OTogcmV0dXJuIEVOVU1fTEFCRUxfODk7CiAgICAgICAgY2FzZSA5MDogcmV0dXJuIEVOVU1fTEFCRUxfOTA7CiAgICAgICAgY2FzZSA5MTogcmV0dXJuIEVOVU1fTEFCRUxfOTE7CiAgICAgICAgY2FzZSA5MjogcmV0dXJuIEVOVU1fTEFCRUxfOTI7CiAgICAgICAgY2FzZSA5MzogcmV0dXJuIEVOVU1fTEFCRUxfOTM7CiAgICAgICAgY2FzZSA5NDogcmV0dXJuIEVOVU1fTEFCRUxfOTQ7CiAgICAgICAgY2FzZSA5NTogcmV0dXJuIEVOVU1fTEFCRUxfOTU7CiAgICAgICAgY2FzZSA5NjogcmV0dXJuIEVOVU1fTEFCRUxfOTY7CiAgICAgICAgY2FzZSA5NzogcmV0dXJuIEVOVU1fTEFCRUxfOTc7CiAgICAgICAgY2FzZSA5ODogcmV0dXJuIEVOVU1fTEFCRUxfOTg7CiAgICAgICAgY2FzZSA5OTogcmV0dXJuIEVOVU1fTEFCRUxfOTk7CiAgICAgICAgY2FzZSAxMDA6IHJldHVybiBFTlVNX0xBQkVMXzEwMDsKICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxWZXJ5TGFyZ2VFbnVtPgogICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgfQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICBWZXJ5TGFyZ2VFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFZlcnlMYXJnZUVudW0+KCkgewogICAgICAgICAgICBwdWJsaWMgVmVyeUxhcmdlRW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIFZlcnlMYXJnZUVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgIH0KICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDQpOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFZlcnlMYXJnZUVudW1bXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICBwdWJsaWMgc3RhdGljIFZlcnlMYXJnZUVudW0gdmFsdWVPZigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgfQogICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgcHJpdmF0ZSBWZXJ5TGFyZ2VFbnVtKGludCB2YWx1ZSkgewogICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVmVyeUxhcmdlRW51bSkKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBTaW5ndWxhcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMigpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogU2luZ3VsYXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxJbnQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQ2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbEludDY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsVWludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQ2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbFVpbnQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxTaW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbFNpbnQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNpbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxTaW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTaW50NjQuCiAgICAgKi8KICAgIGxvbmcgZ2V0T3B0aW9uYWxTaW50NjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgb3B0aW9uYWxfZml4ZWQzMiA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEZpeGVkMzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsRml4ZWQzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsRml4ZWQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBvcHRpb25hbF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRml4ZWQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxGaXhlZDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGaXhlZDY0LgogICAgICovCiAgICBsb25nIGdldE9wdGlvbmFsRml4ZWQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTZml4ZWQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxTZml4ZWQzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBvcHRpb25hbF9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsU2ZpeGVkMzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNmaXhlZDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFNmaXhlZDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZml4ZWQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbFNmaXhlZDY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBvcHRpb25hbF9mbG9hdCA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxGbG9hdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBvcHRpb25hbF9mbG9hdCA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRmxvYXQuCiAgICAgKi8KICAgIGZsb2F0IGdldE9wdGlvbmFsRmxvYXQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBvcHRpb25hbF9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRG91YmxlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbERvdWJsZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgb3B0aW9uYWxfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxEb3VibGUuCiAgICAgKi8KICAgIGRvdWJsZSBnZXRPcHRpb25hbERvdWJsZSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBvcHRpb25hbF9ib29sID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEJvb2wgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsQm9vbCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJvb2wuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0T3B0aW9uYWxCb29sKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsU3RyaW5nQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEJ5dGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlcy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9wdGlvbmFsQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbGdyb3VwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEdyb3VwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxncm91cC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCBnZXRPcHRpb25hbEdyb3VwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwT3JCdWlsZGVyIGdldE9wdGlvbmFsR3JvdXBPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEZvcmVpZ25NZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25NZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkRW51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxOZXN0ZWRFbnVtKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkRW51bS4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRPcHRpb25hbE5lc3RlZEVudW0oKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRm9yZWlnbkVudW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsRm9yZWlnbkVudW0oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0T3B0aW9uYWxGb3JlaWduRW51bSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtIG9wdGlvbmFsX2ltcG9ydF9lbnVtID0gMjM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEltcG9ydEVudW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW1wb3J0RW51bSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW0gb3B0aW9uYWxfaW1wb3J0X2VudW0gPSAyMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEltcG9ydEVudW0uCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtIGdldE9wdGlvbmFsSW1wb3J0RW51bSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFN0cmluZ1BpZWNlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFN0cmluZ1BpZWNlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmdQaWVjZS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxDb3JkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbENvcmQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbENvcmQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxDb3JkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsQ29yZC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxDb3JkQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxMYXp5TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbExhenlNZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF91bnZlcmlmaWVkX2xhenlfbWVzc2FnZSA9IDI4IFt1bnZlcmlmaWVkX2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRSZXBlYXRlZEludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUmVwZWF0ZWQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUmVwZWF0ZWQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+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+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZ0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZyhpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJ5dGVzLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldFJlcGVhdGVkQnl0ZXNMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCeXRlcy4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQnl0ZXNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCeXRlcyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXBlYXRlZEJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gNDYgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cD4gCiAgICAgICAgZ2V0UmVwZWF0ZWRHcm91cExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDQ2IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgZ2V0UmVwZWF0ZWRHcm91cChpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gNDYgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkR3JvdXBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gNDYgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXBPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkR3JvdXBPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwT3JCdWlsZGVyIGdldFJlcGVhdGVkR3JvdXBPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gCiAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gCiAgICAgICAgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gCiAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWROZXN0ZWRFbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXRSZXBlYXRlZE5lc3RlZEVudW0oaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtPiBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGb3JlaWduRW51bS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkRm9yZWlnbkVudW1Db3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW0gcmVwZWF0ZWRfaW1wb3J0X2VudW0gPSA1Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEltcG9ydEVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtPiBnZXRSZXBlYXRlZEltcG9ydEVudW1MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSByZXBlYXRlZF9pbXBvcnRfZW51bSA9IDUzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW1wb3J0RW51bS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW1wb3J0RW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSByZXBlYXRlZF9pbXBvcnRfZW51bSA9IDUzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbXBvcnRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0gZ2V0UmVwZWF0ZWRJbXBvcnRFbnVtKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQ29yZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZENvcmRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRDb3JkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRDb3JkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQ29yZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRDb3JkKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkQ29yZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkQ29yZEJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IAogICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRSZXBlYXRlZExhenlNZXNzYWdlKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZExhenlNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFNpbmd1bGFyIHdpdGggZGVmYXVsdHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRlZmF1bHRfaW50MzIgPSA2MSBbZGVmYXVsdCA9IDQxXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRGVmYXVsdEludDMyKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBTaW5ndWxhciB3aXRoIGRlZmF1bHRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkZWZhdWx0X2ludDMyID0gNjEgW2RlZmF1bHQgPSA0MV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVmYXVsdEludDMyLgogICAgICovCiAgICBpbnQgZ2V0RGVmYXVsdEludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBkZWZhdWx0X2ludDY0ID0gNjIgW2RlZmF1bHQgPSA0Ml07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0SW50NjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0RlZmF1bHRJbnQ2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBkZWZhdWx0X2ludDY0ID0gNjIgW2RlZmF1bHQgPSA0Ml07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVmYXVsdEludDY0LgogICAgICovCiAgICBsb25nIGdldERlZmF1bHRJbnQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIGRlZmF1bHRfdWludDMyID0gNjMgW2RlZmF1bHQgPSA0M107PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0VWludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZWZhdWx0VWludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBkZWZhdWx0X3VpbnQzMiA9IDYzIFtkZWZhdWx0ID0gNDNdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRVaW50MzIuCiAgICAgKi8KICAgIGludCBnZXREZWZhdWx0VWludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgZGVmYXVsdF91aW50NjQgPSA2NCBbZGVmYXVsdCA9IDQ0XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRVaW50NjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0RlZmF1bHRVaW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGRlZmF1bHRfdWludDY0ID0gNjQgW2RlZmF1bHQgPSA0NF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVmYXVsdFVpbnQ2NC4KICAgICAqLwogICAgbG9uZyBnZXREZWZhdWx0VWludDY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgZGVmYXVsdF9zaW50MzIgPSA2NSBbZGVmYXVsdCA9IC00NV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0U2ludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZWZhdWx0U2ludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBkZWZhdWx0X3NpbnQzMiA9IDY1IFtkZWZhdWx0ID0gLTQ1XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0U2ludDMyLgogICAgICovCiAgICBpbnQgZ2V0RGVmYXVsdFNpbnQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IGRlZmF1bHRfc2ludDY0ID0gNjYgW2RlZmF1bHQgPSA0Nl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0U2ludDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZWZhdWx0U2ludDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBkZWZhdWx0X3NpbnQ2NCA9IDY2IFtkZWZhdWx0ID0gNDZdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRTaW50NjQuCiAgICAgKi8KICAgIGxvbmcgZ2V0RGVmYXVsdFNpbnQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBkZWZhdWx0X2ZpeGVkMzIgPSA2NyBbZGVmYXVsdCA9IDQ3XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRGaXhlZDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZWZhdWx0Rml4ZWQzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIGRlZmF1bHRfZml4ZWQzMiA9IDY3IFtkZWZhdWx0ID0gNDddOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRGaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0RGVmYXVsdEZpeGVkMzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgZGVmYXVsdF9maXhlZDY0ID0gNjggW2RlZmF1bHQgPSA0OF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0Rml4ZWQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRGVmYXVsdEZpeGVkNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBkZWZhdWx0X2ZpeGVkNjQgPSA2OCBbZGVmYXVsdCA9IDQ4XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0Rml4ZWQ2NC4KICAgICAqLwogICAgbG9uZyBnZXREZWZhdWx0Rml4ZWQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgZGVmYXVsdF9zZml4ZWQzMiA9IDY5IFtkZWZhdWx0ID0gNDldOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdFNmaXhlZDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZWZhdWx0U2ZpeGVkMzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgZGVmYXVsdF9zZml4ZWQzMiA9IDY5IFtkZWZhdWx0ID0gNDldOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRTZml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldERlZmF1bHRTZml4ZWQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgZGVmYXVsdF9zZml4ZWQ2NCA9IDcwIFtkZWZhdWx0ID0gLTUwXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRTZml4ZWQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRGVmYXVsdFNmaXhlZDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDY0IGRlZmF1bHRfc2ZpeGVkNjQgPSA3MCBbZGVmYXVsdCA9IC01MF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVmYXVsdFNmaXhlZDY0LgogICAgICovCiAgICBsb25nIGdldERlZmF1bHRTZml4ZWQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZGVmYXVsdF9mbG9hdCA9IDcxIFtkZWZhdWx0ID0gNTEuNV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0RmxvYXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0RlZmF1bHRGbG9hdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBkZWZhdWx0X2Zsb2F0ID0gNzEgW2RlZmF1bHQgPSA1MS41XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0RmxvYXQuCiAgICAgKi8KICAgIGZsb2F0IGdldERlZmF1bHRGbG9hdCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGRlZmF1bHRfZG91YmxlID0gNzIgW2RlZmF1bHQgPSA1MjAwMF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0RG91YmxlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZWZhdWx0RG91YmxlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBkZWZhdWx0X2RvdWJsZSA9IDcyIFtkZWZhdWx0ID0gNTIwMDBdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHREb3VibGUuCiAgICAgKi8KICAgIGRvdWJsZSBnZXREZWZhdWx0RG91YmxlKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRlZmF1bHRfYm9vbCA9IDczIFtkZWZhdWx0ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0Qm9vbCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRGVmYXVsdEJvb2woKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZWZhdWx0X2Jvb2wgPSA3MyBbZGVmYXVsdCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRCb29sLgogICAgICovCiAgICBib29sZWFuIGdldERlZmF1bHRCb29sKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmcgPSA3NCBbZGVmYXVsdCA9ICJoZWxsbyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdFN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRGVmYXVsdFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmcgPSA3NCBbZGVmYXVsdCA9ICJoZWxsbyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRTdHJpbmcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RGVmYXVsdFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmcgPSA3NCBbZGVmYXVsdCA9ICJoZWxsbyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBkZWZhdWx0U3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXREZWZhdWx0U3RyaW5nQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGRlZmF1bHRfYnl0ZXMgPSA3NSBbZGVmYXVsdCA9ICJ3b3JsZCJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdEJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZWZhdWx0Qnl0ZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZGVmYXVsdF9ieXRlcyA9IDc1IFtkZWZhdWx0ID0gIndvcmxkIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVmYXVsdEJ5dGVzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RGVmYXVsdEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZGVmYXVsdF9uZXN0ZWRfZW51bSA9IDgxIFtkZWZhdWx0ID0gQkFSXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHROZXN0ZWRFbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZWZhdWx0TmVzdGVkRW51bSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZGVmYXVsdF9uZXN0ZWRfZW51bSA9IDgxIFtkZWZhdWx0ID0gQkFSXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0TmVzdGVkRW51bS4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXREZWZhdWx0TmVzdGVkRW51bSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIGRlZmF1bHRfZm9yZWlnbl9lbnVtID0gODIgW2RlZmF1bHQgPSBGT1JFSUdOX0JBUl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0Rm9yZWlnbkVudW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0RlZmF1bHRGb3JlaWduRW51bSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gZGVmYXVsdF9mb3JlaWduX2VudW0gPSA4MiBbZGVmYXVsdCA9IEZPUkVJR05fQkFSXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0Rm9yZWlnbkVudW0uCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0RGVmYXVsdEZvcmVpZ25FbnVtKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW0gZGVmYXVsdF9pbXBvcnRfZW51bSA9IDgzIFtkZWZhdWx0ID0gSU1QT1JUX0JBUl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0SW1wb3J0RW51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRGVmYXVsdEltcG9ydEVudW0oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtIGRlZmF1bHRfaW1wb3J0X2VudW0gPSA4MyBbZGVmYXVsdCA9IElNUE9SVF9CQVJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRJbXBvcnRFbnVtLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bSBnZXREZWZhdWx0SW1wb3J0RW51bSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nX3BpZWNlID0gODQgW2RlZmF1bHQgPSAiYWJjIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdFN0cmluZ1BpZWNlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZWZhdWx0U3RyaW5nUGllY2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nX3BpZWNlID0gODQgW2RlZmF1bHQgPSAiYWJjIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRTdHJpbmdQaWVjZS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXREZWZhdWx0U3RyaW5nUGllY2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nX3BpZWNlID0gODQgW2RlZmF1bHQgPSAiYWJjIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBkZWZhdWx0U3RyaW5nUGllY2UuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldERlZmF1bHRTdHJpbmdQaWVjZUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9jb3JkID0gODUgW2RlZmF1bHQgPSAiMTIzIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRDb3JkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEZWZhdWx0Q29yZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9jb3JkID0gODUgW2RlZmF1bHQgPSAiMTIzIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0Q29yZC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXREZWZhdWx0Q29yZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9jb3JkID0gODUgW2RlZmF1bHQgPSAiMTIzIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZGVmYXVsdENvcmQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldERlZmF1bHRDb3JkQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlVpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZVaW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDExMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZlVpbnQzMi4KICAgICAqLwogICAgaW50IGdldE9uZW9mVWludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZk5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09uZW9mTmVzdGVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9uZW9mTmVzdGVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9uZW9mTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPbmVvZlN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mU3RyaW5nLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9uZW9mU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9uZW9mU3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPbmVvZlN0cmluZ0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDExNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09uZW9mQnl0ZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZCeXRlcy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9uZW9mQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9jb3JkID0gMTE1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZDb3JkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPbmVvZkNvcmQoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX2NvcmQgPSAxMTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZDb3JkLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9uZW9mQ29yZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2ZfY29yZCA9IDExNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb25lb2ZDb3JkLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPbmVvZkNvcmRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZ19waWVjZSA9IDExNiBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZTdHJpbmdQaWVjZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZTdHJpbmdQaWVjZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nX3BpZWNlID0gMTE2IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZTdHJpbmdQaWVjZS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRPbmVvZlN0cmluZ1BpZWNlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmdfcGllY2UgPSAxMTYgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmdQaWVjZS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T25lb2ZTdHJpbmdQaWVjZUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbGF6eV9uZXN0ZWRfbWVzc2FnZSA9IDExNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZMYXp5TmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZMYXp5TmVzdGVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbGF6eV9uZXN0ZWRfbWVzc2FnZSA9IDExNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mTGF6eU5lc3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T25lb2ZMYXp5TmVzdGVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbGF6eV9uZXN0ZWRfbWVzc2FnZSA9IDExNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPbmVvZkxhenlOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCk7CgogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT25lb2ZGaWVsZENhc2UgZ2V0T25lb2ZGaWVsZENhc2UoKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUaGlzIHByb3RvIGluY2x1ZGVzIGV2ZXJ5IHR5cGUgb2YgZmllbGQgaW4gYm90aCBzaW5ndWxhciBhbmQgcmVwZWF0ZWQKICAgKiBmb3Jtcy4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RBbGxUeXBlcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMpCiAgICAgIFRlc3RBbGxUeXBlc09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RBbGxUeXBlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RBbGxUeXBlcygpIHsKICAgICAgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgIG9wdGlvbmFsQnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gMTsKICAgICAgb3B0aW9uYWxGb3JlaWduRW51bV8gPSA0OwogICAgICBvcHRpb25hbEltcG9ydEVudW1fID0gNzsKICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSAiIjsKICAgICAgb3B0aW9uYWxDb3JkXyA9ICIiOwogICAgICByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICByZXBlYXRlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICByZXBlYXRlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgcmVwZWF0ZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRCeXRlc18gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgcmVwZWF0ZWRHcm91cF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZE5lc3RlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRJbXBvcnRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZENvcmRfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIGRlZmF1bHRJbnQzMl8gPSA0MTsKICAgICAgZGVmYXVsdEludDY0XyA9IDQyTDsKICAgICAgZGVmYXVsdFVpbnQzMl8gPSA0MzsKICAgICAgZGVmYXVsdFVpbnQ2NF8gPSA0NEw7CiAgICAgIGRlZmF1bHRTaW50MzJfID0gLTQ1OwogICAgICBkZWZhdWx0U2ludDY0XyA9IDQ2TDsKICAgICAgZGVmYXVsdEZpeGVkMzJfID0gNDc7CiAgICAgIGRlZmF1bHRGaXhlZDY0XyA9IDQ4TDsKICAgICAgZGVmYXVsdFNmaXhlZDMyXyA9IDQ5OwogICAgICBkZWZhdWx0U2ZpeGVkNjRfID0gLTUwTDsKICAgICAgZGVmYXVsdEZsb2F0XyA9IDUxLjVGOwogICAgICBkZWZhdWx0RG91YmxlXyA9IDUyMDAwRDsKICAgICAgZGVmYXVsdEJvb2xfID0gdHJ1ZTsKICAgICAgZGVmYXVsdFN0cmluZ18gPSAiaGVsbG8iOwogICAgICBkZWZhdWx0Qnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5ieXRlc0RlZmF1bHRWYWx1ZSgid29ybGQiKTsKICAgICAgZGVmYXVsdE5lc3RlZEVudW1fID0gMjsKICAgICAgZGVmYXVsdEZvcmVpZ25FbnVtXyA9IDU7CiAgICAgIGRlZmF1bHRJbXBvcnRFbnVtXyA9IDg7CiAgICAgIGRlZmF1bHRTdHJpbmdQaWVjZV8gPSAiYWJjIjsKICAgICAgZGVmYXVsdENvcmRfID0gIjEyMyI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdEFsbFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW19CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIE5lc3RlZEVudW0KICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEZPTygxKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQkFSKDIpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QkFaID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVooMyksCiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBJbnRlbnRpb25hbGx5IG5lZ2F0aXZlLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+TkVHID0gLTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgTkVHKC0xKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSX1ZBTFVFID0gMjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBWiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFaX1ZBTFVFID0gMzsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEludGVudGlvbmFsbHkgbmVnYXRpdmUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5ORUcgPSAtMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBORUdfVkFMVUUgPSAtMTsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIEZPTzsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIEJBUjsKICAgICAgICAgIGNhc2UgMzogcmV0dXJuIEJBWjsKICAgICAgICAgIGNhc2UgLTE6IHJldHVybiBORUc7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxOZXN0ZWRFbnVtPgogICAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgICAgfQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgICAgTmVzdGVkRW51bT4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE5lc3RlZEVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBOZXN0ZWRFbnVtIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBOZXN0ZWRFbnVtLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgICB9CiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTmVzdGVkRW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgTmVzdGVkRW51bShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtKQogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICogVGhpcyBmaWxlIG5lZWRzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIHRvIHRlc3QgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJiIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzQmIoKTsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAqIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCiAgICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYmIuCiAgICAgICAqLwogICAgICBpbnQgZ2V0QmIoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTmVzdGVkTWVzc2FnZSBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgLy8gVXNlIE5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBOZXN0ZWRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBOZXN0ZWRNZXNzYWdlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQl9GSUVMRF9OVU1CRVIgPSAxOwogICAgICBwcml2YXRlIGludCBiYl8gPSAwOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICogVGhpcyBmaWxlIG5lZWRzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIHRvIHRlc3QgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJiIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQmIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJiLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEJiKCkgewogICAgICAgIHJldHVybiBiYl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBiYl8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBiYl8pOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9iajsKCiAgICAgICAgaWYgKGhhc0JiKCkgIT0gb3RoZXIuaGFzQmIoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNCYigpKSB7CiAgICAgICAgICBpZiAoZ2V0QmIoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEJiKCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNCYigpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCQl9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCYigpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBiYl8gPSAwOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LmJiXyA9IGJiXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSlvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzQmIoKSkgewogICAgICAgICAgICBzZXRCYihvdGhlci5nZXRCYigpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgICBiYl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCBiYl8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJiIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzQmIoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBiYi4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRCYigpIHsKICAgICAgICAgIHJldHVybiBiYl87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogVGhlIGZpZWxkIG5hbWUgImIiIGZhaWxzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIGJlY2F1c2UgaXQgY29uZmxpY3RzIHdpdGgKICAgICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJiIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmIoaW50IHZhbHVlKSB7CgogICAgICAgICAgYmJfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQmIoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBiYl8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxOZXN0ZWRNZXNzYWdlPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE5lc3RlZE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBPcHRpb25hbEdyb3VwT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXApCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNBKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICAgKi8KICAgICAgaW50IGdldEEoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXB9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgT3B0aW9uYWxHcm91cCBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXApCiAgICAgICAgT3B0aW9uYWxHcm91cE9yQnVpbGRlciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgLy8gVXNlIE9wdGlvbmFsR3JvdXAubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBPcHRpb25hbEdyb3VwKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgT3B0aW9uYWxHcm91cCgpIHsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBPcHRpb25hbEdyb3VwKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfT3B0aW9uYWxHcm91cF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfT3B0aW9uYWxHcm91cF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBX0ZJRUxEX05VTUJFUiA9IDE3OwogICAgICBwcml2YXRlIGludCBhXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgIHJldHVybiBhXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDE3LCBhXyk7CiAgICAgICAgfQogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDE3LCBhXyk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXApKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCkgb2JqOwoKICAgICAgICBpZiAoaGFzQSgpICE9IG90aGVyLmhhc0EoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICAgIGlmIChnZXRBKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRBKCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCkKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXBPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX09wdGlvbmFsR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19PcHRpb25hbEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBhXyA9IDA7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19PcHRpb25hbEdyb3VwX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIGJ1aWxkKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQuYV8gPSBhXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXApIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cClvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzQSgpKSB7CiAgICAgICAgICAgIHNldEEob3RoZXIuZ2V0QSgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMTM2OiB7CiAgICAgICAgICAgICAgICAgIGFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM2CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCBhXyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE3OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTc7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0QSgpIHsKICAgICAgICAgIHJldHVybiBhXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE3OzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGEgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRBKGludCB2YWx1ZSkgewoKICAgICAgICAgIGFfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTc7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBhXyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXApCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T3B0aW9uYWxHcm91cD4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE9wdGlvbmFsR3JvdXA+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgT3B0aW9uYWxHcm91cCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE9wdGlvbmFsR3JvdXA+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPcHRpb25hbEdyb3VwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIFJlcGVhdGVkR3JvdXBPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA0Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc0EoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA0Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgICAqLwogICAgICBpbnQgZ2V0QSgpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBSZXBlYXRlZEdyb3VwIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCkKICAgICAgICBSZXBlYXRlZEdyb3VwT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgUmVwZWF0ZWRHcm91cC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIFJlcGVhdGVkR3JvdXAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBSZXBlYXRlZEdyb3VwKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IFJlcGVhdGVkR3JvdXAoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19SZXBlYXRlZEdyb3VwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19SZXBlYXRlZEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFfRklFTERfTlVNQkVSID0gNDc7CiAgICAgIHByaXZhdGUgaW50IGFfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA0Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gNDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEEoKSB7CiAgICAgICAgcmV0dXJuIGFfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNDcsIGFfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNDcsIGFfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwKSBvYmo7CgogICAgICAgIGlmIChoYXNBKCkgIT0gb3RoZXIuaGFzQSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgICAgaWYgKGdldEEoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEEoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBKCk7CiAgICAgICAgfQogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXB9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwKQogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cE9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfUmVwZWF0ZWRHcm91cF9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX1JlcGVhdGVkR3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cC5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGFfID0gMDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX1JlcGVhdGVkR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5hXyA9IGFfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5oYXNBKCkpIHsKICAgICAgICAgICAgc2V0QShvdGhlci5nZXRBKCkpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAzNzY6IHsKICAgICAgICAgICAgICAgICAgYV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSAzNzYKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IGFfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gNDc7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA0Nzs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgICAgcmV0dXJuIGFfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gNDc7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYSB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEEoaW50IHZhbHVlKSB7CgogICAgICAgICAgYV8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA0Nzs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQSgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIGFfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXApCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXBlYXRlZEdyb3VwPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8UmVwZWF0ZWRHcm91cD4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBSZXBlYXRlZEdyb3VwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVwZWF0ZWRHcm91cD4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlcGVhdGVkR3JvdXA+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwcml2YXRlIGludCBiaXRGaWVsZDFfOwogICAgcHJpdmF0ZSBpbnQgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9uZW9mRmllbGRfOwogICAgcHVibGljIGVudW0gT25lb2ZGaWVsZENhc2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkludGVybmFsT25lT2ZFbnVtIHsKICAgICAgT05FT0ZfVUlOVDMyKDExMSksCiAgICAgIE9ORU9GX05FU1RFRF9NRVNTQUdFKDExMiksCiAgICAgIE9ORU9GX1NUUklORygxMTMpLAogICAgICBPTkVPRl9CWVRFUygxMTQpLAogICAgICBPTkVPRl9DT1JEKDExNSksCiAgICAgIE9ORU9GX1NUUklOR19QSUVDRSgxMTYpLAogICAgICBPTkVPRl9MQVpZX05FU1RFRF9NRVNTQUdFKDExNyksCiAgICAgIE9ORU9GRklFTERfTk9UX1NFVCgwKTsKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CiAgICAgIHByaXZhdGUgT25lb2ZGaWVsZENhc2UoaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWJlciBvZiB0aGUgZW51bSB0byBsb29rIGZvci4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWJlci4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBPbmVvZkZpZWxkQ2FzZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIE9uZW9mRmllbGRDYXNlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDExMTogcmV0dXJuIE9ORU9GX1VJTlQzMjsKICAgICAgICAgIGNhc2UgMTEyOiByZXR1cm4gT05FT0ZfTkVTVEVEX01FU1NBR0U7CiAgICAgICAgICBjYXNlIDExMzogcmV0dXJuIE9ORU9GX1NUUklORzsKICAgICAgICAgIGNhc2UgMTE0OiByZXR1cm4gT05FT0ZfQllURVM7CiAgICAgICAgICBjYXNlIDExNTogcmV0dXJuIE9ORU9GX0NPUkQ7CiAgICAgICAgICBjYXNlIDExNjogcmV0dXJuIE9ORU9GX1NUUklOR19QSUVDRTsKICAgICAgICAgIGNhc2UgMTE3OiByZXR1cm4gT05FT0ZfTEFaWV9ORVNURURfTUVTU0FHRTsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIE9ORU9GRklFTERfTk9UX1NFVDsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgT25lb2ZGaWVsZENhc2UKICAgIGdldE9uZW9mRmllbGRDYXNlKCkgewogICAgICByZXR1cm4gT25lb2ZGaWVsZENhc2UuZm9yTnVtYmVyKAogICAgICAgICAgb25lb2ZGaWVsZENhc2VfKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogU2luZ3VsYXIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBTaW5ndWxhcgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxJbnQ2NF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50NjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UMzJfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzIgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UNjRfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFVpbnQ2NF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IG9wdGlvbmFsX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDY0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBvcHRpb25hbF91aW50NjQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbFVpbnQ2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TSU5UMzJfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsU2ludDMyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBvcHRpb25hbF9zaW50MzIgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTaW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFNpbnQzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFNpbnQzMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsU2ludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TSU5UNjRfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFNpbnQ2NF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNpbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2ludDY0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBvcHRpb25hbF9zaW50NjQgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbFNpbnQ2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsU2ludDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9GSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDc7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEZpeGVkMzJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRml4ZWQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsRml4ZWQzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbEZpeGVkMzIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEZpeGVkMzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0ZJWEVENjRfRklFTERfTlVNQkVSID0gODsKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbEZpeGVkNjRfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEZpeGVkNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZpeGVkNjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBvcHRpb25hbF9maXhlZDY0ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZpeGVkNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsRml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsRml4ZWQ2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0ZJWEVEMzJfRklFTERfTlVNQkVSID0gOTsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsU2ZpeGVkMzJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTZml4ZWQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2ZpeGVkMzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ZpeGVkMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxTZml4ZWQzMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsU2ZpeGVkMzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NGSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDEwOwogICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsU2ZpeGVkNjRfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNmaXhlZDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTZml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ZpeGVkNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsU2ZpeGVkNjQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFNmaXhlZDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9GTE9BVF9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIHByaXZhdGUgZmxvYXQgb3B0aW9uYWxGbG9hdF8gPSAwRjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgb3B0aW9uYWxfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZsb2F0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG9wdGlvbmFsX2Zsb2F0ID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGbG9hdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldE9wdGlvbmFsRmxvYXQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEZsb2F0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9ET1VCTEVfRklFTERfTlVNQkVSID0gMTI7CiAgICBwcml2YXRlIGRvdWJsZSBvcHRpb25hbERvdWJsZV8gPSAwRDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIG9wdGlvbmFsX2RvdWJsZSA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxEb3VibGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbERvdWJsZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgb3B0aW9uYWxfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxEb3VibGUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0T3B0aW9uYWxEb3VibGUoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbERvdWJsZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQk9PTF9GSUVMRF9OVU1CRVIgPSAxMzsKICAgIHByaXZhdGUgYm9vbGVhbiBvcHRpb25hbEJvb2xfID0gZmFsc2U7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxCb29sIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxCb29sKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQm9vbC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0T3B0aW9uYWxCb29sKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxCb29sXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TVFJJTkdfRklFTERfTlVNQkVSID0gMTQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFN0cmluZ18gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFN0cmluZygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0JZVEVTX0ZJRUxEX05VTUJFUiA9IDE1OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgb3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxCeXRlcygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHRpb25hbF9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQnl0ZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T3B0aW9uYWxCeXRlcygpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsQnl0ZXNfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMR1JPVVBfRklFTERfTlVNQkVSID0gMTY7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAgb3B0aW9uYWxHcm91cF87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbGdyb3VwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxHcm91cCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsZ3JvdXAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIGdldE9wdGlvbmFsR3JvdXAoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEdyb3VwXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsR3JvdXBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXBPckJ1aWxkZXIgZ2V0T3B0aW9uYWxHcm91cE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsR3JvdXBfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxHcm91cF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTg7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9GT1JFSUdOX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTk7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxGb3JlaWduTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25NZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxGb3JlaWduTWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU1QT1JUX01FU1NBR0VfRklFTERfTlVNQkVSID0gMjA7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxJbXBvcnRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEltcG9ydE1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUiA9IDIxOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDE7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRFbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZEVudW0oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmZvck51bWJlcihvcHRpb25hbE5lc3RlZEVudW1fKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5GT08gOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRk9SRUlHTl9FTlVNX0ZJRUxEX05VTUJFUiA9IDIyOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxGb3JlaWduRW51bV8gPSA0OwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEZvcmVpZ25FbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZvcmVpZ25FbnVtKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIGdldE9wdGlvbmFsRm9yZWlnbkVudW0oKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIob3B0aW9uYWxGb3JlaWduRW51bV8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLkZPUkVJR05fRk9PIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lNUE9SVF9FTlVNX0ZJRUxEX05VTUJFUiA9IDIzOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbXBvcnRFbnVtXyA9IDc7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSBvcHRpb25hbF9pbXBvcnRfZW51bSA9IDIzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbXBvcnRFbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEltcG9ydEVudW0oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtIG9wdGlvbmFsX2ltcG9ydF9lbnVtID0gMjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbXBvcnRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bSBnZXRPcHRpb25hbEltcG9ydEVudW0oKSB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtIHJlc3VsdCA9IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtLmZvck51bWJlcihvcHRpb25hbEltcG9ydEVudW1fKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0uSU1QT1JUX0ZPTyA6IHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TVFJJTkdfUElFQ0VfRklFTERfTlVNQkVSID0gMjQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFN0cmluZ1BpZWNlXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU3RyaW5nUGllY2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFN0cmluZ1BpZWNlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nUGllY2UoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdQaWVjZV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmdQaWVjZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsU3RyaW5nUGllY2VCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ1BpZWNlXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9DT1JEX0ZJRUxEX05VTUJFUiA9IDI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxDb3JkXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxDb3JkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxDb3JkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxDb3JkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbENvcmQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxDb3JkXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBvcHRpb25hbENvcmRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxDb3JkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxDb3JkQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxDb3JkXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0aW9uYWxDb3JkXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1BVQkxJQ19JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAyNjsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXzsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDI3OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbExhenlNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VOVkVSSUZJRURfTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDI4OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAzMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRJbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUmVwZWF0ZWQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMzE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkSW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBSZXBlYXRlZAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfSU5UNjRfRklFTERfTlVNQkVSID0gMzI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZEludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkSW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9VSU5UMzJfRklFTERfTlVNQkVSID0gMzM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkVWludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkVWludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHJlcGVhdGVkX3VpbnQzMiA9IDMzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9VSU5UNjRfRklFTERfTlVNQkVSID0gMzQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFVpbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRVaW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0lOVDMyX0ZJRUxEX05VTUJFUiA9IDM1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFNpbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNpbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHJlcGVhdGVkX3NpbnQzMiA9IDM1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0lOVDY0X0ZJRUxEX05VTUJFUiA9IDM2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRTaW50NjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkU2ludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNpbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0ZJWEVEMzJfRklFTERfTlVNQkVSID0gMzc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkRml4ZWQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSAzODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkRml4ZWQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGaXhlZDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkRml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0ZJWEVEMzJfRklFTERfTlVNQkVSID0gMzk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkU2ZpeGVkMzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NGSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDQwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRTZml4ZWQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNmaXhlZDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFNmaXhlZDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRkxPQVRfRklFTERfTlVNQkVSID0gNDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5GbG9hdExpc3QgcmVwZWF0ZWRGbG9hdF8gPQogICAgICAgIGVtcHR5RmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGbG9hdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmxvYXQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDQxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGbG9hdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBmbG9hdCBnZXRSZXBlYXRlZEZsb2F0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uZ2V0RmxvYXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0RPVUJMRV9GSUVMRF9OVU1CRVIgPSA0MjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkRvdWJsZUxpc3QgcmVwZWF0ZWREb3VibGVfID0KICAgICAgICBlbXB0eURvdWJsZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRG91YmxlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICBnZXRSZXBlYXRlZERvdWJsZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZERvdWJsZS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZERvdWJsZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZG91YmxlIGdldFJlcGVhdGVkRG91YmxlKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWREb3VibGVfLmdldERvdWJsZShpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQk9PTF9GSUVMRF9OVU1CRVIgPSA0MzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHJlcGVhdGVkQm9vbF8gPQogICAgICAgIGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCb29sLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZ2V0UmVwZWF0ZWRCb29sTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJvb2xDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdldFJlcGVhdGVkQm9vbChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDQ0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZ18gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZy4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZ0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQllURVNfRklFTERfTlVNQkVSID0gNDU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiByZXBlYXRlZEJ5dGVzXyA9CiAgICAgICAgZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCeXRlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCeXRlc0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCeXRlcyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXNfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURHUk9VUF9GSUVMRF9OVU1CRVIgPSA0NjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwPiByZXBlYXRlZEdyb3VwXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDQ2IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwPiBnZXRSZXBlYXRlZEdyb3VwTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkR3JvdXBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gNDYgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZEdyb3VwT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkR3JvdXBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gNDYgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEdyb3VwQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEdyb3VwXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCBnZXRSZXBlYXRlZEdyb3VwKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRHcm91cF8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDQ2IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwT3JCdWlsZGVyIGdldFJlcGVhdGVkR3JvdXBPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEdyb3VwXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDQ4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRk9SRUlHTl9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDQ5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lNUE9SVF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDUwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlPiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVIgPSA1MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWROZXN0ZWRFbnVtXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLkZPTyA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+IGdldFJlcGVhdGVkTmVzdGVkRW51bUxpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPihyZXBlYXRlZE5lc3RlZEVudW1fLCByZXBlYXRlZE5lc3RlZEVudW1fY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZEVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkTmVzdGVkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWROZXN0ZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9GT1JFSUdOX0VOVU1fRklFTERfTlVNQkVSID0gNTI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkRm9yZWlnbkVudW1fOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+IHJlcGVhdGVkRm9yZWlnbkVudW1fY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLkZPUkVJR05fRk9PIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRm9yZWlnbkVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtPiBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+KHJlcGVhdGVkRm9yZWlnbkVudW1fLCByZXBlYXRlZEZvcmVpZ25FbnVtX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGb3JlaWduRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25FbnVtXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRm9yZWlnbkVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRGb3JlaWduRW51bV8uZ2V0KGluZGV4KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfSU1QT1JUX0VOVU1fRklFTERfTlVNQkVSID0gNTM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkSW1wb3J0RW51bV87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0+IHJlcGVhdGVkSW1wb3J0RW51bV9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0gY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bSByZXN1bHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bS5JTVBPUlRfRk9PIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtIHJlcGVhdGVkX2ltcG9ydF9lbnVtID0gNTM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbXBvcnRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0+IGdldFJlcGVhdGVkSW1wb3J0RW51bUxpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bT4ocmVwZWF0ZWRJbXBvcnRFbnVtXywgcmVwZWF0ZWRJbXBvcnRFbnVtX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW0gcmVwZWF0ZWRfaW1wb3J0X2VudW0gPSA1Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEltcG9ydEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbXBvcnRFbnVtQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydEVudW1fLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtIHJlcGVhdGVkX2ltcG9ydF9lbnVtID0gNTM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEltcG9ydEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0gZ2V0UmVwZWF0ZWRJbXBvcnRFbnVtKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRFbnVtX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZEltcG9ydEVudW1fLmdldChpbmRleCkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR19QSUVDRV9GSUVMRF9OVU1CRVIgPSA1NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmdQaWVjZV8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmdQaWVjZS4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmdQaWVjZS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nUGllY2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9DT1JEX0ZJRUxEX05VTUJFUiA9IDU1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZENvcmRfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRDb3JkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZENvcmRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZENvcmQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRDb3JkQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZENvcmRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQ29yZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkQ29yZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZF8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRDb3JkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkQ29yZEJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9MQVpZX01FU1NBR0VfRklFTERfTlVNQkVSID0gNTc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gcmVwZWF0ZWRMYXp5TWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+IGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZExhenlNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfSU5UMzJfRklFTERfTlVNQkVSID0gNjE7CiAgICBwcml2YXRlIGludCBkZWZhdWx0SW50MzJfID0gNDE7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBTaW5ndWxhciB3aXRoIGRlZmF1bHRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkZWZhdWx0X2ludDMyID0gNjEgW2RlZmF1bHQgPSA0MV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0SW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0SW50MzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDA4MDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFNpbmd1bGFyIHdpdGggZGVmYXVsdHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRlZmF1bHRfaW50MzIgPSA2MSBbZGVmYXVsdCA9IDQxXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0SW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RGVmYXVsdEludDMyKCkgewogICAgICByZXR1cm4gZGVmYXVsdEludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDYyOwogICAgcHJpdmF0ZSBsb25nIGRlZmF1bHRJbnQ2NF8gPSA0Mkw7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGRlZmF1bHRfaW50NjQgPSA2MiBbZGVmYXVsdCA9IDQyXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRJbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRJbnQ2NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBkZWZhdWx0X2ludDY0ID0gNjIgW2RlZmF1bHQgPSA0Ml07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVmYXVsdEludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXREZWZhdWx0SW50NjQoKSB7CiAgICAgIHJldHVybiBkZWZhdWx0SW50NjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDYzOwogICAgcHJpdmF0ZSBpbnQgZGVmYXVsdFVpbnQzMl8gPSA0MzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIGRlZmF1bHRfdWludDMyID0gNjMgW2RlZmF1bHQgPSA0M107PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0VWludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRGVmYXVsdFVpbnQzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgZGVmYXVsdF91aW50MzIgPSA2MyBbZGVmYXVsdCA9IDQzXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0VWludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldERlZmF1bHRVaW50MzIoKSB7CiAgICAgIHJldHVybiBkZWZhdWx0VWludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1VJTlQ2NF9GSUVMRF9OVU1CRVIgPSA2NDsKICAgIHByaXZhdGUgbG9uZyBkZWZhdWx0VWludDY0XyA9IDQ0TDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGRlZmF1bHRfdWludDY0ID0gNjQgW2RlZmF1bHQgPSA0NF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0VWludDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRGVmYXVsdFVpbnQ2NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgZGVmYXVsdF91aW50NjQgPSA2NCBbZGVmYXVsdCA9IDQ0XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0VWludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXREZWZhdWx0VWludDY0KCkgewogICAgICByZXR1cm4gZGVmYXVsdFVpbnQ2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9TSU5UMzJfRklFTERfTlVNQkVSID0gNjU7CiAgICBwcml2YXRlIGludCBkZWZhdWx0U2ludDMyXyA9IC00NTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIGRlZmF1bHRfc2ludDMyID0gNjUgW2RlZmF1bHQgPSAtNDVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdFNpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRTaW50MzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIGRlZmF1bHRfc2ludDMyID0gNjUgW2RlZmF1bHQgPSAtNDVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRTaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RGVmYXVsdFNpbnQzMigpIHsKICAgICAgcmV0dXJuIGRlZmF1bHRTaW50MzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfU0lOVDY0X0ZJRUxEX05VTUJFUiA9IDY2OwogICAgcHJpdmF0ZSBsb25nIGRlZmF1bHRTaW50NjRfID0gNDZMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgZGVmYXVsdF9zaW50NjQgPSA2NiBbZGVmYXVsdCA9IDQ2XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRTaW50NjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0U2ludDY0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBkZWZhdWx0X3NpbnQ2NCA9IDY2IFtkZWZhdWx0ID0gNDZdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRTaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldERlZmF1bHRTaW50NjQoKSB7CiAgICAgIHJldHVybiBkZWZhdWx0U2ludDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0ZJWEVEMzJfRklFTERfTlVNQkVSID0gNjc7CiAgICBwcml2YXRlIGludCBkZWZhdWx0Rml4ZWQzMl8gPSA0NzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBkZWZhdWx0X2ZpeGVkMzIgPSA2NyBbZGVmYXVsdCA9IDQ3XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRGaXhlZDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRGVmYXVsdEZpeGVkMzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBkZWZhdWx0X2ZpeGVkMzIgPSA2NyBbZGVmYXVsdCA9IDQ3XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0Rml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREZWZhdWx0Rml4ZWQzMigpIHsKICAgICAgcmV0dXJuIGRlZmF1bHRGaXhlZDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0ZJWEVENjRfRklFTERfTlVNQkVSID0gNjg7CiAgICBwcml2YXRlIGxvbmcgZGVmYXVsdEZpeGVkNjRfID0gNDhMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDY0IGRlZmF1bHRfZml4ZWQ2NCA9IDY4IFtkZWZhdWx0ID0gNDhdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdEZpeGVkNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0Rml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDY0IGRlZmF1bHRfZml4ZWQ2NCA9IDY4IFtkZWZhdWx0ID0gNDhdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRGaXhlZDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXREZWZhdWx0Rml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuIGRlZmF1bHRGaXhlZDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1NGSVhFRDMyX0ZJRUxEX05VTUJFUiA9IDY5OwogICAgcHJpdmF0ZSBpbnQgZGVmYXVsdFNmaXhlZDMyXyA9IDQ5OwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBkZWZhdWx0X3NmaXhlZDMyID0gNjkgW2RlZmF1bHQgPSA0OV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0U2ZpeGVkMzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0U2ZpeGVkMzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgZGVmYXVsdF9zZml4ZWQzMiA9IDY5IFtkZWZhdWx0ID0gNDldOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRTZml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREZWZhdWx0U2ZpeGVkMzIoKSB7CiAgICAgIHJldHVybiBkZWZhdWx0U2ZpeGVkMzJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfU0ZJWEVENjRfRklFTERfTlVNQkVSID0gNzA7CiAgICBwcml2YXRlIGxvbmcgZGVmYXVsdFNmaXhlZDY0XyA9IC01MEw7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDY0IGRlZmF1bHRfc2ZpeGVkNjQgPSA3MCBbZGVmYXVsdCA9IC01MF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0U2ZpeGVkNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0U2ZpeGVkNjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgZGVmYXVsdF9zZml4ZWQ2NCA9IDcwIFtkZWZhdWx0ID0gLTUwXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0U2ZpeGVkNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldERlZmF1bHRTZml4ZWQ2NCgpIHsKICAgICAgcmV0dXJuIGRlZmF1bHRTZml4ZWQ2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9GTE9BVF9GSUVMRF9OVU1CRVIgPSA3MTsKICAgIHByaXZhdGUgZmxvYXQgZGVmYXVsdEZsb2F0XyA9IDUxLjVGOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBkZWZhdWx0X2Zsb2F0ID0gNzEgW2RlZmF1bHQgPSA1MS41XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRGbG9hdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBkZWZhdWx0X2Zsb2F0ID0gNzEgW2RlZmF1bHQgPSA1MS41XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0RmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXREZWZhdWx0RmxvYXQoKSB7CiAgICAgIHJldHVybiBkZWZhdWx0RmxvYXRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfRE9VQkxFX0ZJRUxEX05VTUJFUiA9IDcyOwogICAgcHJpdmF0ZSBkb3VibGUgZGVmYXVsdERvdWJsZV8gPSA1MjAwMEQ7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBkZWZhdWx0X2RvdWJsZSA9IDcyIFtkZWZhdWx0ID0gNTIwMDBdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdERvdWJsZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHREb3VibGUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGRlZmF1bHRfZG91YmxlID0gNzIgW2RlZmF1bHQgPSA1MjAwMF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVmYXVsdERvdWJsZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGRvdWJsZSBnZXREZWZhdWx0RG91YmxlKCkgewogICAgICByZXR1cm4gZGVmYXVsdERvdWJsZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9CT09MX0ZJRUxEX05VTUJFUiA9IDczOwogICAgcHJpdmF0ZSBib29sZWFuIGRlZmF1bHRCb29sXyA9IHRydWU7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGVmYXVsdF9ib29sID0gNzMgW2RlZmF1bHQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRCb29sIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRGVmYXVsdEJvb2woKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZWZhdWx0X2Jvb2wgPSA3MyBbZGVmYXVsdCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRCb29sLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXREZWZhdWx0Qm9vbCgpIHsKICAgICAgcmV0dXJuIGRlZmF1bHRCb29sXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1NUUklOR19GSUVMRF9OVU1CRVIgPSA3NDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGRlZmF1bHRTdHJpbmdfID0gImhlbGxvIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nID0gNzQgW2RlZmF1bHQgPSAiaGVsbG8iXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0U3RyaW5nKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3N0cmluZyA9IDc0IFtkZWZhdWx0ID0gImhlbGxvIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVmYXVsdFN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RGVmYXVsdFN0cmluZygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBkZWZhdWx0U3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBkZWZhdWx0U3RyaW5nXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3N0cmluZyA9IDc0IFtkZWZhdWx0ID0gImhlbGxvIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGRlZmF1bHRTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXREZWZhdWx0U3RyaW5nQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZGVmYXVsdFN0cmluZ187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGRlZmF1bHRTdHJpbmdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9CWVRFU19GSUVMRF9OVU1CRVIgPSA3NTsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRlZmF1bHRCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmJ5dGVzRGVmYXVsdFZhbHVlKCJ3b3JsZCIpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBkZWZhdWx0X2J5dGVzID0gNzUgW2RlZmF1bHQgPSAid29ybGQiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRCeXRlcygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBkZWZhdWx0X2J5dGVzID0gNzUgW2RlZmF1bHQgPSAid29ybGQiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0Qnl0ZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RGVmYXVsdEJ5dGVzKCkgewogICAgICByZXR1cm4gZGVmYXVsdEJ5dGVzXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX05FU1RFRF9FTlVNX0ZJRUxEX05VTUJFUiA9IDgxOwogICAgcHJpdmF0ZSBpbnQgZGVmYXVsdE5lc3RlZEVudW1fID0gMjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGRlZmF1bHRfbmVzdGVkX2VudW0gPSA4MSBbZGVmYXVsdCA9IEJBUl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0TmVzdGVkRW51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzRGVmYXVsdE5lc3RlZEVudW0oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGRlZmF1bHRfbmVzdGVkX2VudW0gPSA4MSBbZGVmYXVsdCA9IEJBUl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVmYXVsdE5lc3RlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZ2V0RGVmYXVsdE5lc3RlZEVudW0oKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5mb3JOdW1iZXIoZGVmYXVsdE5lc3RlZEVudW1fKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVIgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9GT1JFSUdOX0VOVU1fRklFTERfTlVNQkVSID0gODI7CiAgICBwcml2YXRlIGludCBkZWZhdWx0Rm9yZWlnbkVudW1fID0gNTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIGRlZmF1bHRfZm9yZWlnbl9lbnVtID0gODIgW2RlZmF1bHQgPSBGT1JFSUdOX0JBUl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0Rm9yZWlnbkVudW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRGb3JlaWduRW51bSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gZGVmYXVsdF9mb3JlaWduX2VudW0gPSA4MiBbZGVmYXVsdCA9IEZPUkVJR05fQkFSXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0Rm9yZWlnbkVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0RGVmYXVsdEZvcmVpZ25FbnVtKCkgewogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uZm9yTnVtYmVyKGRlZmF1bHRGb3JlaWduRW51bV8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLkZPUkVJR05fQkFSIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfSU1QT1JUX0VOVU1fRklFTERfTlVNQkVSID0gODM7CiAgICBwcml2YXRlIGludCBkZWZhdWx0SW1wb3J0RW51bV8gPSA4OwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW0gZGVmYXVsdF9pbXBvcnRfZW51bSA9IDgzIFtkZWZhdWx0ID0gSU1QT1JUX0JBUl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0SW1wb3J0RW51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzRGVmYXVsdEltcG9ydEVudW0oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtIGRlZmF1bHRfaW1wb3J0X2VudW0gPSA4MyBbZGVmYXVsdCA9IElNUE9SVF9CQVJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRJbXBvcnRFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bSBnZXREZWZhdWx0SW1wb3J0RW51bSgpIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0uZm9yTnVtYmVyKGRlZmF1bHRJbXBvcnRFbnVtXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtLklNUE9SVF9CQVIgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9TVFJJTkdfUElFQ0VfRklFTERfTlVNQkVSID0gODQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBkZWZhdWx0U3RyaW5nUGllY2VfID0gImFiYyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3N0cmluZ19waWVjZSA9IDg0IFtkZWZhdWx0ID0gImFiYyIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRTdHJpbmdQaWVjZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRTdHJpbmdQaWVjZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfcGllY2UgPSA4NCBbZGVmYXVsdCA9ICJhYmMiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGVmYXVsdFN0cmluZ1BpZWNlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXREZWZhdWx0U3RyaW5nUGllY2UoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZGVmYXVsdFN0cmluZ1BpZWNlXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBkZWZhdWx0U3RyaW5nUGllY2VfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nX3BpZWNlID0gODQgW2RlZmF1bHQgPSAiYWJjIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBkZWZhdWx0U3RyaW5nUGllY2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXREZWZhdWx0U3RyaW5nUGllY2VCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBkZWZhdWx0U3RyaW5nUGllY2VfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBkZWZhdWx0U3RyaW5nUGllY2VfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9DT1JEX0ZJRUxEX05VTUJFUiA9IDg1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgZGVmYXVsdENvcmRfID0gIjEyMyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X2NvcmQgPSA4NSBbZGVmYXVsdCA9ICIxMjMiLCBjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdENvcmQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0Q29yZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9jb3JkID0gODUgW2RlZmF1bHQgPSAiMTIzIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0Q29yZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RGVmYXVsdENvcmQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZGVmYXVsdENvcmRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGRlZmF1bHRDb3JkXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X2NvcmQgPSA4NSBbZGVmYXVsdCA9ICIxMjMiLCBjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBkZWZhdWx0Q29yZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldERlZmF1bHRDb3JkQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZGVmYXVsdENvcmRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBkZWZhdWx0Q29yZF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9VSU5UMzJfRklFTERfTlVNQkVSID0gMTExOwogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZVaW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlVpbnQzMigpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTE7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZVaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T25lb2ZVaW50MzIoKSB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTExKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FT0ZfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTEyOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZk5lc3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZk5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9uZW9mTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXzsKICAgICAgfQogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9TVFJJTkdfRklFTERfTlVNQkVSID0gMTEzOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gMTEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlN0cmluZygpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZTdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9uZW9mU3RyaW5nKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSAmJiAob25lb2ZGaWVsZENhc2VfID09IDExMykpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPbmVvZlN0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEzKSB7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IGI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9CWVRFU19GSUVMRF9OVU1CRVIgPSAxMTQ7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mQnl0ZXMoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDExNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZkJ5dGVzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9uZW9mQnl0ZXMoKSB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0KSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FT0ZfQ09SRF9GSUVMRF9OVU1CRVIgPSAxMTU7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9jb3JkID0gMTE1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZDb3JkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZDb3JkKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExNTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX2NvcmQgPSAxMTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZDb3JkLgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPbmVvZkNvcmQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE1KSB7CiAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpICYmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE1KSkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2ZfY29yZCA9IDExNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb25lb2ZDb3JkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T25lb2ZDb3JkQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE1KSB7CiAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTUpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX1NUUklOR19QSUVDRV9GSUVMRF9OVU1CRVIgPSAxMTY7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmdfcGllY2UgPSAxMTYgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mU3RyaW5nUGllY2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlN0cmluZ1BpZWNlKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExNjsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZ19waWVjZSA9IDExNiBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9uZW9mU3RyaW5nUGllY2UoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE2KSB7CiAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpICYmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE2KSkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nX3BpZWNlID0gMTE2IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9uZW9mU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPbmVvZlN0cmluZ1BpZWNlQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE2KSB7CiAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTYpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX0xBWllfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTE3OwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbGF6eV9uZXN0ZWRfbWVzc2FnZSA9IDExNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZMYXp5TmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mTGF6eU5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTE3OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbGF6eV9uZXN0ZWRfbWVzc2FnZSA9IDExNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mTGF6eU5lc3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9uZW9mTGF6eU5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE3KSB7CiAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9sYXp5X25lc3RlZF9tZXNzYWdlID0gMTE3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPbmVvZkxhenlOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNykgewogICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgb3B0aW9uYWxJbnQzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDIsIG9wdGlvbmFsSW50NjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoMywgb3B0aW9uYWxVaW50MzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50NjQoNCwgb3B0aW9uYWxVaW50NjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzIoNSwgb3B0aW9uYWxTaW50MzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50NjQoNiwgb3B0aW9uYWxTaW50NjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDMyKDcsIG9wdGlvbmFsRml4ZWQzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjQoOCwgb3B0aW9uYWxGaXhlZDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzIoOSwgb3B0aW9uYWxTZml4ZWQzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0KDEwLCBvcHRpb25hbFNmaXhlZDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMTEsIG9wdGlvbmFsRmxvYXRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVEb3VibGUoMTIsIG9wdGlvbmFsRG91YmxlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgxMywgb3B0aW9uYWxCb29sXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxNCwgb3B0aW9uYWxTdHJpbmdfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcygxNSwgb3B0aW9uYWxCeXRlc18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUdyb3VwKDE2LCBnZXRPcHRpb25hbEdyb3VwKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTgsIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDE5LCBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMjAsIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDIxLCBvcHRpb25hbE5lc3RlZEVudW1fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDIyLCBvcHRpb25hbEZvcmVpZ25FbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgyMywgb3B0aW9uYWxJbXBvcnRFbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyNCwgb3B0aW9uYWxTdHJpbmdQaWVjZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjUsIG9wdGlvbmFsQ29yZF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMjYsIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDI3LCBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMjgsIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigzMSwgcmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMzIsIHJlcGVhdGVkSW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKDMzLCByZXBlYXRlZFVpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCgzNCwgcmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyKDM1LCByZXBlYXRlZFNpbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQ2NCgzNiwgcmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzIoMzcsIHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRml4ZWQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0KDM4LCByZXBlYXRlZEZpeGVkNjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTZml4ZWQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQzMigzOSwgcmVwZWF0ZWRTZml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ZpeGVkNjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkNjQoNDAsIHJlcGVhdGVkU2ZpeGVkNjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdCg0MSwgcmVwZWF0ZWRGbG9hdF8uZ2V0RmxvYXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWREb3VibGVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKDQyLCByZXBlYXRlZERvdWJsZV8uZ2V0RG91YmxlKGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQm9vbF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDQzLCByZXBlYXRlZEJvb2xfLmdldEJvb2xlYW4oaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA0NCwgcmVwZWF0ZWRTdHJpbmdfLmdldFJhdyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEJ5dGVzXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDQ1LCByZXBlYXRlZEJ5dGVzXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRHcm91cF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVHcm91cCg0NiwgcmVwZWF0ZWRHcm91cF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDQ4LCByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNDksIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg1MCwgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWROZXN0ZWRFbnVtXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oNTEsIHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRm9yZWlnbkVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSg1MiwgcmVwZWF0ZWRGb3JlaWduRW51bV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW1wb3J0RW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDUzLCByZXBlYXRlZEltcG9ydEVudW1fLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZ1BpZWNlXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNTQsIHJlcGVhdGVkU3RyaW5nUGllY2VfLmdldFJhdyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZENvcmRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA1NSwgcmVwZWF0ZWRDb3JkXy5nZXRSYXcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDU3LCByZXBlYXRlZExhenlNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDYxLCBkZWZhdWx0SW50MzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCg2MiwgZGVmYXVsdEludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKDYzLCBkZWZhdWx0VWludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDY0KDY0LCBkZWZhdWx0VWludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyKDY1LCBkZWZhdWx0U2ludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0KDY2LCBkZWZhdWx0U2ludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMig2NywgZGVmYXVsdEZpeGVkMzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0KDY4LCBkZWZhdWx0Rml4ZWQ2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyKDY5LCBkZWZhdWx0U2ZpeGVkMzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQ2NCg3MCwgZGVmYXVsdFNmaXhlZDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoNzEsIGRlZmF1bHRGbG9hdF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSg3MiwgZGVmYXVsdERvdWJsZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUJvb2woNzMsIGRlZmF1bHRCb29sXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA3NCwgZGVmYXVsdFN0cmluZ18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDc1LCBkZWZhdWx0Qnl0ZXNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDgxLCBkZWZhdWx0TmVzdGVkRW51bV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oODIsIGRlZmF1bHRGb3JlaWduRW51bV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oODMsIGRlZmF1bHRJbXBvcnRFbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA4NCwgZGVmYXVsdFN0cmluZ1BpZWNlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA4NSwgZGVmYXVsdENvcmRfKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigKICAgICAgICAgICAgMTExLCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfKSk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDExMiwgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMTEzLCBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTQpIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcygKICAgICAgICAgICAgMTE0LCAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTUpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDExNSwgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE2KSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMTYsIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTE3LCAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIG9wdGlvbmFsSW50MzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplKDIsIG9wdGlvbmFsSW50NjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSgzLCBvcHRpb25hbFVpbnQzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplKDQsIG9wdGlvbmFsVWludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQzMlNpemUoNSwgb3B0aW9uYWxTaW50MzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlU0ludDY0U2l6ZSg2LCBvcHRpb25hbFNpbnQ2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGaXhlZDMyU2l6ZSg3LCBvcHRpb25hbEZpeGVkMzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRml4ZWQ2NFNpemUoOCwgb3B0aW9uYWxGaXhlZDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDMyU2l6ZSg5LCBvcHRpb25hbFNmaXhlZDMyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNGaXhlZDY0U2l6ZSgxMCwgb3B0aW9uYWxTZml4ZWQ2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGbG9hdFNpemUoMTEsIG9wdGlvbmFsRmxvYXRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRG91YmxlU2l6ZSgxMiwgb3B0aW9uYWxEb3VibGVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQm9vbFNpemUoMTMsIG9wdGlvbmFsQm9vbF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMTQsIG9wdGlvbmFsU3RyaW5nXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgxNSwgb3B0aW9uYWxCeXRlc18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVHcm91cFNpemUoMTYsIGdldE9wdGlvbmFsR3JvdXAoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE4LCBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDE5LCBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyMCwgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSgyMSwgb3B0aW9uYWxOZXN0ZWRFbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDIyLCBvcHRpb25hbEZvcmVpZ25FbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDIzLCBvcHRpb25hbEltcG9ydEVudW1fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDI0LCBvcHRpb25hbFN0cmluZ1BpZWNlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyNSwgb3B0aW9uYWxDb3JkXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDI2LCBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDI3LCBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyOCwgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKHJlcGVhdGVkSW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZU5vVGFnKHJlcGVhdGVkSW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkSW50NjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRVaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKHJlcGVhdGVkVWludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkVWludDMyTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZU5vVGFnKHJlcGVhdGVkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkU2ludDMyTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2ludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZFNpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFJlcGVhdGVkU2ZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDEgKiBnZXRSZXBlYXRlZEJvb2xMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRCb29sTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZ18uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEJ5dGVzXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZU5vVGFnKHJlcGVhdGVkQnl0ZXNfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRCeXRlc0xpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEdyb3VwXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVHcm91cFNpemUoNDYsIHJlcGVhdGVkR3JvdXBfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQ4LCByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0OSwgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNTAsIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTmVzdGVkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHJlcGVhdGVkTmVzdGVkRW51bV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRm9yZWlnbkVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZEZvcmVpZ25FbnVtXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIHJlcGVhdGVkRm9yZWlnbkVudW1fLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW1wb3J0RW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHJlcGVhdGVkSW1wb3J0RW51bV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiByZXBlYXRlZEltcG9ydEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nUGllY2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nUGllY2VfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZENvcmRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkQ29yZF8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZENvcmRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNTcsIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg2MSwgZGVmYXVsdEludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSg2MiwgZGVmYXVsdEludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoNjMsIGRlZmF1bHRVaW50MzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDY0U2l6ZSg2NCwgZGVmYXVsdFVpbnQ2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTSW50MzJTaXplKDY1LCBkZWZhdWx0U2ludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemUoNjYsIGRlZmF1bHRTaW50NjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRml4ZWQzMlNpemUoNjcsIGRlZmF1bHRGaXhlZDMyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkNjRTaXplKDY4LCBkZWZhdWx0Rml4ZWQ2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTRml4ZWQzMlNpemUoNjksIGRlZmF1bHRTZml4ZWQzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVTRml4ZWQ2NFNpemUoNzAsIGRlZmF1bHRTZml4ZWQ2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGbG9hdFNpemUoNzEsIGRlZmF1bHRGbG9hdF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVEb3VibGVTaXplKDcyLCBkZWZhdWx0RG91YmxlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJvb2xTaXplKDczLCBkZWZhdWx0Qm9vbF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoNzQsIGRlZmF1bHRTdHJpbmdfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplKDc1LCBkZWZhdWx0Qnl0ZXNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoODEsIGRlZmF1bHROZXN0ZWRFbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDgyLCBkZWZhdWx0Rm9yZWlnbkVudW1fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoODMsIGRlZmF1bHRJbXBvcnRFbnVtXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSg4NCwgZGVmYXVsdFN0cmluZ1BpZWNlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSg4NSwgZGVmYXVsdENvcmRfKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKAogICAgICAgICAgICAgIDExMSwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSBvbmVvZkZpZWxkXykpOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDExMiwgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMTEzLCBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTQpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplKAogICAgICAgICAgICAgIDExNCwgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE1KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxMTUsIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNikgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMTE2LCBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTcpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTE3LCAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcykgb2JqOwoKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50NjQoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50NjQoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDY0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVaW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQzMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxVaW50NjQoKSAhPSBvdGhlci5oYXNPcHRpb25hbFVpbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQ2NCgpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsVWludDY0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxVaW50NjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFNpbnQzMigpICE9IG90aGVyLmhhc09wdGlvbmFsU2ludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsU2ludDMyKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxTaW50MzIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFNpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsU2ludDY0KCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxTaW50NjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxTaW50NjQoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbFNpbnQ2NCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsU2ludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxGaXhlZDMyKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxGaXhlZDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsRml4ZWQzMigpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsRml4ZWQzMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsRml4ZWQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsRml4ZWQ2NCgpICE9IG90aGVyLmhhc09wdGlvbmFsRml4ZWQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEZpeGVkNjQoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEZpeGVkNjQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEZpeGVkNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFNmaXhlZDMyKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxTZml4ZWQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFNmaXhlZDMyKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxTZml4ZWQzMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsU2ZpeGVkMzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFNmaXhlZDY0KCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxTZml4ZWQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFNmaXhlZDY0KCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsU2ZpeGVkNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEZsb2F0KCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxGbG9hdCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEZsb2F0KCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKGdldE9wdGlvbmFsRmxvYXQoKSkKICAgICAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICAgICAgb3RoZXIuZ2V0T3B0aW9uYWxGbG9hdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbERvdWJsZSgpICE9IG90aGVyLmhhc09wdGlvbmFsRG91YmxlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsRG91YmxlKCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldE9wdGlvbmFsRG91YmxlKCkpCiAgICAgICAgICAgICE9IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cygKICAgICAgICAgICAgICAgIG90aGVyLmdldE9wdGlvbmFsRG91YmxlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsQm9vbCgpICE9IG90aGVyLmhhc09wdGlvbmFsQm9vbCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEJvb2woKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEJvb2woKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEJvb2woKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFN0cmluZygpICE9IG90aGVyLmhhc09wdGlvbmFsU3RyaW5nKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsU3RyaW5nKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsU3RyaW5nKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbFN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEJ5dGVzKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxCeXRlcygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEJ5dGVzKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsQnl0ZXMoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsQnl0ZXMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxHcm91cCgpICE9IG90aGVyLmhhc09wdGlvbmFsR3JvdXAoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxHcm91cCgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbEdyb3VwKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEdyb3VwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRFbnVtKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxOZXN0ZWRFbnVtKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkRW51bSgpKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkRW51bV8gIT0gb3RoZXIub3B0aW9uYWxOZXN0ZWRFbnVtXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEZvcmVpZ25FbnVtKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxGb3JlaWduRW51bSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEZvcmVpZ25FbnVtKCkpIHsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduRW51bV8gIT0gb3RoZXIub3B0aW9uYWxGb3JlaWduRW51bV8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbXBvcnRFbnVtKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbXBvcnRFbnVtKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW1wb3J0RW51bSgpKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsSW1wb3J0RW51bV8gIT0gb3RoZXIub3B0aW9uYWxJbXBvcnRFbnVtXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFN0cmluZ1BpZWNlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxTdHJpbmdQaWVjZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFN0cmluZ1BpZWNlKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsU3RyaW5nUGllY2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsU3RyaW5nUGllY2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxDb3JkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxDb3JkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsQ29yZCgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbENvcmQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsQ29yZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSAhPSBvdGhlci5oYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSAhPSBvdGhlci5oYXNPcHRpb25hbExhenlNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkSW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFNpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTZml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTZml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEZsb2F0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRmxvYXRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRCb29sTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQm9vbExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZ0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQnl0ZXNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRHcm91cExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEdyb3VwTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghcmVwZWF0ZWROZXN0ZWRFbnVtXy5lcXVhbHMob3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFyZXBlYXRlZEZvcmVpZ25FbnVtXy5lcXVhbHMob3RoZXIucmVwZWF0ZWRGb3JlaWduRW51bV8pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghcmVwZWF0ZWRJbXBvcnRFbnVtXy5lcXVhbHMob3RoZXIucmVwZWF0ZWRJbXBvcnRFbnVtXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nUGllY2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQ29yZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZExhenlNZXNzYWdlTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkTGF6eU1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEZWZhdWx0SW50MzIoKSAhPSBvdGhlci5oYXNEZWZhdWx0SW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRGVmYXVsdEludDMyKCkpIHsKICAgICAgICBpZiAoZ2V0RGVmYXVsdEludDMyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RGVmYXVsdEludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdEludDY0KCkgIT0gb3RoZXIuaGFzRGVmYXVsdEludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RlZmF1bHRJbnQ2NCgpKSB7CiAgICAgICAgaWYgKGdldERlZmF1bHRJbnQ2NCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldERlZmF1bHRJbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRVaW50MzIoKSAhPSBvdGhlci5oYXNEZWZhdWx0VWludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RlZmF1bHRVaW50MzIoKSkgewogICAgICAgIGlmIChnZXREZWZhdWx0VWludDMyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RGVmYXVsdFVpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRVaW50NjQoKSAhPSBvdGhlci5oYXNEZWZhdWx0VWludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RlZmF1bHRVaW50NjQoKSkgewogICAgICAgIGlmIChnZXREZWZhdWx0VWludDY0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RGVmYXVsdFVpbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRTaW50MzIoKSAhPSBvdGhlci5oYXNEZWZhdWx0U2ludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RlZmF1bHRTaW50MzIoKSkgewogICAgICAgIGlmIChnZXREZWZhdWx0U2ludDMyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RGVmYXVsdFNpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRTaW50NjQoKSAhPSBvdGhlci5oYXNEZWZhdWx0U2ludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RlZmF1bHRTaW50NjQoKSkgewogICAgICAgIGlmIChnZXREZWZhdWx0U2ludDY0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RGVmYXVsdFNpbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRGaXhlZDMyKCkgIT0gb3RoZXIuaGFzRGVmYXVsdEZpeGVkMzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRGVmYXVsdEZpeGVkMzIoKSkgewogICAgICAgIGlmIChnZXREZWZhdWx0Rml4ZWQzMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldERlZmF1bHRGaXhlZDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdEZpeGVkNjQoKSAhPSBvdGhlci5oYXNEZWZhdWx0Rml4ZWQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEZWZhdWx0Rml4ZWQ2NCgpKSB7CiAgICAgICAgaWYgKGdldERlZmF1bHRGaXhlZDY0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RGVmYXVsdEZpeGVkNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEZWZhdWx0U2ZpeGVkMzIoKSAhPSBvdGhlci5oYXNEZWZhdWx0U2ZpeGVkMzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRGVmYXVsdFNmaXhlZDMyKCkpIHsKICAgICAgICBpZiAoZ2V0RGVmYXVsdFNmaXhlZDMyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RGVmYXVsdFNmaXhlZDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdFNmaXhlZDY0KCkgIT0gb3RoZXIuaGFzRGVmYXVsdFNmaXhlZDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RlZmF1bHRTZml4ZWQ2NCgpKSB7CiAgICAgICAgaWYgKGdldERlZmF1bHRTZml4ZWQ2NCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldERlZmF1bHRTZml4ZWQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRGbG9hdCgpICE9IG90aGVyLmhhc0RlZmF1bHRGbG9hdCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEZWZhdWx0RmxvYXQoKSkgewogICAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0RGVmYXVsdEZsb2F0KCkpCiAgICAgICAgICAgICE9IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgICAgIG90aGVyLmdldERlZmF1bHRGbG9hdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEZWZhdWx0RG91YmxlKCkgIT0gb3RoZXIuaGFzRGVmYXVsdERvdWJsZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEZWZhdWx0RG91YmxlKCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldERlZmF1bHREb3VibGUoKSkKICAgICAgICAgICAgIT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKAogICAgICAgICAgICAgICAgb3RoZXIuZ2V0RGVmYXVsdERvdWJsZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEZWZhdWx0Qm9vbCgpICE9IG90aGVyLmhhc0RlZmF1bHRCb29sKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RlZmF1bHRCb29sKCkpIHsKICAgICAgICBpZiAoZ2V0RGVmYXVsdEJvb2woKQogICAgICAgICAgICAhPSBvdGhlci5nZXREZWZhdWx0Qm9vbCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRTdHJpbmcoKSAhPSBvdGhlci5oYXNEZWZhdWx0U3RyaW5nKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RlZmF1bHRTdHJpbmcoKSkgewogICAgICAgIGlmICghZ2V0RGVmYXVsdFN0cmluZygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RGVmYXVsdFN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEZWZhdWx0Qnl0ZXMoKSAhPSBvdGhlci5oYXNEZWZhdWx0Qnl0ZXMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRGVmYXVsdEJ5dGVzKCkpIHsKICAgICAgICBpZiAoIWdldERlZmF1bHRCeXRlcygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RGVmYXVsdEJ5dGVzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHROZXN0ZWRFbnVtKCkgIT0gb3RoZXIuaGFzRGVmYXVsdE5lc3RlZEVudW0oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRGVmYXVsdE5lc3RlZEVudW0oKSkgewogICAgICAgIGlmIChkZWZhdWx0TmVzdGVkRW51bV8gIT0gb3RoZXIuZGVmYXVsdE5lc3RlZEVudW1fKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRGb3JlaWduRW51bSgpICE9IG90aGVyLmhhc0RlZmF1bHRGb3JlaWduRW51bSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEZWZhdWx0Rm9yZWlnbkVudW0oKSkgewogICAgICAgIGlmIChkZWZhdWx0Rm9yZWlnbkVudW1fICE9IG90aGVyLmRlZmF1bHRGb3JlaWduRW51bV8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdEltcG9ydEVudW0oKSAhPSBvdGhlci5oYXNEZWZhdWx0SW1wb3J0RW51bSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEZWZhdWx0SW1wb3J0RW51bSgpKSB7CiAgICAgICAgaWYgKGRlZmF1bHRJbXBvcnRFbnVtXyAhPSBvdGhlci5kZWZhdWx0SW1wb3J0RW51bV8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdFN0cmluZ1BpZWNlKCkgIT0gb3RoZXIuaGFzRGVmYXVsdFN0cmluZ1BpZWNlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RlZmF1bHRTdHJpbmdQaWVjZSgpKSB7CiAgICAgICAgaWYgKCFnZXREZWZhdWx0U3RyaW5nUGllY2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldERlZmF1bHRTdHJpbmdQaWVjZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEZWZhdWx0Q29yZCgpICE9IG90aGVyLmhhc0RlZmF1bHRDb3JkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RlZmF1bHRDb3JkKCkpIHsKICAgICAgICBpZiAoIWdldERlZmF1bHRDb3JkKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXREZWZhdWx0Q29yZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0T25lb2ZGaWVsZENhc2UoKS5lcXVhbHMob3RoZXIuZ2V0T25lb2ZGaWVsZENhc2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgc3dpdGNoIChvbmVvZkZpZWxkQ2FzZV8pIHsKICAgICAgICBjYXNlIDExMToKICAgICAgICAgIGlmIChnZXRPbmVvZlVpbnQzMigpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T25lb2ZVaW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMTI6CiAgICAgICAgICBpZiAoIWdldE9uZW9mTmVzdGVkTWVzc2FnZSgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPbmVvZk5lc3RlZE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTEzOgogICAgICAgICAgaWYgKCFnZXRPbmVvZlN0cmluZygpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPbmVvZlN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMTQ6CiAgICAgICAgICBpZiAoIWdldE9uZW9mQnl0ZXMoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T25lb2ZCeXRlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMTU6CiAgICAgICAgICBpZiAoIWdldE9uZW9mQ29yZCgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPbmVvZkNvcmQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTE2OgogICAgICAgICAgaWYgKCFnZXRPbmVvZlN0cmluZ1BpZWNlKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9uZW9mU3RyaW5nUGllY2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTE3OgogICAgICAgICAgaWYgKCFnZXRPbmVvZkxhenlOZXN0ZWRNZXNzYWdlKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9uZW9mTGF6eU5lc3RlZE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEludDMyKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50NjQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXRPcHRpb25hbEludDY0KCkpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFVpbnQzMigpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQ2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXRPcHRpb25hbFVpbnQ2NCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxTaW50MzIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxTaW50MzIoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxTaW50NjQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0T3B0aW9uYWxTaW50NjQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsRml4ZWQzMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRklYRUQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxGaXhlZDMyKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsRml4ZWQ2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0T3B0aW9uYWxGaXhlZDY0KCkpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFNmaXhlZDMyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TRklYRUQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxTZml4ZWQzMigpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFNmaXhlZDY0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxGbG9hdCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgZ2V0T3B0aW9uYWxGbG9hdCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxEb3VibGUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldE9wdGlvbmFsRG91YmxlKCkpKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxCb29sKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9CT09MX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKAogICAgICAgICAgICBnZXRPcHRpb25hbEJvb2woKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsU3RyaW5nKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsU3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxCeXRlcygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfQllURVNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEdyb3VwKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTEdST1VQX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEdyb3VwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRk9SRUlHTl9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRFbnVtKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgb3B0aW9uYWxOZXN0ZWRFbnVtXzsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduRW51bSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRk9SRUlHTl9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBvcHRpb25hbEZvcmVpZ25FbnVtXzsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbXBvcnRFbnVtKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTVBPUlRfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgb3B0aW9uYWxJbXBvcnRFbnVtXzsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxTdHJpbmdQaWVjZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU1RSSU5HX1BJRUNFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFN0cmluZ1BpZWNlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxDb3JkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9DT1JEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbENvcmQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1BVQkxJQ19JTVBPUlRfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxMYXp5TWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1VOVkVSSUZJRURfTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkSW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkSW50NjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkVWludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9VSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkVWludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkVWludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9VSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkVWludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2ludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2ludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU2ludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRml4ZWQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRklYRUQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2ZpeGVkMzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NGSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2ZpeGVkNjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NGSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFNmaXhlZDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRmxvYXRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZMT0FUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRG91YmxlQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ET1VCTEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRG91YmxlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQm9vbENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQk9PTF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRCb29sTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQnl0ZXNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0JZVEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEJ5dGVzTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkR3JvdXBDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVER1JPVVBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkR3JvdXBMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZPUkVJR05fTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0lNUE9SVF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWROZXN0ZWRFbnVtQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ORVNURURfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcmVwZWF0ZWROZXN0ZWRFbnVtXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZvcmVpZ25FbnVtQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GT1JFSUdOX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkRm9yZWlnbkVudW1fLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkSW1wb3J0RW51bUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU1QT1JUX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkSW1wb3J0RW51bV8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HX1BJRUNFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQ29yZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQ09SRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0xBWllfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNEZWZhdWx0SW50MzIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFRkFVTFRfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldERlZmF1bHRJbnQzMigpOwogICAgICB9CiAgICAgIGlmIChoYXNEZWZhdWx0SW50NjQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFRkFVTFRfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldERlZmF1bHRJbnQ2NCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdFVpbnQzMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgREVGQVVMVF9VSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldERlZmF1bHRVaW50MzIoKTsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdFVpbnQ2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgREVGQVVMVF9VSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldERlZmF1bHRVaW50NjQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRTaW50MzIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFRkFVTFRfU0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREZWZhdWx0U2ludDMyKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRTaW50NjQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFRkFVTFRfU0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXREZWZhdWx0U2ludDY0KCkpOwogICAgICB9CiAgICAgIGlmIChoYXNEZWZhdWx0Rml4ZWQzMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgREVGQVVMVF9GSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREZWZhdWx0Rml4ZWQzMigpOwogICAgICB9CiAgICAgIGlmIChoYXNEZWZhdWx0Rml4ZWQ2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgREVGQVVMVF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXREZWZhdWx0Rml4ZWQ2NCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdFNmaXhlZDMyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBERUZBVUxUX1NGSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREZWZhdWx0U2ZpeGVkMzIoKTsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdFNmaXhlZDY0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBERUZBVUxUX1NGSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXREZWZhdWx0U2ZpeGVkNjQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRGbG9hdCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgREVGQVVMVF9GTE9BVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICBnZXREZWZhdWx0RmxvYXQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHREb3VibGUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFRkFVTFRfRE9VQkxFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0RGVmYXVsdERvdWJsZSgpKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRCb29sKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBERUZBVUxUX0JPT0xfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldERlZmF1bHRCb29sKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNEZWZhdWx0U3RyaW5nKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBERUZBVUxUX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RGVmYXVsdFN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0RlZmF1bHRCeXRlcygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgREVGQVVMVF9CWVRFU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RGVmYXVsdEJ5dGVzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdE5lc3RlZEVudW0oKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFRkFVTFRfTkVTVEVEX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGRlZmF1bHROZXN0ZWRFbnVtXzsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdEZvcmVpZ25FbnVtKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBERUZBVUxUX0ZPUkVJR05fRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZGVmYXVsdEZvcmVpZ25FbnVtXzsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdEltcG9ydEVudW0oKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFRkFVTFRfSU1QT1JUX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGRlZmF1bHRJbXBvcnRFbnVtXzsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdFN0cmluZ1BpZWNlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBERUZBVUxUX1NUUklOR19QSUVDRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RGVmYXVsdFN0cmluZ1BpZWNlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRGVmYXVsdENvcmQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFRkFVTFRfQ09SRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RGVmYXVsdENvcmQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIHN3aXRjaCAob25lb2ZGaWVsZENhc2VfKSB7CiAgICAgICAgY2FzZSAxMTE6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPTkVPRl9VSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZVaW50MzIoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTEyOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTEzOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mU3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTE0OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfQllURVNfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZCeXRlcygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDExNToKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9ORU9GX0NPUkRfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZDb3JkKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTE2OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfU1RSSU5HX1BJRUNFX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mU3RyaW5nUGllY2UoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMTc6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPTkVPRl9MQVpZX05FU1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mTGF6eU5lc3RlZE1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoaXMgcHJvdG8gaW5jbHVkZXMgZXZlcnkgdHlwZSBvZiBmaWVsZCBpbiBib3RoIHNpbmd1bGFyIGFuZCByZXBlYXRlZAogICAgICogZm9ybXMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRPcHRpb25hbEdyb3VwRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRHcm91cEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGJpdEZpZWxkMV8gPSAwOwogICAgICAgIGJpdEZpZWxkMl8gPSAwOwogICAgICAgIG9wdGlvbmFsSW50MzJfID0gMDsKICAgICAgICBvcHRpb25hbEludDY0XyA9IDBMOwogICAgICAgIG9wdGlvbmFsVWludDMyXyA9IDA7CiAgICAgICAgb3B0aW9uYWxVaW50NjRfID0gMEw7CiAgICAgICAgb3B0aW9uYWxTaW50MzJfID0gMDsKICAgICAgICBvcHRpb25hbFNpbnQ2NF8gPSAwTDsKICAgICAgICBvcHRpb25hbEZpeGVkMzJfID0gMDsKICAgICAgICBvcHRpb25hbEZpeGVkNjRfID0gMEw7CiAgICAgICAgb3B0aW9uYWxTZml4ZWQzMl8gPSAwOwogICAgICAgIG9wdGlvbmFsU2ZpeGVkNjRfID0gMEw7CiAgICAgICAgb3B0aW9uYWxGbG9hdF8gPSAwRjsKICAgICAgICBvcHRpb25hbERvdWJsZV8gPSAwRDsKICAgICAgICBvcHRpb25hbEJvb2xfID0gZmFsc2U7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgICAgb3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgICAgb3B0aW9uYWxHcm91cF8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEdyb3VwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxHcm91cEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gMTsKICAgICAgICBvcHRpb25hbEZvcmVpZ25FbnVtXyA9IDQ7CiAgICAgICAgb3B0aW9uYWxJbXBvcnRFbnVtXyA9IDc7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSAiIjsKICAgICAgICBvcHRpb25hbENvcmRfID0gIiI7CiAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIHJlcGVhdGVkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIHJlcGVhdGVkQnl0ZXNfID0gZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEdyb3VwXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRHcm91cF8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDgwMDApOwogICAgICAgIHJlcGVhdGVkSW1wb3J0RW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMTAwMDApOwogICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIHJlcGVhdGVkQ29yZF8gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICBkZWZhdWx0SW50MzJfID0gNDE7CiAgICAgICAgZGVmYXVsdEludDY0XyA9IDQyTDsKICAgICAgICBkZWZhdWx0VWludDMyXyA9IDQzOwogICAgICAgIGRlZmF1bHRVaW50NjRfID0gNDRMOwogICAgICAgIGRlZmF1bHRTaW50MzJfID0gLTQ1OwogICAgICAgIGRlZmF1bHRTaW50NjRfID0gNDZMOwogICAgICAgIGRlZmF1bHRGaXhlZDMyXyA9IDQ3OwogICAgICAgIGRlZmF1bHRGaXhlZDY0XyA9IDQ4TDsKICAgICAgICBkZWZhdWx0U2ZpeGVkMzJfID0gNDk7CiAgICAgICAgZGVmYXVsdFNmaXhlZDY0XyA9IC01MEw7CiAgICAgICAgZGVmYXVsdEZsb2F0XyA9IDUxLjVGOwogICAgICAgIGRlZmF1bHREb3VibGVfID0gNTIwMDBEOwogICAgICAgIGRlZmF1bHRCb29sXyA9IHRydWU7CiAgICAgICAgZGVmYXVsdFN0cmluZ18gPSAiaGVsbG8iOwogICAgICAgIGRlZmF1bHRCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmJ5dGVzRGVmYXVsdFZhbHVlKCJ3b3JsZCIpOwogICAgICAgIGRlZmF1bHROZXN0ZWRFbnVtXyA9IDI7CiAgICAgICAgZGVmYXVsdEZvcmVpZ25FbnVtXyA9IDU7CiAgICAgICAgZGVmYXVsdEltcG9ydEVudW1fID0gODsKICAgICAgICBkZWZhdWx0U3RyaW5nUGllY2VfID0gImFiYyI7CiAgICAgICAgZGVmYXVsdENvcmRfID0gIjEyMyI7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvbmVvZkxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb25lb2ZMYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyh0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgaWYgKGJpdEZpZWxkMV8gIT0gMCkgeyBidWlsZFBhcnRpYWwxKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQyXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDIocmVzdWx0KTsgfQogICAgICAgIGJ1aWxkUGFydGlhbE9uZW9mcyhyZXN1bHQpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRHcm91cF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEdyb3VwXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEdyb3VwXyA9IHJlcGVhdGVkR3JvdXBfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRHcm91cF8gPSByZXBlYXRlZEdyb3VwQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDEwMDApOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEltcG9ydE1lc3NhZ2VfKTsKICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDIwMDApOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSByZXBlYXRlZEltcG9ydE1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkRW51bV8pOwogICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDQwMDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQucmVwZWF0ZWROZXN0ZWRFbnVtXyA9IHJlcGVhdGVkTmVzdGVkRW51bV87CiAgICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkRm9yZWlnbkVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkRm9yZWlnbkVudW1fID0gcmVwZWF0ZWRGb3JlaWduRW51bV87CiAgICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRJbXBvcnRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5yZXBlYXRlZEltcG9ydEVudW1fID0gcmVwZWF0ZWRJbXBvcnRFbnVtXzsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTGF6eU1lc3NhZ2VfKTsKICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwODAwMDApOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkTGF6eU1lc3NhZ2VfID0gcmVwZWF0ZWRMYXp5TWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZExhenlNZXNzYWdlXyA9IHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMl8gPSBvcHRpb25hbEludDMyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDY0XyA9IG9wdGlvbmFsSW50NjRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVWludDMyXyA9IG9wdGlvbmFsVWludDMyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQ2NF8gPSBvcHRpb25hbFVpbnQ2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTaW50MzJfID0gb3B0aW9uYWxTaW50MzJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsU2ludDY0XyA9IG9wdGlvbmFsU2ludDY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEZpeGVkMzJfID0gb3B0aW9uYWxGaXhlZDMyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEZpeGVkNjRfID0gb3B0aW9uYWxGaXhlZDY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFNmaXhlZDMyXyA9IG9wdGlvbmFsU2ZpeGVkMzJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsU2ZpeGVkNjRfID0gb3B0aW9uYWxTZml4ZWQ2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxGbG9hdF8gPSBvcHRpb25hbEZsb2F0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbERvdWJsZV8gPSBvcHRpb25hbERvdWJsZV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxCb29sXyA9IG9wdGlvbmFsQm9vbF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTdHJpbmdfID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsQnl0ZXNfID0gb3B0aW9uYWxCeXRlc187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxHcm91cF8gPSBvcHRpb25hbEdyb3VwQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxHcm91cF8KICAgICAgICAgICAgICA6IG9wdGlvbmFsR3JvdXBCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEltcG9ydE1lc3NhZ2VfID0gb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxJbXBvcnRNZXNzYWdlXwogICAgICAgICAgICAgIDogb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbE5lc3RlZEVudW1fID0gb3B0aW9uYWxOZXN0ZWRFbnVtXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEZvcmVpZ25FbnVtXyA9IG9wdGlvbmFsRm9yZWlnbkVudW1fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW1wb3J0RW51bV8gPSBvcHRpb25hbEltcG9ydEVudW1fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsU3RyaW5nUGllY2VfID0gb3B0aW9uYWxTdHJpbmdQaWVjZV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxDb3JkXyA9IG9wdGlvbmFsQ29yZF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxMYXp5TWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyA9IG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbnQzMl8gPSByZXBlYXRlZEludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEludDY0XyA9IHJlcGVhdGVkSW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFVpbnQzMl8gPSByZXBlYXRlZFVpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkVWludDY0XyA9IHJlcGVhdGVkVWludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTaW50MzJfID0gcmVwZWF0ZWRTaW50MzJfOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDFfID0gYml0RmllbGQxXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFNpbnQ2NF8gPSByZXBlYXRlZFNpbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZpeGVkMzJfID0gcmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRml4ZWQ2NF8gPSByZXBlYXRlZEZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2ZpeGVkMzJfID0gcmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTZml4ZWQ2NF8gPSByZXBlYXRlZFNmaXhlZDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZsb2F0XyA9IHJlcGVhdGVkRmxvYXRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZERvdWJsZV8gPSByZXBlYXRlZERvdWJsZV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEJvb2xfID0gcmVwZWF0ZWRCb29sXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmdfID0gcmVwZWF0ZWRTdHJpbmdfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRCeXRlc18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQnl0ZXNfID0gcmVwZWF0ZWRCeXRlc187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmdQaWVjZV8gPSByZXBlYXRlZFN0cmluZ1BpZWNlXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQ29yZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQ29yZF8gPSByZXBlYXRlZENvcmRfOwogICAgICAgIH0KICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kZWZhdWx0SW50MzJfID0gZGVmYXVsdEludDMyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kZWZhdWx0SW50NjRfID0gZGVmYXVsdEludDY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kZWZhdWx0VWludDMyXyA9IGRlZmF1bHRVaW50MzJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRlZmF1bHRVaW50NjRfID0gZGVmYXVsdFVpbnQ2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZGVmYXVsdFNpbnQzMl8gPSBkZWZhdWx0U2ludDMyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMV8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZGVmYXVsdFNpbnQ2NF8gPSBkZWZhdWx0U2ludDY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kZWZhdWx0Rml4ZWQzMl8gPSBkZWZhdWx0Rml4ZWQzMl87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZGVmYXVsdEZpeGVkNjRfID0gZGVmYXVsdEZpeGVkNjRfOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRlZmF1bHRTZml4ZWQzMl8gPSBkZWZhdWx0U2ZpeGVkMzJfOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRlZmF1bHRTZml4ZWQ2NF8gPSBkZWZhdWx0U2ZpeGVkNjRfOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRlZmF1bHRGbG9hdF8gPSBkZWZhdWx0RmxvYXRfOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRlZmF1bHREb3VibGVfID0gZGVmYXVsdERvdWJsZV87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMV8gfD0gdG9fYml0RmllbGQxXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQyXyA9IGJpdEZpZWxkMl87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMV8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZGVmYXVsdEJvb2xfID0gZGVmYXVsdEJvb2xfOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRlZmF1bHRTdHJpbmdfID0gZGVmYXVsdFN0cmluZ187CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZGVmYXVsdEJ5dGVzXyA9IGRlZmF1bHRCeXRlc187CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQyXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZGVmYXVsdE5lc3RlZEVudW1fID0gZGVmYXVsdE5lc3RlZEVudW1fOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRlZmF1bHRGb3JlaWduRW51bV8gPSBkZWZhdWx0Rm9yZWlnbkVudW1fOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMl8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRlZmF1bHRJbXBvcnRFbnVtXyA9IGRlZmF1bHRJbXBvcnRFbnVtXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMV8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kZWZhdWx0U3RyaW5nUGllY2VfID0gZGVmYXVsdFN0cmluZ1BpZWNlXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMV8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDJfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kZWZhdWx0Q29yZF8gPSBkZWZhdWx0Q29yZF87CiAgICAgICAgICB0b19iaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDFfIHw9IHRvX2JpdEZpZWxkMV87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxPbmVvZnMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRDYXNlXyA9IG9uZW9mRmllbGRDYXNlXzsKICAgICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSB0aGlzLm9uZW9mRmllbGRfOwogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyICYmCiAgICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE3ICYmCiAgICAgICAgICAgIG9uZW9mTGF6eU5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSBvbmVvZkxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzIob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50NjQoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQ2NChvdGhlci5nZXRPcHRpb25hbEludDY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxVaW50MzIoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxVaW50MzIob3RoZXIuZ2V0T3B0aW9uYWxVaW50MzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFVpbnQ2NCgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFVpbnQ2NChvdGhlci5nZXRPcHRpb25hbFVpbnQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsU2ludDMyKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsU2ludDMyKG90aGVyLmdldE9wdGlvbmFsU2ludDMyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxTaW50NjQoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxTaW50NjQob3RoZXIuZ2V0T3B0aW9uYWxTaW50NjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEZpeGVkMzIoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxGaXhlZDMyKG90aGVyLmdldE9wdGlvbmFsRml4ZWQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsRml4ZWQ2NCgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEZpeGVkNjQob3RoZXIuZ2V0T3B0aW9uYWxGaXhlZDY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxTZml4ZWQzMigpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFNmaXhlZDMyKG90aGVyLmdldE9wdGlvbmFsU2ZpeGVkMzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFNmaXhlZDY0KCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsU2ZpeGVkNjQob3RoZXIuZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsRmxvYXQoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxGbG9hdChvdGhlci5nZXRPcHRpb25hbEZsb2F0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxEb3VibGUoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxEb3VibGUob3RoZXIuZ2V0T3B0aW9uYWxEb3VibGUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEJvb2woKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxCb29sKG90aGVyLmdldE9wdGlvbmFsQm9vbCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsU3RyaW5nKCkpIHsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IG90aGVyLm9wdGlvbmFsU3RyaW5nXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxCeXRlcygpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEJ5dGVzKG90aGVyLmdldE9wdGlvbmFsQnl0ZXMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEdyb3VwKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxHcm91cChvdGhlci5nZXRPcHRpb25hbEdyb3VwKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbEZvcmVpZ25NZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbEltcG9ydE1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxOZXN0ZWRFbnVtKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsTmVzdGVkRW51bShvdGhlci5nZXRPcHRpb25hbE5lc3RlZEVudW0oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEZvcmVpZ25FbnVtKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsRm9yZWlnbkVudW0ob3RoZXIuZ2V0T3B0aW9uYWxGb3JlaWduRW51bSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW1wb3J0RW51bSgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEltcG9ydEVudW0ob3RoZXIuZ2V0T3B0aW9uYWxJbXBvcnRFbnVtKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxTdHJpbmdQaWVjZSgpKSB7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IG90aGVyLm9wdGlvbmFsU3RyaW5nUGllY2VfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbENvcmQoKSkgewogICAgICAgICAgb3B0aW9uYWxDb3JkXyA9IG90aGVyLm9wdGlvbmFsQ29yZF87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZShvdGhlci5nZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbExhenlNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxMYXp5TWVzc2FnZShvdGhlci5nZXRPcHRpb25hbExhenlNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZShvdGhlci5nZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBvdGhlci5yZXBlYXRlZEludDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZEludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBvdGhlci5yZXBlYXRlZEludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFVpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRVaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBvdGhlci5yZXBlYXRlZFVpbnQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRVaW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkVWludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFVpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDY0XyA9IG90aGVyLnJlcGVhdGVkVWludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFVpbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2ludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gb3RoZXIucmVwZWF0ZWRTaW50MzJfOwogICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2ludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8gPSBvdGhlci5yZXBlYXRlZFNpbnQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IG90aGVyLnJlcGVhdGVkRml4ZWQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGaXhlZDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBvdGhlci5yZXBlYXRlZEZpeGVkNjRfOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTZml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTZml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gb3RoZXIucmVwZWF0ZWRTZml4ZWQzMl87CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZml4ZWQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTZml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfID0gb3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZml4ZWQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfID0gb3RoZXIucmVwZWF0ZWRGbG9hdF87CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGbG9hdF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWREb3VibGVfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRG91YmxlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gb3RoZXIucmVwZWF0ZWREb3VibGVfOwogICAgICAgICAgICByZXBlYXRlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRG91YmxlXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkQm9vbF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8gPSBvdGhlci5yZXBlYXRlZEJvb2xfOwogICAgICAgICAgICByZXBlYXRlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkQm9vbF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTdHJpbmdfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU3RyaW5nXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmdfID0gb3RoZXIucmVwZWF0ZWRTdHJpbmdfOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZ18uYWRkQWxsKG90aGVyLnJlcGVhdGVkU3RyaW5nXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEJ5dGVzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEJ5dGVzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRCeXRlc18gPSBvdGhlci5yZXBlYXRlZEJ5dGVzXzsKICAgICAgICAgICAgcmVwZWF0ZWRCeXRlc18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJ5dGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkQnl0ZXNfLmFkZEFsbChvdGhlci5yZXBlYXRlZEJ5dGVzXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkR3JvdXBfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRHcm91cF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRHcm91cF8gPSBvdGhlci5yZXBlYXRlZEdyb3VwXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkR3JvdXBfLmFkZEFsbChvdGhlci5yZXBlYXRlZEdyb3VwXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRHcm91cF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZEdyb3VwQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkR3JvdXBfID0gb3RoZXIucmVwZWF0ZWRHcm91cF87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA0MDApOwogICAgICAgICAgICAgIHJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZEdyb3VwRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZEdyb3VwXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkTmVzdGVkTWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA4MDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZE5lc3RlZE1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwODAwKTsKICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIucmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmFkZEFsbChvdGhlci5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRGb3JlaWduTWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDEwMDApOwogICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkSW1wb3J0TWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDIwMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW1wb3J0TWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZEltcG9ydE1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIucmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBvdGhlci5yZXBlYXRlZE5lc3RlZEVudW1fOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGRBbGwob3RoZXIucmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZvcmVpZ25FbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25FbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8gPSBvdGhlci5yZXBlYXRlZEZvcmVpZ25FbnVtXzsKICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDgwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGb3JlaWduRW51bV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbXBvcnRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEltcG9ydEVudW1fLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEltcG9ydEVudW1fID0gb3RoZXIucmVwZWF0ZWRJbXBvcnRFbnVtXzsKICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMTAwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0RW51bV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW1wb3J0RW51bV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTdHJpbmdQaWVjZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmdQaWVjZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfID0gb3RoZXIucmVwZWF0ZWRTdHJpbmdQaWVjZV87CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU3RyaW5nUGllY2VfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQ29yZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRDb3JkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRDb3JkXyA9IG90aGVyLnJlcGVhdGVkQ29yZF87CiAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQ29yZElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZENvcmRfLmFkZEFsbChvdGhlci5yZXBlYXRlZENvcmRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRMYXp5TWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkTGF6eU1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkTGF6eU1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZExhenlNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZExhenlNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkTGF6eU1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRGVmYXVsdEludDMyKCkpIHsKICAgICAgICAgIHNldERlZmF1bHRJbnQzMihvdGhlci5nZXREZWZhdWx0SW50MzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEZWZhdWx0SW50NjQoKSkgewogICAgICAgICAgc2V0RGVmYXVsdEludDY0KG90aGVyLmdldERlZmF1bHRJbnQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0RlZmF1bHRVaW50MzIoKSkgewogICAgICAgICAgc2V0RGVmYXVsdFVpbnQzMihvdGhlci5nZXREZWZhdWx0VWludDMyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRGVmYXVsdFVpbnQ2NCgpKSB7CiAgICAgICAgICBzZXREZWZhdWx0VWludDY0KG90aGVyLmdldERlZmF1bHRVaW50NjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEZWZhdWx0U2ludDMyKCkpIHsKICAgICAgICAgIHNldERlZmF1bHRTaW50MzIob3RoZXIuZ2V0RGVmYXVsdFNpbnQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0RlZmF1bHRTaW50NjQoKSkgewogICAgICAgICAgc2V0RGVmYXVsdFNpbnQ2NChvdGhlci5nZXREZWZhdWx0U2ludDY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRGVmYXVsdEZpeGVkMzIoKSkgewogICAgICAgICAgc2V0RGVmYXVsdEZpeGVkMzIob3RoZXIuZ2V0RGVmYXVsdEZpeGVkMzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEZWZhdWx0Rml4ZWQ2NCgpKSB7CiAgICAgICAgICBzZXREZWZhdWx0Rml4ZWQ2NChvdGhlci5nZXREZWZhdWx0Rml4ZWQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0RlZmF1bHRTZml4ZWQzMigpKSB7CiAgICAgICAgICBzZXREZWZhdWx0U2ZpeGVkMzIob3RoZXIuZ2V0RGVmYXVsdFNmaXhlZDMyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRGVmYXVsdFNmaXhlZDY0KCkpIHsKICAgICAgICAgIHNldERlZmF1bHRTZml4ZWQ2NChvdGhlci5nZXREZWZhdWx0U2ZpeGVkNjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEZWZhdWx0RmxvYXQoKSkgewogICAgICAgICAgc2V0RGVmYXVsdEZsb2F0KG90aGVyLmdldERlZmF1bHRGbG9hdCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0RlZmF1bHREb3VibGUoKSkgewogICAgICAgICAgc2V0RGVmYXVsdERvdWJsZShvdGhlci5nZXREZWZhdWx0RG91YmxlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRGVmYXVsdEJvb2woKSkgewogICAgICAgICAgc2V0RGVmYXVsdEJvb2wob3RoZXIuZ2V0RGVmYXVsdEJvb2woKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEZWZhdWx0U3RyaW5nKCkpIHsKICAgICAgICAgIGRlZmF1bHRTdHJpbmdfID0gb3RoZXIuZGVmYXVsdFN0cmluZ187CiAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0RlZmF1bHRCeXRlcygpKSB7CiAgICAgICAgICBzZXREZWZhdWx0Qnl0ZXMob3RoZXIuZ2V0RGVmYXVsdEJ5dGVzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRGVmYXVsdE5lc3RlZEVudW0oKSkgewogICAgICAgICAgc2V0RGVmYXVsdE5lc3RlZEVudW0ob3RoZXIuZ2V0RGVmYXVsdE5lc3RlZEVudW0oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEZWZhdWx0Rm9yZWlnbkVudW0oKSkgewogICAgICAgICAgc2V0RGVmYXVsdEZvcmVpZ25FbnVtKG90aGVyLmdldERlZmF1bHRGb3JlaWduRW51bSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0RlZmF1bHRJbXBvcnRFbnVtKCkpIHsKICAgICAgICAgIHNldERlZmF1bHRJbXBvcnRFbnVtKG90aGVyLmdldERlZmF1bHRJbXBvcnRFbnVtKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRGVmYXVsdFN0cmluZ1BpZWNlKCkpIHsKICAgICAgICAgIGRlZmF1bHRTdHJpbmdQaWVjZV8gPSBvdGhlci5kZWZhdWx0U3RyaW5nUGllY2VfOwogICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEZWZhdWx0Q29yZCgpKSB7CiAgICAgICAgICBkZWZhdWx0Q29yZF8gPSBvdGhlci5kZWZhdWx0Q29yZF87CiAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgc3dpdGNoIChvdGhlci5nZXRPbmVvZkZpZWxkQ2FzZSgpKSB7CiAgICAgICAgICBjYXNlIE9ORU9GX1VJTlQzMjogewogICAgICAgICAgICBzZXRPbmVvZlVpbnQzMihvdGhlci5nZXRPbmVvZlVpbnQzMigpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GX05FU1RFRF9NRVNTQUdFOiB7CiAgICAgICAgICAgIG1lcmdlT25lb2ZOZXN0ZWRNZXNzYWdlKG90aGVyLmdldE9uZW9mTmVzdGVkTWVzc2FnZSgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GX1NUUklORzogewogICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTM7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gb3RoZXIub25lb2ZGaWVsZF87CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgT05FT0ZfQllURVM6IHsKICAgICAgICAgICAgc2V0T25lb2ZCeXRlcyhvdGhlci5nZXRPbmVvZkJ5dGVzKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgT05FT0ZfQ09SRDogewogICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTU7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gb3RoZXIub25lb2ZGaWVsZF87CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgT05FT0ZfU1RSSU5HX1BJRUNFOiB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExNjsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBvdGhlci5vbmVvZkZpZWxkXzsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBPTkVPRl9MQVpZX05FU1RFRF9NRVNTQUdFOiB7CiAgICAgICAgICAgIG1lcmdlT25lb2ZMYXp5TmVzdGVkTWVzc2FnZShvdGhlci5nZXRPbmVvZkxhenlOZXN0ZWRNZXNzYWdlKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgT05FT0ZGSUVMRF9OT1RfU0VUOiB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50NjRfID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFVpbnQzMl8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQKICAgICAgICAgICAgICBjYXNlIDMyOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFVpbnQ2NF8gPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIKICAgICAgICAgICAgICBjYXNlIDQwOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFNpbnQzMl8gPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAKICAgICAgICAgICAgICBjYXNlIDQ4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFNpbnQ2NF8gPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDgKICAgICAgICAgICAgICBjYXNlIDYxOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEZpeGVkMzJfID0gaW5wdXQucmVhZEZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2MQogICAgICAgICAgICAgIGNhc2UgNjU6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsRml4ZWQ2NF8gPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY1CiAgICAgICAgICAgICAgY2FzZSA3NzogewogICAgICAgICAgICAgICAgb3B0aW9uYWxTZml4ZWQzMl8gPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NwogICAgICAgICAgICAgIGNhc2UgODE6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsU2ZpeGVkNjRfID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODEKICAgICAgICAgICAgICBjYXNlIDkzOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEZsb2F0XyA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkzCiAgICAgICAgICAgICAgY2FzZSA5NzogewogICAgICAgICAgICAgICAgb3B0aW9uYWxEb3VibGVfID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk3CiAgICAgICAgICAgICAgY2FzZSAxMDQ6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsQm9vbF8gPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNAogICAgICAgICAgICAgIGNhc2UgMTE0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTQKICAgICAgICAgICAgICBjYXNlIDEyMjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxCeXRlc18gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjIKICAgICAgICAgICAgICBjYXNlIDEzMTogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZEdyb3VwKDE2LAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsR3JvdXBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzMQogICAgICAgICAgICAgIGNhc2UgMTQ2OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0NgogICAgICAgICAgICAgIGNhc2UgMTU0OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNTQKICAgICAgICAgICAgICBjYXNlIDE2MjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjIKICAgICAgICAgICAgICBjYXNlIDE2ODogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMjEsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTY4CiAgICAgICAgICAgICAgY2FzZSAxNzY6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDIyLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgb3B0aW9uYWxGb3JlaWduRW51bV8gPSB0bXBSYXc7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzYKICAgICAgICAgICAgICBjYXNlIDE4NDogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgyMywgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIG9wdGlvbmFsSW1wb3J0RW51bV8gPSB0bXBSYXc7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxODQKICAgICAgICAgICAgICBjYXNlIDE5NDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOTQKICAgICAgICAgICAgICBjYXNlIDIwMjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxDb3JkXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIwMgogICAgICAgICAgICAgIGNhc2UgMjEwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxMAogICAgICAgICAgICAgIGNhc2UgMjE4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMTgKICAgICAgICAgICAgICBjYXNlIDIyNjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIyNgogICAgICAgICAgICAgIGNhc2UgMjQ4OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0OAogICAgICAgICAgICAgIGNhc2UgMjUwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTAKICAgICAgICAgICAgICBjYXNlIDI1NjogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1NgogICAgICAgICAgICAgIGNhc2UgMjU4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjU4CiAgICAgICAgICAgICAgY2FzZSAyNjQ6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkVWludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjY0CiAgICAgICAgICAgICAgY2FzZSAyNjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEludChpbnB1dC5yZWFkVUludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2NgogICAgICAgICAgICAgIGNhc2UgMjcyOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjcyCiAgICAgICAgICAgICAgY2FzZSAyNzQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNzQKICAgICAgICAgICAgICBjYXNlIDI4MDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODAKICAgICAgICAgICAgICBjYXNlIDI4MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQzMl8uYWRkSW50KGlucHV0LnJlYWRTSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjgyCiAgICAgICAgICAgICAgY2FzZSAyODg6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRTSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyODgKICAgICAgICAgICAgICBjYXNlIDI5MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNpbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5MAogICAgICAgICAgICAgIGNhc2UgMzAxOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMwMQogICAgICAgICAgICAgIGNhc2UgMjk4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KGlucHV0LnJlYWRGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5OAogICAgICAgICAgICAgIGNhc2UgMzA1OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzA1CiAgICAgICAgICAgICAgY2FzZSAzMDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRMb25nKGlucHV0LnJlYWRGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMwNgogICAgICAgICAgICAgIGNhc2UgMzE3OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRTRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMxNwogICAgICAgICAgICAgIGNhc2UgMzE0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5hZGRJbnQoaW5wdXQucmVhZFNGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMxNAogICAgICAgICAgICAgIGNhc2UgMzIxOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIxCiAgICAgICAgICAgICAgY2FzZSAzMjI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDY0SXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLmFkZExvbmcoaW5wdXQucmVhZFNGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyMgogICAgICAgICAgICAgIGNhc2UgMzMzOiB7CiAgICAgICAgICAgICAgICBmbG9hdCB2ID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMzMKICAgICAgICAgICAgICBjYXNlIDMzMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkRmxvYXQoaW5wdXQucmVhZEZsb2F0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzMAogICAgICAgICAgICAgIGNhc2UgMzM3OiB7CiAgICAgICAgICAgICAgICBkb3VibGUgdiA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkRG91YmxlKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzNwogICAgICAgICAgICAgIGNhc2UgMzM4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWREb3VibGVfLmFkZERvdWJsZShpbnB1dC5yZWFkRG91YmxlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMzOAogICAgICAgICAgICAgIGNhc2UgMzQ0OiB7CiAgICAgICAgICAgICAgICBib29sZWFuIHYgPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEJvb2xfLmFkZEJvb2xlYW4odik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQ0CiAgICAgICAgICAgICAgY2FzZSAzNDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoYWxsb2MgLyAxKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRCb29sXy5hZGRCb29sZWFuKGlucHV0LnJlYWRCb29sKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0NgogICAgICAgICAgICAgIGNhc2UgMzU0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZ18uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNTQKICAgICAgICAgICAgICBjYXNlIDM2MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHYgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkQnl0ZXNfLmFkZCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNjIKICAgICAgICAgICAgICBjYXNlIDM3MTogewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkR3JvdXAoNDYsCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEdyb3VwXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEdyb3VwQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNzEKICAgICAgICAgICAgICBjYXNlIDM4NjogewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzg2CiAgICAgICAgICAgICAgY2FzZSAzOTQ6IHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzOTQKICAgICAgICAgICAgICBjYXNlIDQwMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MDIKICAgICAgICAgICAgICBjYXNlIDQwODogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoNTEsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MDgKICAgICAgICAgICAgICBjYXNlIDQxMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg1MSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZEVudW1Jc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDEwCiAgICAgICAgICAgICAgY2FzZSA0MTY6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDUyLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MTYKICAgICAgICAgICAgICBjYXNlIDQxODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg1MiwgdG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25FbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MTgKICAgICAgICAgICAgICBjYXNlIDQyNDogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg1MywgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0RW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEltcG9ydEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyNAogICAgICAgICAgICAgIGNhc2UgNDI2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoNTMsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbXBvcnRFbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyNgogICAgICAgICAgICAgIGNhc2UgNDM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDM0CiAgICAgICAgICAgICAgY2FzZSA0NDI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRDb3JkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZENvcmRfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDQyCiAgICAgICAgICAgICAgY2FzZSA0NTg6IHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0NTgKICAgICAgICAgICAgICBjYXNlIDQ4ODogewogICAgICAgICAgICAgICAgZGVmYXVsdEludDMyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ4OAogICAgICAgICAgICAgIGNhc2UgNDk2OiB7CiAgICAgICAgICAgICAgICBkZWZhdWx0SW50NjRfID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDk2CiAgICAgICAgICAgICAgY2FzZSA1MDQ6IHsKICAgICAgICAgICAgICAgIGRlZmF1bHRVaW50MzJfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwNDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwNAogICAgICAgICAgICAgIGNhc2UgNTEyOiB7CiAgICAgICAgICAgICAgICBkZWZhdWx0VWludDY0XyA9IGlucHV0LnJlYWRVSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MTIKICAgICAgICAgICAgICBjYXNlIDUyMDogewogICAgICAgICAgICAgICAgZGVmYXVsdFNpbnQzMl8gPSBpbnB1dC5yZWFkU0ludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTIwCiAgICAgICAgICAgICAgY2FzZSA1Mjg6IHsKICAgICAgICAgICAgICAgIGRlZmF1bHRTaW50NjRfID0gaW5wdXQucmVhZFNJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUyOAogICAgICAgICAgICAgIGNhc2UgNTQxOiB7CiAgICAgICAgICAgICAgICBkZWZhdWx0Rml4ZWQzMl8gPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU0MQogICAgICAgICAgICAgIGNhc2UgNTQ1OiB7CiAgICAgICAgICAgICAgICBkZWZhdWx0Rml4ZWQ2NF8gPSBpbnB1dC5yZWFkRml4ZWQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDA4MDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU0NQogICAgICAgICAgICAgIGNhc2UgNTU3OiB7CiAgICAgICAgICAgICAgICBkZWZhdWx0U2ZpeGVkMzJfID0gaW5wdXQucmVhZFNGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTU3CiAgICAgICAgICAgICAgY2FzZSA1NjE6IHsKICAgICAgICAgICAgICAgIGRlZmF1bHRTZml4ZWQ2NF8gPSBpbnB1dC5yZWFkU0ZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NjEKICAgICAgICAgICAgICBjYXNlIDU3MzogewogICAgICAgICAgICAgICAgZGVmYXVsdEZsb2F0XyA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQxXyB8PSAweDQwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU3MwogICAgICAgICAgICAgIGNhc2UgNTc3OiB7CiAgICAgICAgICAgICAgICBkZWZhdWx0RG91YmxlXyA9IGlucHV0LnJlYWREb3VibGUoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHg4MDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NzcKICAgICAgICAgICAgICBjYXNlIDU4NDogewogICAgICAgICAgICAgICAgZGVmYXVsdEJvb2xfID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1ODQKICAgICAgICAgICAgICBjYXNlIDU5NDogewogICAgICAgICAgICAgICAgZGVmYXVsdFN0cmluZ18gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1OTQKICAgICAgICAgICAgICBjYXNlIDYwMjogewogICAgICAgICAgICAgICAgZGVmYXVsdEJ5dGVzXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYwMgogICAgICAgICAgICAgIGNhc2UgNjQ4OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg4MSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGRlZmF1bHROZXN0ZWRFbnVtXyA9IHRtcFJhdzsKICAgICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY0OAogICAgICAgICAgICAgIGNhc2UgNjU2OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg4MiwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGRlZmF1bHRGb3JlaWduRW51bV8gPSB0bXBSYXc7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NTYKICAgICAgICAgICAgICBjYXNlIDY2NDogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg4MywgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGRlZmF1bHRJbXBvcnRFbnVtXyA9IHRtcFJhdzsKICAgICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY2NAogICAgICAgICAgICAgIGNhc2UgNjc0OiB7CiAgICAgICAgICAgICAgICBkZWZhdWx0U3RyaW5nUGllY2VfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjc0CiAgICAgICAgICAgICAgY2FzZSA2ODI6IHsKICAgICAgICAgICAgICAgIGRlZmF1bHRDb3JkXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY4MgogICAgICAgICAgICAgIGNhc2UgODg4OiB7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4ODgKICAgICAgICAgICAgICBjYXNlIDg5ODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4OTgKICAgICAgICAgICAgICBjYXNlIDkwNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTM7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGJzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkwNgogICAgICAgICAgICAgIGNhc2UgOTE0OiB7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTE0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkxNAogICAgICAgICAgICAgIGNhc2UgOTIyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExNTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRfID0gYnM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTIyCiAgICAgICAgICAgICAgY2FzZSA5MzA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTE2OwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBiczsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MzAKICAgICAgICAgICAgICBjYXNlIDkzODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T25lb2ZMYXp5TmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTM4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9uZW9mRmllbGRfOwogICAgICBwdWJsaWMgT25lb2ZGaWVsZENhc2UKICAgICAgICAgIGdldE9uZW9mRmllbGRDYXNlKCkgewogICAgICAgIHJldHVybiBPbmVvZkZpZWxkQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZGaWVsZCgpIHsKICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQxXzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQyXzsKCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFNpbmd1bGFyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogU2luZ3VsYXIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMigpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFNpbmd1bGFyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogU2luZ3VsYXIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb3B0aW9uYWxJbnQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxJbnQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQ2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0ID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb3B0aW9uYWxJbnQ2NF8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzIgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMiA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMigpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxVaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxVaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFVpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxVaW50MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9wdGlvbmFsVWludDMyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFVpbnQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IG9wdGlvbmFsX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50NjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDY0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbFVpbnQ2NCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxVaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgb3B0aW9uYWxfdWludDY0ID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxVaW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFVpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsVWludDY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IG9wdGlvbmFsX3VpbnQ2NCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsVWludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvcHRpb25hbFVpbnQ2NF8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTaW50MzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBvcHRpb25hbF9zaW50MzIgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2ludDMyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIG9wdGlvbmFsX3NpbnQzMiA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNpbnQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFNpbnQzMigpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxTaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFNpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxTaW50MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgb3B0aW9uYWxfc2ludDMyID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTaW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9wdGlvbmFsU2ludDMyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbFNpbnQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2ludDY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTaW50NjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgb3B0aW9uYWxfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2ludDY0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbFNpbnQ2NCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxTaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50NjQgb3B0aW9uYWxfc2ludDY0ID0gNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTaW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFNpbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsU2ludDY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IG9wdGlvbmFsX3NpbnQ2NCA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU2ludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvcHRpb25hbFNpbnQ2NF8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxGaXhlZDMyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEZpeGVkMzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZpeGVkMzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGaXhlZDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsRml4ZWQzMigpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxGaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBvcHRpb25hbF9maXhlZDMyID0gNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxGaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxGaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEZpeGVkMzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIG9wdGlvbmFsX2ZpeGVkMzIgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEZpeGVkMzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9wdGlvbmFsRml4ZWQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxGaXhlZDY0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEZpeGVkNjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZpeGVkNjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDY0IG9wdGlvbmFsX2ZpeGVkNjQgPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGaXhlZDY0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbEZpeGVkNjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsRml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRml4ZWQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsRml4ZWQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgb3B0aW9uYWxfZml4ZWQ2NCA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRml4ZWQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb3B0aW9uYWxGaXhlZDY0XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFNmaXhlZDMyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBvcHRpb25hbF9zZml4ZWQzMiA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2ZpeGVkMzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFNmaXhlZDMyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZml4ZWQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFNmaXhlZDMyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFNmaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgb3B0aW9uYWxfc2ZpeGVkMzIgPSA5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFNmaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTZml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxTZml4ZWQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDMyIG9wdGlvbmFsX3NmaXhlZDMyID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTZml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb3B0aW9uYWxTZml4ZWQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxTZml4ZWQ2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgb3B0aW9uYWxfc2ZpeGVkNjQgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTZml4ZWQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2ZpeGVkNjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBvcHRpb25hbF9zZml4ZWQ2NCA9IDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZml4ZWQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxTZml4ZWQ2NCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxTZml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU2ZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFNmaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxTZml4ZWQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNmaXhlZDY0IG9wdGlvbmFsX3NmaXhlZDY0ID0gMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU2ZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9wdGlvbmFsU2ZpeGVkNjRfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmxvYXQgb3B0aW9uYWxGbG9hdF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgb3B0aW9uYWxfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBvcHRpb25hbF9mbG9hdCA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGbG9hdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldE9wdGlvbmFsRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsRmxvYXRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBvcHRpb25hbF9mbG9hdCA9IDExOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEZsb2F0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEZsb2F0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgb3B0aW9uYWxfZmxvYXQgPSAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxGbG9hdCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb3B0aW9uYWxGbG9hdF8gPSAwRjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBkb3VibGUgb3B0aW9uYWxEb3VibGVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBvcHRpb25hbF9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxEb3VibGUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbERvdWJsZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBvcHRpb25hbF9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRG91YmxlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldE9wdGlvbmFsRG91YmxlKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbERvdWJsZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBvcHRpb25hbF9kb3VibGUgPSAxMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxEb3VibGUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbERvdWJsZShkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxEb3VibGVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgb3B0aW9uYWxfZG91YmxlID0gMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRG91YmxlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwODAwKTsKICAgICAgICBvcHRpb25hbERvdWJsZV8gPSAwRDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBib29sZWFuIG9wdGlvbmFsQm9vbF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBvcHRpb25hbF9ib29sID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQm9vbCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQm9vbCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCb29sLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRPcHRpb25hbEJvb2woKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsQm9vbF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbCA9IDEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEJvb2wgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEJvb2woYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEJvb2xfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2wgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxCb29sKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvcHRpb25hbEJvb2xfID0gZmFsc2U7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFN0cmluZ18gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9wdGlvbmFsU3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSAxNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFN0cmluZygpIHsKICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbFN0cmluZygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDE0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbFN0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIG9wdGlvbmFsQnl0ZXNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQnl0ZXMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHRpb25hbF9ieXRlcyA9IDE1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlcy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEJ5dGVzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxCeXRlcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQnl0ZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbEJ5dGVzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxCeXRlcygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgb3B0aW9uYWxCeXRlc18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbEJ5dGVzKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCBvcHRpb25hbEdyb3VwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwT3JCdWlsZGVyPiBvcHRpb25hbEdyb3VwQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbGdyb3VwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsR3JvdXAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxncm91cC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwIGdldE9wdGlvbmFsR3JvdXAoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxHcm91cF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEdyb3VwXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsR3JvdXBCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsR3JvdXAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cCB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbEdyb3VwXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEdyb3VwQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDE2IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEdyb3VwKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxHcm91cF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxHcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbEdyb3VwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbEdyb3VwXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsR3JvdXBfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxHcm91cEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxHcm91cF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxHcm91cEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbEdyb3VwXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEdyb3VwKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA4MDAwKTsKICAgICAgICBvcHRpb25hbEdyb3VwXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEdyb3VwQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxHcm91cEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAuQnVpbGRlciBnZXRPcHRpb25hbEdyb3VwQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsR3JvdXBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXBPckJ1aWxkZXIgZ2V0T3B0aW9uYWxHcm91cE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxHcm91cEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEdyb3VwQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxHcm91cF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsR3JvdXBfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDE2IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5PcHRpb25hbEdyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXBPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxHcm91cEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuT3B0aW9uYWxHcm91cE9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsR3JvdXAoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsR3JvdXBCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGb3JlaWduTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZvcmVpZ25NZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGb3JlaWduTWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIGdldE9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbEZvcmVpZ25NZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ25fbWVzc2FnZSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxGb3JlaWduTWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbXBvcnRNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxJbXBvcnRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9pbXBvcnRfbWVzc2FnZSA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIG9wdGlvbmFsX2ltcG9ydF9tZXNzYWdlID0gMjA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEltcG9ydE1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9wdGlvbmFsSW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsSW1wb3J0TWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2UgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsSW1wb3J0TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbEltcG9ydE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxOZXN0ZWRFbnVtXyA9IDE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRFbnVtIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxOZXN0ZWRFbnVtKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIG9wdGlvbmFsX25lc3RlZF9lbnVtID0gMjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldE9wdGlvbmFsTmVzdGVkRW51bSgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZm9yTnVtYmVyKG9wdGlvbmFsTmVzdGVkRW51bV8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uRk9PIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gb3B0aW9uYWxfbmVzdGVkX2VudW0gPSAyMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxOZXN0ZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRFbnVtKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvcHRpb25hbE5lc3RlZEVudW1fID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBvcHRpb25hbF9uZXN0ZWRfZW51bSA9IDIxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbE5lc3RlZEVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9wdGlvbmFsTmVzdGVkRW51bV8gPSAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEZvcmVpZ25FbnVtXyA9IDQ7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRm9yZWlnbkVudW0gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZvcmVpZ25FbnVtKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2ZvcmVpZ25fZW51bSA9IDIyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxGb3JlaWduRW51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0T3B0aW9uYWxGb3JlaWduRW51bSgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uZm9yTnVtYmVyKG9wdGlvbmFsRm9yZWlnbkVudW1fKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLkZPUkVJR05fRk9PIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRm9yZWlnbkVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEZvcmVpZ25FbnVtKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvcHRpb25hbEZvcmVpZ25FbnVtXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRm9yZWlnbkVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbXBvcnRFbnVtXyA9IDc7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW0gb3B0aW9uYWxfaW1wb3J0X2VudW0gPSAyMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbXBvcnRFbnVtIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbXBvcnRFbnVtKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtIG9wdGlvbmFsX2ltcG9ydF9lbnVtID0gMjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEltcG9ydEVudW0uCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bSBnZXRPcHRpb25hbEltcG9ydEVudW0oKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0uZm9yTnVtYmVyKG9wdGlvbmFsSW1wb3J0RW51bV8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtLklNUE9SVF9GT08gOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSBvcHRpb25hbF9pbXBvcnRfZW51bSA9IDIzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEltcG9ydEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEltcG9ydEVudW0oY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvcHRpb25hbEltcG9ydEVudW1fID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSBvcHRpb25hbF9pbXBvcnRfZW51bSA9IDIzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEltcG9ydEVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9wdGlvbmFsSW1wb3J0RW51bV8gPSA3OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFN0cmluZ1BpZWNlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU3RyaW5nUGllY2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nUGllY2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZ1BpZWNlKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdQaWVjZV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX3BpZWNlID0gMjQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZ1BpZWNlLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdQaWVjZV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZ1BpZWNlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxTdHJpbmdQaWVjZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfcGllY2UgPSAyNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFN0cmluZ1BpZWNlKCkgewogICAgICAgIG9wdGlvbmFsU3RyaW5nUGllY2VfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0T3B0aW9uYWxTdHJpbmdQaWVjZSgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19waWVjZSA9IDI0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZ1BpZWNlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTdHJpbmdQaWVjZUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbFN0cmluZ1BpZWNlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsQ29yZF8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9jb3JkID0gMjUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQ29yZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbENvcmQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxDb3JkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxDb3JkKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxDb3JkXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIG9wdGlvbmFsQ29yZF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbENvcmQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRPcHRpb25hbENvcmRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsQ29yZF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIG9wdGlvbmFsQ29yZF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbENvcmQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbENvcmQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbENvcmRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfY29yZCA9IDI1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbENvcmQoKSB7CiAgICAgICAgb3B0aW9uYWxDb3JkXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldE9wdGlvbmFsQ29yZCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX2NvcmQgPSAyNSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsQ29yZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQ29yZEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbENvcmRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPT0gbnVsbCA/IGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIERlZmluZWQgaW4gdW5pdHRlc3RfaW1wb3J0X3B1YmxpYy5wcm90bwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5QdWJsaWNJbXBvcnRNZXNzYWdlIG9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZSA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gIT0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogRGVmaW5lZCBpbiB1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2Ugb3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzYWdlID0gMjY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBEZWZpbmVkIGluIHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZSBvcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0UHVibGljLlB1YmxpY0ltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnRQdWJsaWMuUHVibGljSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxQdWJsaWNJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsTGF6eU1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbExhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxMYXp5TWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbExhenlNZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxMYXp5TWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gMjcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDI3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSAyNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF91bnZlcmlmaWVkX2xhenlfbWVzc2FnZSA9IDI4IFt1bnZlcmlmaWVkX2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5X21lc3NhZ2UgPSAyOCBbdW52ZXJpZmllZF9sYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlID0gMjggW3VudmVyaWZpZWRfbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF91bnZlcmlmaWVkX2xhenlfbWVzc2FnZSA9IDI4IFt1bnZlcmlmaWVkX2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF91bnZlcmlmaWVkX2xhenlfbWVzc2FnZSA9IDI4IFt1bnZlcmlmaWVkX2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbFVudmVyaWZpZWRMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRJbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkSW50MzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBSZXBlYXRlZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRJbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDMxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBSZXBlYXRlZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEludDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBSZXBlYXRlZAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAzMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRJbnQzMigpIHsKICAgICAgICByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDA4MDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkSW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEludDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZEludDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZEludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRJbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDMyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRJbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMzI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkSW50NjQoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRVaW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFVpbnQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRVaW50MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkVWludDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRVaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkVWludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVWludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRVaW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcmVwZWF0ZWRfdWludDMyID0gMzM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFVpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkVWludDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRVaW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiByZXBlYXRlZF91aW50MzIgPSAzMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRVaW50MzIoKSB7CiAgICAgICAgcmVwZWF0ZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFVpbnQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkVWludDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFVpbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkVWludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFVpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFVpbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVWludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVWludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRVaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVWludDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAzNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkVWludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRVaW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFVpbnQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDM0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFVpbnQ2NCgpIHsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTaW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFNpbnQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTaW50MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkU2ludDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2ludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNpbnQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNpbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTaW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcmVwZWF0ZWRfc2ludDMyID0gMzU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU2ludDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTaW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiByZXBlYXRlZF9zaW50MzIgPSAzNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTaW50MzIoKSB7CiAgICAgICAgcmVwZWF0ZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTaW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNpbnQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ludDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFNpbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRTaW50NjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ludDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZFNpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTaW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFNpbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcmVwZWF0ZWRfc2ludDY0ID0gMzY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ludDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCByZXBlYXRlZF9zaW50NjQgPSAzNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2ludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTaW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFNpbnQ2NF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHJlcGVhdGVkX3NpbnQ2NCA9IDM2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNpbnQ2NCgpIHsKICAgICAgICByZXBlYXRlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRml4ZWQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDMyXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMzc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRml4ZWQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAzNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRml4ZWQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEZpeGVkMzJfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDM3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZpeGVkMzIoKSB7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRml4ZWQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDY0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkRml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGaXhlZDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaXhlZDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMzg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAzODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRml4ZWQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEZpeGVkNjRfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDM4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZpeGVkNjQoKSB7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTZml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ZpeGVkMzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRTZml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkU2ZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcmVwZWF0ZWRfc2ZpeGVkMzIgPSAzOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2ZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZFNmaXhlZDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFNmaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZml4ZWQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNmaXhlZDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2ZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2ZpeGVkMzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNmaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTZml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2ZpeGVkMzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiByZXBlYXRlZF9zZml4ZWQzMiA9IDM5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTZml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU2ZpeGVkMzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU2ZpeGVkMzJfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHJlcGVhdGVkX3NmaXhlZDMyID0gMzk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2ZpeGVkMzIoKSB7CiAgICAgICAgcmVwZWF0ZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFNmaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTZml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRTZml4ZWQ2NF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkU2ZpeGVkNjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU2ZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNmaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNmaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNmaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkU2ZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2ZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2ZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFNmaXhlZDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCByZXBlYXRlZF9zZml4ZWQ2NCA9IDQwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNmaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTZml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNmaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHJlcGVhdGVkX3NmaXhlZDY0ID0gNDA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNmaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTZml4ZWQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTZml4ZWQ2NF8pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcmVwZWF0ZWRfc2ZpeGVkNjQgPSA0MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTZml4ZWQ2NCgpIHsKICAgICAgICByZXBlYXRlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5GbG9hdExpc3QgcmVwZWF0ZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRmxvYXRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZsb2F0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZsb2F0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRmxvYXRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZsb2F0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZsb2F0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZsb2F0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZsb2F0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZsb2F0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRSZXBlYXRlZEZsb2F0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0Xy5nZXRGbG9hdChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGbG9hdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmxvYXQoCiAgICAgICAgICBpbnQgaW5kZXgsIGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRmxvYXRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZsb2F0Xy5zZXRGbG9hdChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSA0MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRGbG9hdCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmxvYXQoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfLmFkZEZsb2F0KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEZsb2F0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGbG9hdCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRmxvYXRfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gNDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRmxvYXQoKSB7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkRvdWJsZUxpc3QgcmVwZWF0ZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRG91YmxlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWREb3VibGVfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRG91YmxlXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZERvdWJsZV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZERvdWJsZV8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZERvdWJsZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0UmVwZWF0ZWREb3VibGVMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWREb3VibGUuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRG91YmxlQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRG91YmxlXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZERvdWJsZSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZG91YmxlIGdldFJlcGVhdGVkRG91YmxlKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZERvdWJsZV8uZ2V0RG91YmxlKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHJlcGVhdGVkX2RvdWJsZSA9IDQyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRG91YmxlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWREb3VibGUoCiAgICAgICAgICBpbnQgaW5kZXgsIGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRG91YmxlXy5zZXREb3VibGUoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWREb3VibGUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZERvdWJsZShkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZERvdWJsZV8uYWRkRG91YmxlKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSByZXBlYXRlZF9kb3VibGUgPSA0Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRG91YmxlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWREb3VibGUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Eb3VibGU+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRG91YmxlXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcmVwZWF0ZWRfZG91YmxlID0gNDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRG91YmxlKCkgewogICAgICAgIHJlcGVhdGVkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHJlcGVhdGVkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEJvb2xJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEJvb2xfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkQm9vbF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQm9vbF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkQm9vbF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRCb29sXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCb29sLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0UmVwZWF0ZWRCb29sTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJvb2wuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQm9vbENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEJvb2xfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGdldFJlcGVhdGVkQm9vbChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sXy5nZXRCb29sZWFuKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRCb29sIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRCb29sKAogICAgICAgICAgaW50IGluZGV4LCBib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQm9vbF8uc2V0Qm9vbGVhbihpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sID0gNDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQm9vbCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQm9vbChib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQm9vbF8uYWRkQm9vbGVhbih2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2wgPSA0Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkQm9vbCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkQm9vbCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkJvb2xlYW4+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEJvb2xfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbCA9IDQzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEJvb2woKSB7CiAgICAgICAgcmVwZWF0ZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFN0cmluZ18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAxMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0xpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ18uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFN0cmluZygKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ18uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nID0gNDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZ18pOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZyA9IDQ0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFN0cmluZygpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMTAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcgPSA0NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ18uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiByZXBlYXRlZEJ5dGVzXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQnl0ZXNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEJ5dGVzXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEJ5dGVzXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDIwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQnl0ZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRCeXRlc0xpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRCeXRlc18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEJ5dGVzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMgPSA0NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQnl0ZXNDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlc18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQnl0ZXMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXBlYXRlZEJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEJ5dGVzXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQnl0ZXMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEJ5dGVzKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXNJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJ5dGVzXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzID0gNDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQnl0ZXMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEJ5dGVzKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQnl0ZXNfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRCeXRlcyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkQnl0ZXMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlc0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEJ5dGVzXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlcyA9IDQ1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEJ5dGVzKCkgewogICAgICAgIHJlcGVhdGVkQnl0ZXNfID0gZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXA+IHJlcGVhdGVkR3JvdXBfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cD4ocmVwZWF0ZWRHcm91cF8pOwogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwNDAwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwT3JCdWlsZGVyPiByZXBlYXRlZEdyb3VwQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDQ2IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cD4gZ2V0UmVwZWF0ZWRHcm91cExpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRHcm91cF8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gNDYgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRHcm91cENvdW50KCkgewogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkR3JvdXBfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDQ2IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCBnZXRSZXBlYXRlZEdyb3VwKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkR3JvdXBfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEdyb3VwQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gNDYgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkR3JvdXAoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRHcm91cF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRHcm91cCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRHcm91cF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRHcm91cChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkR3JvdXBJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDQ2IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEdyb3VwKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkR3JvdXBJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gNDYgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkR3JvdXAoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEdyb3VwXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRHcm91cCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRHcm91cF8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRHcm91cCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cD4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEdyb3VwXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gNDYgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRHcm91cCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDA0MDApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDQ2IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZEdyb3VwKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRHcm91cF8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEdyb3VwQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAuQnVpbGRlciBnZXRSZXBlYXRlZEdyb3VwQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEdyb3VwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXBPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRHcm91cE9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkR3JvdXBfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEdyb3VwT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEdyb3VwQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkR3JvdXBfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSA0NiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAuQnVpbGRlciBhZGRSZXBlYXRlZEdyb3VwQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRHcm91cEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gNDYgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwLkJ1aWxkZXIgYWRkUmVwZWF0ZWRHcm91cEJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRHcm91cEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDQ2IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cC5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEdyb3VwQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkR3JvdXBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkR3JvdXBGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEdyb3VwQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlJlcGVhdGVkR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cE9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkR3JvdXBfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMV8gJiAweDAwMDAwNDAwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkR3JvdXBCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMV8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U+KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwODAwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UgPSA0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWRNZXNzYWdlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkTmVzdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZSA9IDQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkTWVzc2FnZV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX25lc3RlZF9tZXNzYWdlID0gNDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDFfICYgMHgwMDAwMDgwMCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4ocmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8pOwogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAxMDAwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGb3JlaWduTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGb3JlaWduTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZEZvcmVpZ25NZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduTWVzc2FnZV8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZSA9IDQ5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlID0gNDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRGb3JlaWduTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSByZXBlYXRlZF9mb3JlaWduX21lc3NhZ2UgPSA0OTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25NZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMV8gJiAweDAwMDAxMDAwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4ocmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW1wb3J0TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEltcG9ydE1lc3NhZ2UoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW1wb3J0TWVzc2FnZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2U+IHZhbHVlcykgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkSW1wb3J0TWVzc2FnZSgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRJbXBvcnRNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEltcG9ydE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2UgcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UgPSA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZSByZXBlYXRlZF9pbXBvcnRfbWVzc2FnZSA9IDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRJbXBvcnRNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlIHJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlID0gNTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEltcG9ydE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydE1lc3NhZ2UsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLkJ1aWxkZXIsIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkSW1wb3J0TWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5CdWlsZGVyLCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW1wb3J0TWVzc2FnZV8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQxXyAmIDB4MDAwMDIwMDApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWROZXN0ZWRFbnVtXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4ocmVwZWF0ZWROZXN0ZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkTmVzdGVkRW51bS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBnZXRSZXBlYXRlZE5lc3RlZEVudW1MaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0+KHJlcGVhdGVkTmVzdGVkRW51bV8sIHJlcGVhdGVkTmVzdGVkRW51bV9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZE5lc3RlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkRW51bUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlcGVhdGVkX25lc3RlZF9lbnVtID0gNTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWROZXN0ZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGdldFJlcGVhdGVkTmVzdGVkRW51bShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRFbnVtX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZE5lc3RlZEVudW1fLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZE5lc3RlZEVudW0oCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSByZXBlYXRlZF9uZXN0ZWRfZW51bSA9IDUxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZE5lc3RlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZEVudW0ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkTmVzdGVkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkTmVzdGVkRW51bSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZE5lc3RlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gcmVwZWF0ZWRfbmVzdGVkX2VudW0gPSA1MTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWROZXN0ZWRFbnVtKCkgewogICAgICAgIHJlcGVhdGVkTmVzdGVkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZEZvcmVpZ25FbnVtXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQxXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZEZvcmVpZ25FbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+IGdldFJlcGVhdGVkRm9yZWlnbkVudW1MaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+KHJlcGVhdGVkRm9yZWlnbkVudW1fLCByZXBlYXRlZEZvcmVpZ25FbnVtX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZvcmVpZ25FbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZvcmVpZ25FbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRm9yZWlnbkVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcGVhdGVkX2ZvcmVpZ25fZW51bSA9IDUyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRm9yZWlnbkVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0UmVwZWF0ZWRGb3JlaWduRW51bShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGb3JlaWduRW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRGb3JlaWduRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGb3JlaWduRW51bSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRm9yZWlnbkVudW1fLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRm9yZWlnbkVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZvcmVpZ25FbnVtKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkRm9yZWlnbkVudW1Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVwZWF0ZWRfZm9yZWlnbl9lbnVtID0gNTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEZvcmVpZ25FbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGb3JlaWduRW51bSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGb3JlaWduRW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWRGb3JlaWduRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSByZXBlYXRlZF9mb3JlaWduX2VudW0gPSA1Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRGb3JlaWduRW51bSgpIHsKICAgICAgICByZXBlYXRlZEZvcmVpZ25FbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkSW1wb3J0RW51bV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW1wb3J0RW51bUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQxXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEltcG9ydEVudW1fID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHJlcGVhdGVkSW1wb3J0RW51bV8pOwogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDEwMDAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtIHJlcGVhdGVkX2ltcG9ydF9lbnVtID0gNTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEltcG9ydEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0+IGdldFJlcGVhdGVkSW1wb3J0RW51bUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0+KHJlcGVhdGVkSW1wb3J0RW51bV8sIHJlcGVhdGVkSW1wb3J0RW51bV9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtIHJlcGVhdGVkX2ltcG9ydF9lbnVtID0gNTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEltcG9ydEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW1wb3J0RW51bUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEltcG9ydEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtIHJlcGVhdGVkX2ltcG9ydF9lbnVtID0gNTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbXBvcnRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bSBnZXRSZXBlYXRlZEltcG9ydEVudW0oaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW1wb3J0RW51bV9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRJbXBvcnRFbnVtXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtIHJlcGVhdGVkX2ltcG9ydF9lbnVtID0gNTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbXBvcnRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRJbXBvcnRFbnVtKAogICAgICAgICAgaW50IGluZGV4LCBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbXBvcnRFbnVtXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtIHJlcGVhdGVkX2ltcG9ydF9lbnVtID0gNTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW1wb3J0RW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW1wb3J0RW51bShjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0RW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbXBvcnRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbXBvcnRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW0gcmVwZWF0ZWRfaW1wb3J0X2VudW0gPSA1Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkSW1wb3J0RW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW1wb3J0RW51bSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkSW1wb3J0RW51bUlzTXV0YWJsZSgpOwogICAgICAgIGZvciAoY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHJlcGVhdGVkSW1wb3J0RW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSByZXBlYXRlZF9pbXBvcnRfZW51bSA9IDUzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEltcG9ydEVudW0oKSB7CiAgICAgICAgcmVwZWF0ZWRJbXBvcnRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nUGllY2VfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZ1BpZWNlXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KHJlcGVhdGVkU3RyaW5nUGllY2VfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDIwMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nUGllY2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmdQaWVjZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nUGllY2UgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFN0cmluZ1BpZWNlKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nUGllY2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfcGllY2UgPSA1NCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nUGllY2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdQaWVjZUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZ1BpZWNlXyk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX3BpZWNlID0gNTQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmdQaWVjZSgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMjAwMDApOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19waWVjZSA9IDU0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmdQaWVjZUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZV8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkQ29yZF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRDb3JkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRDb3JkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRDb3JkXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRDb3JkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDA0MDAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQ29yZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0UmVwZWF0ZWRDb3JkTGlzdCgpIHsKICAgICAgICByZXBlYXRlZENvcmRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQ29yZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRDb3JkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQ29yZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZENvcmQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZF8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkQ29yZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRSZXBlYXRlZENvcmRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRDb3JkXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2NvcmQgPSA1NSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZENvcmQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZENvcmQoCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQ29yZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQ29yZF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZENvcmQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZENvcmQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZENvcmRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZENvcmRfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRDb3JkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRDb3JkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkQ29yZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZENvcmRfKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9jb3JkID0gNTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQ29yZCgpIHsKICAgICAgICByZXBlYXRlZENvcmRfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDA0MDAwMCk7OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfY29yZCA9IDU1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRDb3JkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRDb3JkQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQ29yZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQ29yZF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMV8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPihyZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRMYXp5TWVzc2FnZV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTGF6eU1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTGF6eU1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZExhenlNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZExhenlNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTGF6eU1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZExhenlNZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRMYXp5TWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZExhenlNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRMYXp5TWVzc2FnZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZExhenlNZXNzYWdlXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDgwMDAwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkTGF6eU1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZExhenlNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZExhenlNZXNzYWdlXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRSZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRMYXp5TWVzc2FnZV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHJlcGVhdGVkX2xhenlfbWVzc2FnZSA9IDU3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZExhenlNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgcmVwZWF0ZWRfbGF6eV9tZXNzYWdlID0gNTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSByZXBlYXRlZF9sYXp5X21lc3NhZ2UgPSA1NyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRMYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQxXyAmIDB4MDAwODAwMDApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRMYXp5TWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBkZWZhdWx0SW50MzJfID0gNDE7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBTaW5ndWxhciB3aXRoIGRlZmF1bHRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkZWZhdWx0X2ludDMyID0gNjEgW2RlZmF1bHQgPSA0MV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRJbnQzMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFNpbmd1bGFyIHdpdGggZGVmYXVsdHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRlZmF1bHRfaW50MzIgPSA2MSBbZGVmYXVsdCA9IDQxXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRJbnQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXREZWZhdWx0SW50MzIoKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRJbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFNpbmd1bGFyIHdpdGggZGVmYXVsdHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRlZmF1bHRfaW50MzIgPSA2MSBbZGVmYXVsdCA9IDQxXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGVmYXVsdEludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVmYXVsdEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBkZWZhdWx0SW50MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBTaW5ndWxhciB3aXRoIGRlZmF1bHRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkZWZhdWx0X2ludDMyID0gNjEgW2RlZmF1bHQgPSA0MV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRlZmF1bHRJbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgZGVmYXVsdEludDMyXyA9IDQxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZGVmYXVsdEludDY0XyA9IDQyTDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGRlZmF1bHRfaW50NjQgPSA2MiBbZGVmYXVsdCA9IDQyXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdEludDY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRGVmYXVsdEludDY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgZGVmYXVsdF9pbnQ2NCA9IDYyIFtkZWZhdWx0ID0gNDJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZGVmYXVsdEludDY0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXREZWZhdWx0SW50NjQoKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGRlZmF1bHRfaW50NjQgPSA2MiBbZGVmYXVsdCA9IDQyXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGVmYXVsdEludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVmYXVsdEludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZGVmYXVsdEludDY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgZGVmYXVsdF9pbnQ2NCA9IDYyIFtkZWZhdWx0ID0gNDJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZWZhdWx0SW50NjQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAyMDAwMDApOwogICAgICAgIGRlZmF1bHRJbnQ2NF8gPSA0Mkw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGRlZmF1bHRVaW50MzJfID0gNDM7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgZGVmYXVsdF91aW50MzIgPSA2MyBbZGVmYXVsdCA9IDQzXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdFVpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRVaW50MzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgZGVmYXVsdF91aW50MzIgPSA2MyBbZGVmYXVsdCA9IDQzXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRVaW50MzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RGVmYXVsdFVpbnQzMigpIHsKICAgICAgICByZXR1cm4gZGVmYXVsdFVpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBkZWZhdWx0X3VpbnQzMiA9IDYzIFtkZWZhdWx0ID0gNDNdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkZWZhdWx0VWludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVmYXVsdFVpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZGVmYXVsdFVpbnQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBkZWZhdWx0X3VpbnQzMiA9IDYzIFtkZWZhdWx0ID0gNDNdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZWZhdWx0VWludDMyKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBkZWZhdWx0VWludDMyXyA9IDQzOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZGVmYXVsdFVpbnQ2NF8gPSA0NEw7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgZGVmYXVsdF91aW50NjQgPSA2NCBbZGVmYXVsdCA9IDQ0XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdFVpbnQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRVaW50NjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgZGVmYXVsdF91aW50NjQgPSA2NCBbZGVmYXVsdCA9IDQ0XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRVaW50NjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldERlZmF1bHRVaW50NjQoKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRVaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgZGVmYXVsdF91aW50NjQgPSA2NCBbZGVmYXVsdCA9IDQ0XTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGVmYXVsdFVpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERlZmF1bHRVaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBkZWZhdWx0VWludDY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGRlZmF1bHRfdWludDY0ID0gNjQgW2RlZmF1bHQgPSA0NF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRlZmF1bHRVaW50NjQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDA4MDAwMDApOwogICAgICAgIGRlZmF1bHRVaW50NjRfID0gNDRMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBkZWZhdWx0U2ludDMyXyA9IC00NTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQzMiBkZWZhdWx0X3NpbnQzMiA9IDY1IFtkZWZhdWx0ID0gLTQ1XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdFNpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRTaW50MzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgZGVmYXVsdF9zaW50MzIgPSA2NSBbZGVmYXVsdCA9IC00NV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0U2ludDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldERlZmF1bHRTaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRTaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzaW50MzIgZGVmYXVsdF9zaW50MzIgPSA2NSBbZGVmYXVsdCA9IC00NV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlZmF1bHRTaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0U2ludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBkZWZhdWx0U2ludDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDMyIGRlZmF1bHRfc2ludDMyID0gNjUgW2RlZmF1bHQgPSAtNDVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZWZhdWx0U2ludDMyKCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBkZWZhdWx0U2ludDMyXyA9IC00NTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIGRlZmF1bHRTaW50NjRfID0gNDZMOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IGRlZmF1bHRfc2ludDY0ID0gNjYgW2RlZmF1bHQgPSA0Nl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRTaW50NjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0U2ludDY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IGRlZmF1bHRfc2ludDY0ID0gNjYgW2RlZmF1bHQgPSA0Nl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0U2ludDY0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXREZWZhdWx0U2ludDY0KCkgewogICAgICAgIHJldHVybiBkZWZhdWx0U2ludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ludDY0IGRlZmF1bHRfc2ludDY0ID0gNjYgW2RlZmF1bHQgPSA0Nl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlZmF1bHRTaW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0U2ludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZGVmYXVsdFNpbnQ2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHNpbnQ2NCBkZWZhdWx0X3NpbnQ2NCA9IDY2IFtkZWZhdWx0ID0gNDZdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZWZhdWx0U2ludDY0KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBkZWZhdWx0U2ludDY0XyA9IDQ2TDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZGVmYXVsdEZpeGVkMzJfID0gNDc7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIGRlZmF1bHRfZml4ZWQzMiA9IDY3IFtkZWZhdWx0ID0gNDddOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0Rml4ZWQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRGaXhlZDMyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBkZWZhdWx0X2ZpeGVkMzIgPSA2NyBbZGVmYXVsdCA9IDQ3XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRGaXhlZDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldERlZmF1bHRGaXhlZDMyKCkgewogICAgICAgIHJldHVybiBkZWZhdWx0Rml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgZGVmYXVsdF9maXhlZDMyID0gNjcgW2RlZmF1bHQgPSA0N107PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlZmF1bHRGaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVmYXVsdEZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGRlZmF1bHRGaXhlZDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBkZWZhdWx0X2ZpeGVkMzIgPSA2NyBbZGVmYXVsdCA9IDQ3XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGVmYXVsdEZpeGVkMzIoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDQwMDAwMDApOwogICAgICAgIGRlZmF1bHRGaXhlZDMyXyA9IDQ3OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgZGVmYXVsdEZpeGVkNjRfID0gNDhMOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBkZWZhdWx0X2ZpeGVkNjQgPSA2OCBbZGVmYXVsdCA9IDQ4XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdEZpeGVkNjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0Rml4ZWQ2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkNjQgZGVmYXVsdF9maXhlZDY0ID0gNjggW2RlZmF1bHQgPSA0OF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0Rml4ZWQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RGVmYXVsdEZpeGVkNjQoKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHRGaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBkZWZhdWx0X2ZpeGVkNjQgPSA2OCBbZGVmYXVsdCA9IDQ4XTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGVmYXVsdEZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0Rml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGRlZmF1bHRGaXhlZDY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQ2NCBkZWZhdWx0X2ZpeGVkNjQgPSA2OCBbZGVmYXVsdCA9IDQ4XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGVmYXVsdEZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDgwMDAwMDApOwogICAgICAgIGRlZmF1bHRGaXhlZDY0XyA9IDQ4TDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZGVmYXVsdFNmaXhlZDMyXyA9IDQ5OwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgZGVmYXVsdF9zZml4ZWQzMiA9IDY5IFtkZWZhdWx0ID0gNDldOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0U2ZpeGVkMzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0U2ZpeGVkMzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBkZWZhdWx0X3NmaXhlZDMyID0gNjkgW2RlZmF1bHQgPSA0OV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0U2ZpeGVkMzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RGVmYXVsdFNmaXhlZDMyKCkgewogICAgICAgIHJldHVybiBkZWZhdWx0U2ZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQzMiBkZWZhdWx0X3NmaXhlZDMyID0gNjkgW2RlZmF1bHQgPSA0OV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlZmF1bHRTZml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERlZmF1bHRTZml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZGVmYXVsdFNmaXhlZDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkMzIgZGVmYXVsdF9zZml4ZWQzMiA9IDY5IFtkZWZhdWx0ID0gNDldOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZWZhdWx0U2ZpeGVkMzIoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MTAwMDAwMDApOwogICAgICAgIGRlZmF1bHRTZml4ZWQzMl8gPSA0OTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIGRlZmF1bHRTZml4ZWQ2NF8gPSAtNTBMOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgZGVmYXVsdF9zZml4ZWQ2NCA9IDcwIFtkZWZhdWx0ID0gLTUwXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdFNmaXhlZDY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRGVmYXVsdFNmaXhlZDY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc2ZpeGVkNjQgZGVmYXVsdF9zZml4ZWQ2NCA9IDcwIFtkZWZhdWx0ID0gLTUwXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRTZml4ZWQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RGVmYXVsdFNmaXhlZDY0KCkgewogICAgICAgIHJldHVybiBkZWZhdWx0U2ZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBkZWZhdWx0X3NmaXhlZDY0ID0gNzAgW2RlZmF1bHQgPSAtNTBdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkZWZhdWx0U2ZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0U2ZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBkZWZhdWx0U2ZpeGVkNjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzZml4ZWQ2NCBkZWZhdWx0X3NmaXhlZDY0ID0gNzAgW2RlZmF1bHQgPSAtNTBdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZWZhdWx0U2ZpeGVkNjQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MjAwMDAwMDApOwogICAgICAgIGRlZmF1bHRTZml4ZWQ2NF8gPSAtNTBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IGRlZmF1bHRGbG9hdF8gPSA1MS41RjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGRlZmF1bHRfZmxvYXQgPSA3MSBbZGVmYXVsdCA9IDUxLjVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0RmxvYXQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0RmxvYXQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBkZWZhdWx0X2Zsb2F0ID0gNzEgW2RlZmF1bHQgPSA1MS41XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRGbG9hdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldERlZmF1bHRGbG9hdCgpIHsKICAgICAgICByZXR1cm4gZGVmYXVsdEZsb2F0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZGVmYXVsdF9mbG9hdCA9IDcxIFtkZWZhdWx0ID0gNTEuNV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlZmF1bHRGbG9hdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERlZmF1bHRGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBkZWZhdWx0RmxvYXRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBkZWZhdWx0X2Zsb2F0ID0gNzEgW2RlZmF1bHQgPSA1MS41XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGVmYXVsdEZsb2F0KCkgewogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBkZWZhdWx0RmxvYXRfID0gNTEuNUY7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZG91YmxlIGRlZmF1bHREb3VibGVfID0gNTIwMDBEOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGRlZmF1bHRfZG91YmxlID0gNzIgW2RlZmF1bHQgPSA1MjAwMF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHREb3VibGUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0RG91YmxlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGRlZmF1bHRfZG91YmxlID0gNzIgW2RlZmF1bHQgPSA1MjAwMF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0RG91YmxlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldERlZmF1bHREb3VibGUoKSB7CiAgICAgICAgcmV0dXJuIGRlZmF1bHREb3VibGVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgZGVmYXVsdF9kb3VibGUgPSA3MiBbZGVmYXVsdCA9IDUyMDAwXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGVmYXVsdERvdWJsZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERlZmF1bHREb3VibGUoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGRlZmF1bHREb3VibGVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgZGVmYXVsdF9kb3VibGUgPSA3MiBbZGVmYXVsdCA9IDUyMDAwXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGVmYXVsdERvdWJsZSgpIHsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgZGVmYXVsdERvdWJsZV8gPSA1MjAwMEQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYm9vbGVhbiBkZWZhdWx0Qm9vbF8gPSB0cnVlOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZWZhdWx0X2Jvb2wgPSA3MyBbZGVmYXVsdCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0Qm9vbCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRCb29sKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZWZhdWx0X2Jvb2wgPSA3MyBbZGVmYXVsdCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZGVmYXVsdEJvb2wuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldERlZmF1bHRCb29sKCkgewogICAgICAgIHJldHVybiBkZWZhdWx0Qm9vbF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGVmYXVsdF9ib29sID0gNzMgW2RlZmF1bHQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGVmYXVsdEJvb2wgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0Qm9vbChib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGRlZmF1bHRCb29sXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkZWZhdWx0X2Jvb2wgPSA3MyBbZGVmYXVsdCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZWZhdWx0Qm9vbCgpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgZGVmYXVsdEJvb2xfID0gdHJ1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGRlZmF1bHRTdHJpbmdfID0gImhlbGxvIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3N0cmluZyA9IDc0IFtkZWZhdWx0ID0gImhlbGxvIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRGVmYXVsdFN0cmluZygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3N0cmluZyA9IDc0IFtkZWZhdWx0ID0gImhlbGxvIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0U3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RGVmYXVsdFN0cmluZygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGRlZmF1bHRTdHJpbmdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgZGVmYXVsdFN0cmluZ18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nID0gNzQgW2RlZmF1bHQgPSAiaGVsbG8iXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBkZWZhdWx0U3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RGVmYXVsdFN0cmluZ0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZGVmYXVsdFN0cmluZ187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGRlZmF1bHRTdHJpbmdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nID0gNzQgW2RlZmF1bHQgPSAiaGVsbG8iXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGVmYXVsdFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERlZmF1bHRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBkZWZhdWx0U3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nID0gNzQgW2RlZmF1bHQgPSAiaGVsbG8iXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGVmYXVsdFN0cmluZygpIHsKICAgICAgICBkZWZhdWx0U3RyaW5nXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldERlZmF1bHRTdHJpbmcoKTsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X3N0cmluZyA9IDc0IFtkZWZhdWx0ID0gImhlbGxvIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBkZWZhdWx0U3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVmYXVsdFN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBkZWZhdWx0U3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGVmYXVsdEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuYnl0ZXNEZWZhdWx0VmFsdWUoIndvcmxkIik7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBkZWZhdWx0X2J5dGVzID0gNzUgW2RlZmF1bHQgPSAid29ybGQiXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdEJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRGVmYXVsdEJ5dGVzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZGVmYXVsdF9ieXRlcyA9IDc1IFtkZWZhdWx0ID0gIndvcmxkIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0Qnl0ZXMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RGVmYXVsdEJ5dGVzKCkgewogICAgICAgIHJldHVybiBkZWZhdWx0Qnl0ZXNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBkZWZhdWx0X2J5dGVzID0gNzUgW2RlZmF1bHQgPSAid29ybGQiXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGVmYXVsdEJ5dGVzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVmYXVsdEJ5dGVzKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZGVmYXVsdEJ5dGVzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZGVmYXVsdF9ieXRlcyA9IDc1IFtkZWZhdWx0ID0gIndvcmxkIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRlZmF1bHRCeXRlcygpIHsKICAgICAgICBiaXRGaWVsZDJfID0gKGJpdEZpZWxkMl8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgZGVmYXVsdEJ5dGVzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldERlZmF1bHRCeXRlcygpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBkZWZhdWx0TmVzdGVkRW51bV8gPSAyOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGRlZmF1bHRfbmVzdGVkX2VudW0gPSA4MSBbZGVmYXVsdCA9IEJBUl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHROZXN0ZWRFbnVtIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzRGVmYXVsdE5lc3RlZEVudW0oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gZGVmYXVsdF9uZXN0ZWRfZW51bSA9IDgxIFtkZWZhdWx0ID0gQkFSXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHROZXN0ZWRFbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBnZXREZWZhdWx0TmVzdGVkRW51bSgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uZm9yTnVtYmVyKGRlZmF1bHROZXN0ZWRFbnVtXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bS5CQVIgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bSBkZWZhdWx0X25lc3RlZF9lbnVtID0gODEgW2RlZmF1bHQgPSBCQVJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkZWZhdWx0TmVzdGVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERlZmF1bHROZXN0ZWRFbnVtKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDAwODsKICAgICAgICBkZWZhdWx0TmVzdGVkRW51bV8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtIGRlZmF1bHRfbmVzdGVkX2VudW0gPSA4MSBbZGVmYXVsdCA9IEJBUl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRlZmF1bHROZXN0ZWRFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBkZWZhdWx0TmVzdGVkRW51bV8gPSAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBkZWZhdWx0Rm9yZWlnbkVudW1fID0gNTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBkZWZhdWx0X2ZvcmVpZ25fZW51bSA9IDgyIFtkZWZhdWx0ID0gRk9SRUlHTl9CQVJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZWZhdWx0Rm9yZWlnbkVudW0gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0Rm9yZWlnbkVudW0oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gZGVmYXVsdF9mb3JlaWduX2VudW0gPSA4MiBbZGVmYXVsdCA9IEZPUkVJR05fQkFSXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRGb3JlaWduRW51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0RGVmYXVsdEZvcmVpZ25FbnVtKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIoZGVmYXVsdEZvcmVpZ25FbnVtXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5GT1JFSUdOX0JBUiA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIGRlZmF1bHRfZm9yZWlnbl9lbnVtID0gODIgW2RlZmF1bHQgPSBGT1JFSUdOX0JBUl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlZmF1bHRGb3JlaWduRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERlZmF1bHRGb3JlaWduRW51bShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgZGVmYXVsdEZvcmVpZ25FbnVtXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gZGVmYXVsdF9mb3JlaWduX2VudW0gPSA4MiBbZGVmYXVsdCA9IEZPUkVJR05fQkFSXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGVmYXVsdEZvcmVpZ25FbnVtKCkgewogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBkZWZhdWx0Rm9yZWlnbkVudW1fID0gNTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZGVmYXVsdEltcG9ydEVudW1fID0gODsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSBkZWZhdWx0X2ltcG9ydF9lbnVtID0gODMgW2RlZmF1bHQgPSBJTVBPUlRfQkFSXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVmYXVsdEltcG9ydEVudW0gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0SW1wb3J0RW51bSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDJfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSBkZWZhdWx0X2ltcG9ydF9lbnVtID0gODMgW2RlZmF1bHQgPSBJTVBPUlRfQkFSXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRlZmF1bHRJbXBvcnRFbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0gZ2V0RGVmYXVsdEltcG9ydEVudW0oKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0gcmVzdWx0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0uZm9yTnVtYmVyKGRlZmF1bHRJbXBvcnRFbnVtXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0uSU1QT1JUX0JBUiA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtIGRlZmF1bHRfaW1wb3J0X2VudW0gPSA4MyBbZGVmYXVsdCA9IElNUE9SVF9CQVJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkZWZhdWx0SW1wb3J0RW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERlZmF1bHRJbXBvcnRFbnVtKGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgZGVmYXVsdEltcG9ydEVudW1fID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bSBkZWZhdWx0X2ltcG9ydF9lbnVtID0gODMgW2RlZmF1bHQgPSBJTVBPUlRfQkFSXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGVmYXVsdEltcG9ydEVudW0oKSB7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwMjApOwogICAgICAgIGRlZmF1bHRJbXBvcnRFbnVtXyA9IDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBkZWZhdWx0U3RyaW5nUGllY2VfID0gImFiYyI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfcGllY2UgPSA4NCBbZGVmYXVsdCA9ICJhYmMiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRTdHJpbmdQaWVjZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEZWZhdWx0U3RyaW5nUGllY2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQyXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfcGllY2UgPSA4NCBbZGVmYXVsdCA9ICJhYmMiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0U3RyaW5nUGllY2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXREZWZhdWx0U3RyaW5nUGllY2UoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBkZWZhdWx0U3RyaW5nUGllY2VfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgZGVmYXVsdFN0cmluZ1BpZWNlXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfcGllY2UgPSA4NCBbZGVmYXVsdCA9ICJhYmMiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZGVmYXVsdFN0cmluZ1BpZWNlLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RGVmYXVsdFN0cmluZ1BpZWNlQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBkZWZhdWx0U3RyaW5nUGllY2VfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBkZWZhdWx0U3RyaW5nUGllY2VfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfc3RyaW5nX3BpZWNlID0gODQgW2RlZmF1bHQgPSAiYWJjIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkZWZhdWx0U3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0U3RyaW5nUGllY2UoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBkZWZhdWx0U3RyaW5nUGllY2VfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQyXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfcGllY2UgPSA4NCBbZGVmYXVsdCA9ICJhYmMiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRlZmF1bHRTdHJpbmdQaWVjZSgpIHsKICAgICAgICBkZWZhdWx0U3RyaW5nUGllY2VfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0RGVmYXVsdFN0cmluZ1BpZWNlKCk7CiAgICAgICAgYml0RmllbGQyXyA9IChiaXRGaWVsZDJfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGVmYXVsdF9zdHJpbmdfcGllY2UgPSA4NCBbZGVmYXVsdCA9ICJhYmMiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBkZWZhdWx0U3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREZWZhdWx0U3RyaW5nUGllY2VCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZGVmYXVsdFN0cmluZ1BpZWNlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGRlZmF1bHRDb3JkXyA9ICIxMjMiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfY29yZCA9IDg1IFtkZWZhdWx0ID0gIjEyMyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlZmF1bHRDb3JkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0RlZmF1bHRDb3JkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMl8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfY29yZCA9IDg1IFtkZWZhdWx0ID0gIjEyMyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkZWZhdWx0Q29yZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldERlZmF1bHRDb3JkKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZGVmYXVsdENvcmRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgZGVmYXVsdENvcmRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X2NvcmQgPSA4NSBbZGVmYXVsdCA9ICIxMjMiLCBjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGRlZmF1bHRDb3JkLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0RGVmYXVsdENvcmRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGRlZmF1bHRDb3JkXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgZGVmYXVsdENvcmRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfY29yZCA9IDg1IFtkZWZhdWx0ID0gIjEyMyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlZmF1bHRDb3JkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGVmYXVsdENvcmQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBkZWZhdWx0Q29yZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDJfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkZWZhdWx0X2NvcmQgPSA4NSBbZGVmYXVsdCA9ICIxMjMiLCBjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEZWZhdWx0Q29yZCgpIHsKICAgICAgICBkZWZhdWx0Q29yZF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXREZWZhdWx0Q29yZCgpOwogICAgICAgIGJpdEZpZWxkMl8gPSAoYml0RmllbGQyXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRlZmF1bHRfY29yZCA9IDg1IFtkZWZhdWx0ID0gIjEyMyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBkZWZhdWx0Q29yZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERlZmF1bHRDb3JkQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGRlZmF1bHRDb3JkXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMl8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mVWludDMyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mVWludDMyKCkgewogICAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTExOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb25lb2ZVaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldE9uZW9mVWludDMyKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTExKSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSBvbmVvZkZpZWxkXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSAxMTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9uZW9mVWludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZVaW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMTsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gMTExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZlVpbnQzMigpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMSkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZk5lc3RlZE1lc3NhZ2UuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldE9uZW9mTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIpIHsKICAgICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICAgICByZXR1cm4gb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZOZXN0ZWRNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZk5lc3RlZE1lc3NhZ2UoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9uZW9mTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT25lb2ZOZXN0ZWRNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTIgJiYKICAgICAgICAgICAgICBvbmVvZkZpZWxkXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXykKICAgICAgICAgICAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMikgewogICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX25lc3RlZF9tZXNzYWdlID0gMTEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbmVzdGVkX21lc3NhZ2UgPSAxMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPbmVvZk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSAmJiAob25lb2ZOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICAgIHJldHVybiBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSB7CiAgICAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSkgb25lb2ZGaWVsZF87CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9uZXN0ZWRfbWVzc2FnZSA9IDExMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T25lb2ZOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIShvbmVvZkZpZWxkQ2FzZV8gPT0gMTEyKSkgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXywKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTEyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBvbmVvZk5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZlN0cmluZy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T25lb2ZTdHJpbmcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHM7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9uZW9mU3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExMykgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGI7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9uZW9mU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTM7CiAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDExMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZTdHJpbmcoKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTMpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSAxMTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvbmVvZlN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mU3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExMzsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZCeXRlcygpIHsKICAgICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDExNDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSAxMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZkJ5dGVzLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPbmVvZkJ5dGVzKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE0KSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gMTE0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVvZkJ5dGVzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZCeXRlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExNDsKICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDExNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZCeXRlcygpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNCkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9jb3JkID0gMTE1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZkNvcmQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZkNvcmQoKSB7CiAgICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9jb3JkID0gMTE1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb25lb2ZDb3JkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPbmVvZkNvcmQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNSkgewogICAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTUpIHsKICAgICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHM7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9jb3JkID0gMTE1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9uZW9mQ29yZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0T25lb2ZDb3JkQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNSkgewogICAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgICAgfQogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNSkgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGI7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9jb3JkID0gMTE1IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVvZkNvcmQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZkNvcmQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTU7CiAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX2NvcmQgPSAxMTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mQ29yZCgpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNSkgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX2NvcmQgPSAxMTUgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvbmVvZkNvcmQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZkNvcmRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTE1OwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nX3BpZWNlID0gMTE2IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mU3RyaW5nUGllY2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVvZlN0cmluZ1BpZWNlKCkgewogICAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gMTE2OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nX3BpZWNlID0gMTE2IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZlN0cmluZ1BpZWNlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPbmVvZlN0cmluZ1BpZWNlKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTYpIHsKICAgICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE2KSB7CiAgICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBzOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nX3BpZWNlID0gMTE2IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmdQaWVjZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0T25lb2ZTdHJpbmdQaWVjZUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTYpIHsKICAgICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTYpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nX3BpZWNlID0gMTE2IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9uZW9mU3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZlN0cmluZ1BpZWNlKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTE2OwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmdfcGllY2UgPSAxMTYgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZTdHJpbmdQaWVjZSgpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNikgewogICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZ19waWVjZSA9IDExNiBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmdQaWVjZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mU3RyaW5nUGllY2VCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTE2OwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gb25lb2ZMYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX2xhenlfbmVzdGVkX21lc3NhZ2UgPSAxMTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZMYXp5TmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mTGF6eU5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSAxMTc7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBvbmVvZl9sYXp5X25lc3RlZF9tZXNzYWdlID0gMTE3IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZkxhenlOZXN0ZWRNZXNzYWdlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRPbmVvZkxhenlOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChvbmVvZkxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTcpIHsKICAgICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNykgewogICAgICAgICAgICByZXR1cm4gb25lb2ZMYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX2xhenlfbmVzdGVkX21lc3NhZ2UgPSAxMTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZkxhenlOZXN0ZWRNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob25lb2ZMYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvbmVvZkxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExNzsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX2xhenlfbmVzdGVkX21lc3NhZ2UgPSAxMTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZkxhenlOZXN0ZWRNZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvbmVvZkxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvbmVvZkxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDExNzsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX2xhenlfbmVzdGVkX21lc3NhZ2UgPSAxMTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9uZW9mTGF6eU5lc3RlZE1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvbmVvZkxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSAxMTcgJiYKICAgICAgICAgICAgICBvbmVvZkZpZWxkXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlKSBvbmVvZkZpZWxkXykKICAgICAgICAgICAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNykgewogICAgICAgICAgICBvbmVvZkxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9uZW9mTGF6eU5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gMTE3OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbGF6eV9uZXN0ZWRfbWVzc2FnZSA9IDExNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZMYXp5TmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAob25lb2ZMYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE3KSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gMTE3KSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIG9uZW9mTGF6eU5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIG9uZW9mX2xhenlfbmVzdGVkX21lc3NhZ2UgPSAxMTcgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9uZW9mTGF6eU5lc3RlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRPbmVvZkxhenlOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbGF6eV9uZXN0ZWRfbWVzc2FnZSA9IDExNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0T25lb2ZMYXp5TmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoKG9uZW9mRmllbGRDYXNlXyA9PSAxMTcpICYmIChvbmVvZkxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICAgIHJldHVybiBvbmVvZkxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDExNykgewogICAgICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2Ugb25lb2ZfbGF6eV9uZXN0ZWRfbWVzc2FnZSA9IDExNyBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPbmVvZkxhenlOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvbmVvZkxhenlOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCEob25lb2ZGaWVsZENhc2VfID09IDExNykpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgICAgfQogICAgICAgICAgb25lb2ZMYXp5TmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UpIG9uZW9mRmllbGRfLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAxMTc7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG9uZW9mTGF6eU5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RBbGxUeXBlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0QWxsVHlwZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0QWxsVHlwZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0QWxsVHlwZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEFsbFR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIE5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNoaWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNDaGlsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMgZ2V0Q2hpbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRDaGlsZE9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBheWxvYWQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1BheWxvYWQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBwYXlsb2FkLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRQYXlsb2FkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRQYXlsb2FkT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzPiAKICAgICAgICBnZXRSZXBlYXRlZENoaWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQ2hpbGQoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRDaGlsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZENoaWxkT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcGVhdGVkQ2hpbGRPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgbGF6eV9jaGlsZCA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxhenlDaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTGF6eUNoaWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgbGF6eV9jaGlsZCA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsYXp5Q2hpbGQuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIGdldExhenlDaGlsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGxhenlfY2hpbGQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRMYXp5Q2hpbGRPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZWFnZXJfY2hpbGQgPSA1IFtsYXp5ID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZWFnZXJDaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRWFnZXJDaGlsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGVhZ2VyX2NoaWxkID0gNSBbbGF6eSA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlYWdlckNoaWxkLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRFYWdlckNoaWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZWFnZXJfY2hpbGQgPSA1IFtsYXp5ID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0RWFnZXJDaGlsZE9yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRoaXMgcHJvdG8gaW5jbHVkZXMgYSByZWN1cnNpdmVseSBuZXN0ZWQgbWVzc2FnZS4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZFRlc3RBbGxUeXBlcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMpCiAgICAgIE5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgTmVzdGVkVGVzdEFsbFR5cGVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIE5lc3RlZFRlc3RBbGxUeXBlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIE5lc3RlZFRlc3RBbGxUeXBlcygpIHsKICAgICAgcmVwZWF0ZWRDaGlsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgTmVzdGVkVGVzdEFsbFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDSElMRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZF87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2hpbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIGdldENoaWxkKCkgewogICAgICByZXR1cm4gY2hpbGRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0Q2hpbGRPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogY2hpbGRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBWUxPQURfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgcGF5bG9hZF87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXlsb2FkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUGF5bG9hZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHBheWxvYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRQYXlsb2FkKCkgewogICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcGF5bG9hZF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UGF5bG9hZE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHBheWxvYWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBheWxvYWRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0NISUxEX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXM+IHJlcGVhdGVkQ2hpbGRfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcz4gZ2V0UmVwZWF0ZWRDaGlsZExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZENoaWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZENoaWxkT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQ2hpbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRDaGlsZENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRDaGlsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBnZXRSZXBlYXRlZENoaWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRDaGlsZF8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRDaGlsZE9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQ2hpbGRfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTEFaWV9DSElMRF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBsYXp5Q2hpbGRfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGxhenlfY2hpbGQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsYXp5Q2hpbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMYXp5Q2hpbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBsYXp5X2NoaWxkID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxhenlDaGlsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIGdldExhenlDaGlsZCgpIHsKICAgICAgcmV0dXJuIGxhenlDaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbGF6eUNoaWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBsYXp5X2NoaWxkID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldExhenlDaGlsZE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGxhenlDaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbGF6eUNoaWxkXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFQUdFUl9DSElMRF9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBlYWdlckNoaWxkXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBlYWdlcl9jaGlsZCA9IDUgW2xhenkgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBlYWdlckNoaWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRWFnZXJDaGlsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGVhZ2VyX2NoaWxkID0gNSBbbGF6eSA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlYWdlckNoaWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0RWFnZXJDaGlsZCgpIHsKICAgICAgcmV0dXJuIGVhZ2VyQ2hpbGRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGVhZ2VyQ2hpbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGVhZ2VyX2NoaWxkID0gNSBbbGF6eSA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRFYWdlckNoaWxkT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gZWFnZXJDaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZWFnZXJDaGlsZF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEsIGdldENoaWxkKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMiwgZ2V0UGF5bG9hZCgpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQ2hpbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgzLCByZXBlYXRlZENoaWxkXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNCwgZ2V0TGF6eUNoaWxkKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNSwgZ2V0RWFnZXJDaGlsZCgpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGdldENoaWxkKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBnZXRQYXlsb2FkKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRDaGlsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgcmVwZWF0ZWRDaGlsZF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgZ2V0TGF6eUNoaWxkKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1LCBnZXRFYWdlckNoaWxkKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcykgb2JqOwoKICAgICAgaWYgKGhhc0NoaWxkKCkgIT0gb3RoZXIuaGFzQ2hpbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQ2hpbGQoKSkgewogICAgICAgIGlmICghZ2V0Q2hpbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldENoaWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1BheWxvYWQoKSAhPSBvdGhlci5oYXNQYXlsb2FkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1BheWxvYWQoKSkgewogICAgICAgIGlmICghZ2V0UGF5bG9hZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGF5bG9hZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRDaGlsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZENoaWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTGF6eUNoaWxkKCkgIT0gb3RoZXIuaGFzTGF6eUNoaWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0xhenlDaGlsZCgpKSB7CiAgICAgICAgaWYgKCFnZXRMYXp5Q2hpbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldExhenlDaGlsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNFYWdlckNoaWxkKCkgIT0gb3RoZXIuaGFzRWFnZXJDaGlsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNFYWdlckNoaWxkKCkpIHsKICAgICAgICBpZiAoIWdldEVhZ2VyQ2hpbGQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEVhZ2VyQ2hpbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNDaGlsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ0hJTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldENoaWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzUGF5bG9hZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFZTE9BRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGF5bG9hZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQ2hpbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0NISUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZENoaWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0xhenlDaGlsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTEFaWV9DSElMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TGF6eUNoaWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRWFnZXJDaGlsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRUFHRVJfQ0hJTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEVhZ2VyQ2hpbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGlzIHByb3RvIGluY2x1ZGVzIGEgcmVjdXJzaXZlbHkgbmVzdGVkIG1lc3NhZ2UuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRDaGlsZEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRDaGlsZEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0TGF6eUNoaWxkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRFYWdlckNoaWxkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBjaGlsZF8gPSBudWxsOwogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgY2hpbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHBheWxvYWRfID0gbnVsbDsKICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHBheWxvYWRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZENoaWxkXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZENoaWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGxhenlDaGlsZF8gPSBudWxsOwogICAgICAgIGlmIChsYXp5Q2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBsYXp5Q2hpbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBsYXp5Q2hpbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGVhZ2VyQ2hpbGRfID0gbnVsbDsKICAgICAgICBpZiAoZWFnZXJDaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGVhZ2VyQ2hpbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBlYWdlckNoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXModGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRDaGlsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZENoaWxkXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZENoaWxkXyA9IHJlcGVhdGVkQ2hpbGRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRDaGlsZF8gPSByZXBlYXRlZENoaWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNoaWxkXyA9IGNoaWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gY2hpbGRfCiAgICAgICAgICAgICAgOiBjaGlsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucGF5bG9hZF8gPSBwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gcGF5bG9hZF8KICAgICAgICAgICAgICA6IHBheWxvYWRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxhenlDaGlsZF8gPSBsYXp5Q2hpbGRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBsYXp5Q2hpbGRfCiAgICAgICAgICAgICAgOiBsYXp5Q2hpbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmVhZ2VyQ2hpbGRfID0gZWFnZXJDaGlsZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGVhZ2VyQ2hpbGRfCiAgICAgICAgICAgICAgOiBlYWdlckNoaWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0NoaWxkKCkpIHsKICAgICAgICAgIG1lcmdlQ2hpbGQob3RoZXIuZ2V0Q2hpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNQYXlsb2FkKCkpIHsKICAgICAgICAgIG1lcmdlUGF5bG9hZChvdGhlci5nZXRQYXlsb2FkKCkpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRDaGlsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZENoaWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZENoaWxkXyA9IG90aGVyLnJlcGVhdGVkQ2hpbGRfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZENoaWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRDaGlsZF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkQ2hpbGRfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZENoaWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZENoaWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRDaGlsZF8gPSBvdGhlci5yZXBlYXRlZENoaWxkXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkQ2hpbGRGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkQ2hpbGRfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzTGF6eUNoaWxkKCkpIHsKICAgICAgICAgIG1lcmdlTGF6eUNoaWxkKG90aGVyLmdldExhenlDaGlsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0VhZ2VyQ2hpbGQoKSkgewogICAgICAgICAgbWVyZ2VFYWdlckNoaWxkKG90aGVyLmdldEVhZ2VyQ2hpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldENoaWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldFBheWxvYWRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQ2hpbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRDaGlsZF8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRMYXp5Q2hpbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0RWFnZXJDaGlsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlcj4gY2hpbGRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY2hpbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMgZ2V0Q2hpbGQoKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENoaWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBjaGlsZF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDaGlsZCgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgY2hpbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VDaGlsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBjaGlsZF8gIT0gbnVsbCAmJgogICAgICAgICAgICBjaGlsZF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0Q2hpbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNoaWxkXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChjaGlsZF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNoaWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBjaGlsZF8gPSBudWxsOwogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgY2hpbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRDaGlsZEJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRDaGlsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBjaGlsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldENoaWxkT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRDaGlsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0Q2hpbGQoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGNoaWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBheWxvYWRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IHBheWxvYWRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBheWxvYWQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzUGF5bG9hZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBwYXlsb2FkLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFBheWxvYWQoKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcGF5bG9hZF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBwYXlsb2FkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYXlsb2FkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHBheWxvYWRfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHBheWxvYWRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBheWxvYWQoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcGF5bG9hZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VQYXlsb2FkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkgJiYKICAgICAgICAgICAgcGF5bG9hZF8gIT0gbnVsbCAmJgogICAgICAgICAgICBwYXlsb2FkXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRQYXlsb2FkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwYXlsb2FkXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKHBheWxvYWRfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBheWxvYWQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIHBheWxvYWRfID0gbnVsbDsKICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHBheWxvYWRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRQYXlsb2FkQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldFBheWxvYWRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFBheWxvYWRPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcGF5bG9hZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHBheWxvYWRfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcGF5bG9hZF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRQYXlsb2FkRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0UGF5bG9hZCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcGF5bG9hZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcGF5bG9hZEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzPiByZXBlYXRlZENoaWxkXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRDaGlsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZENoaWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzPihyZXBlYXRlZENoaWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXI+IHJlcGVhdGVkQ2hpbGRCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXM+IGdldFJlcGVhdGVkQ2hpbGRMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZENoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkQ2hpbGRfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZENoaWxkQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRDaGlsZF8uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMgZ2V0UmVwZWF0ZWRDaGlsZChpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZENoaWxkXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRDaGlsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRDaGlsZElzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRDaGlsZF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQ2hpbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZENoaWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZENoaWxkXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZENoaWxkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRDaGlsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZENoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZENoaWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZENoaWxkXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQ2hpbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQ2hpbGRJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZENoaWxkKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQ2hpbGRJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRDaGlsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQ2hpbGRJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZENoaWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcz4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZENoaWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZENoaWxkXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQ2hpbGQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZENoaWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZENoaWxkQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkQ2hpbGQoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZENoaWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZENoaWxkXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRDaGlsZEJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRDaGlsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRDaGlsZE9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZENoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQ2hpbGRfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkQ2hpbGRPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZENoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQ2hpbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRDaGlsZF8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyByZXBlYXRlZF9jaGlsZCA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYWRkUmVwZWF0ZWRDaGlsZEJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQ2hpbGRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgcmVwZWF0ZWRfY2hpbGQgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyIGFkZFJlcGVhdGVkQ2hpbGRCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQ2hpbGRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2NoaWxkID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRDaGlsZEJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZENoaWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZENoaWxkRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXBlYXRlZENoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRDaGlsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZENoaWxkXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXBlYXRlZENoaWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZENoaWxkQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMgbGF6eUNoaWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBsYXp5Q2hpbGRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgbGF6eV9jaGlsZCA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbGF6eUNoaWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0xhenlDaGlsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgbGF6eV9jaGlsZCA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGxhenlDaGlsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBnZXRMYXp5Q2hpbGQoKSB7CiAgICAgICAgaWYgKGxhenlDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBsYXp5Q2hpbGRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGxhenlDaGlsZF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBsYXp5Q2hpbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGxhenlfY2hpbGQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TGF6eUNoaWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKGxhenlDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgbGF6eUNoaWxkXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsYXp5Q2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGxhenlfY2hpbGQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TGF6eUNoaWxkKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAobGF6eUNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbGF6eUNoaWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsYXp5Q2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGxhenlfY2hpbGQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VMYXp5Q2hpbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAobGF6eUNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApICYmCiAgICAgICAgICAgIGxhenlDaGlsZF8gIT0gbnVsbCAmJgogICAgICAgICAgICBsYXp5Q2hpbGRfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldExhenlDaGlsZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGF6eUNoaWxkXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsYXp5Q2hpbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAobGF6eUNoaWxkXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgbGF6eV9jaGlsZCA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxhenlDaGlsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgbGF6eUNoaWxkXyA9IG51bGw7CiAgICAgICAgaWYgKGxhenlDaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGxhenlDaGlsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGxhenlDaGlsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgbGF6eV9jaGlsZCA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRMYXp5Q2hpbGRCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0TGF6eUNoaWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIGxhenlfY2hpbGQgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldExhenlDaGlsZE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAobGF6eUNoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGxhenlDaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGxhenlDaGlsZF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBsYXp5Q2hpbGRfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBsYXp5X2NoaWxkID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRMYXp5Q2hpbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGxhenlDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGxhenlDaGlsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TGF6eUNoaWxkKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBsYXp5Q2hpbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGxhenlDaGlsZEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGVhZ2VyQ2hpbGRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IGVhZ2VyQ2hpbGRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZWFnZXJfY2hpbGQgPSA1IFtsYXp5ID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBlYWdlckNoaWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0VhZ2VyQ2hpbGQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGVhZ2VyX2NoaWxkID0gNSBbbGF6eSA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGVhZ2VyQ2hpbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0RWFnZXJDaGlsZCgpIHsKICAgICAgICBpZiAoZWFnZXJDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBlYWdlckNoaWxkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBlYWdlckNoaWxkXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGVhZ2VyQ2hpbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGVhZ2VyX2NoaWxkID0gNSBbbGF6eSA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRFYWdlckNoaWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKGVhZ2VyQ2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVhZ2VyQ2hpbGRfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGVhZ2VyQ2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGVhZ2VyX2NoaWxkID0gNSBbbGF6eSA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRFYWdlckNoaWxkKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZWFnZXJDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVhZ2VyQ2hpbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGVhZ2VyQ2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGVhZ2VyX2NoaWxkID0gNSBbbGF6eSA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUVhZ2VyQ2hpbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAoZWFnZXJDaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSAmJgogICAgICAgICAgICBlYWdlckNoaWxkXyAhPSBudWxsICYmCiAgICAgICAgICAgIGVhZ2VyQ2hpbGRfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEVhZ2VyQ2hpbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVhZ2VyQ2hpbGRfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGVhZ2VyQ2hpbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZWFnZXJDaGlsZF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGVhZ2VyX2NoaWxkID0gNSBbbGF6eSA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckVhZ2VyQ2hpbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGVhZ2VyQ2hpbGRfID0gbnVsbDsKICAgICAgICBpZiAoZWFnZXJDaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGVhZ2VyQ2hpbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBlYWdlckNoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBlYWdlcl9jaGlsZCA9IDUgW2xhenkgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0RWFnZXJDaGlsZEJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRFYWdlckNoaWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGVhZ2VyX2NoaWxkID0gNSBbbGF6eSA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0RWFnZXJDaGlsZE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoZWFnZXJDaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBlYWdlckNoaWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZWFnZXJDaGlsZF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBlYWdlckNoaWxkXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZWFnZXJfY2hpbGQgPSA1IFtsYXp5ID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRFYWdlckNoaWxkRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChlYWdlckNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZWFnZXJDaGlsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0RWFnZXJDaGlsZCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgZWFnZXJDaGlsZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZWFnZXJDaGlsZEJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkVGVzdEFsbFR5cGVzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE5lc3RlZFRlc3RBbGxUeXBlcz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE5lc3RlZFRlc3RBbGxUeXBlcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZFRlc3RBbGxUeXBlcz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRUZXN0QWxsVHlwZXM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdERlcHJlY2F0ZWRGaWVsZHNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkZXByZWNhdGVkX2ludDMyID0gMSBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBkZXByZWNhdGVkIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzLmRlcHJlY2F0ZWRfaW50MzIgaXMgZGVwcmVjYXRlZC4KICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc1CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlcHJlY2F0ZWRJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBib29sZWFuIGhhc0RlcHJlY2F0ZWRJbnQzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkZXByZWNhdGVkX2ludDMyID0gMSBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBkZXByZWNhdGVkIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzLmRlcHJlY2F0ZWRfaW50MzIgaXMgZGVwcmVjYXRlZC4KICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc1CiAgICAgKiBAcmV0dXJuIFRoZSBkZXByZWNhdGVkSW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBpbnQgZ2V0RGVwcmVjYXRlZEludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgPSA0IFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgaXMgZGVwcmVjYXRlZC4KICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc2CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldERlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGRlcHJlY2F0ZWRfcmVwZWF0ZWRfc3RyaW5nID0gNCBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBkZXByZWNhdGVkIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzLmRlcHJlY2F0ZWRfcmVwZWF0ZWRfc3RyaW5nIGlzIGRlcHJlY2F0ZWQuCiAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3NgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgaW50IGdldERlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBkZXByZWNhdGVkX3JlcGVhdGVkX3N0cmluZyA9IDQgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX3JlcGVhdGVkX3N0cmluZyBpcyBkZXByZWNhdGVkLgogICAgICogICAgIFNlZSBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG87bD0xNzYKICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIGphdmEubGFuZy5TdHJpbmcgZ2V0RGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBkZXByZWNhdGVkX3JlcGVhdGVkX3N0cmluZyA9IDQgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX3JlcGVhdGVkX3N0cmluZyBpcyBkZXByZWNhdGVkLgogICAgICogICAgIFNlZSBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG87bD0xNzYKICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0RGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkX21lc3NhZ2UgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9tZXNzYWdlIGlzIGRlcHJlY2F0ZWQuCiAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3NwogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZXByZWNhdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBib29sZWFuIGhhc0RlcHJlY2F0ZWRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkX21lc3NhZ2UgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9tZXNzYWdlIGlzIGRlcHJlY2F0ZWQuCiAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3NwogICAgICogQHJldHVybiBUaGUgZGVwcmVjYXRlZE1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldERlcHJlY2F0ZWRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkX21lc3NhZ2UgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXREZXByZWNhdGVkTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZGVwcmVjYXRlZF9pbnQzMl9pbl9vbmVvZiA9IDIgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX2ludDMyX2luX29uZW9mIGlzIGRlcHJlY2F0ZWQuCiAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3OQogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZXByZWNhdGVkSW50MzJJbk9uZW9mIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIGJvb2xlYW4gaGFzRGVwcmVjYXRlZEludDMySW5PbmVvZigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBkZXByZWNhdGVkX2ludDMyX2luX29uZW9mID0gMiBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBkZXByZWNhdGVkIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzLmRlcHJlY2F0ZWRfaW50MzJfaW5fb25lb2YgaXMgZGVwcmVjYXRlZC4KICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc5CiAgICAgKiBAcmV0dXJuIFRoZSBkZXByZWNhdGVkSW50MzJJbk9uZW9mLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgaW50IGdldERlcHJlY2F0ZWRJbnQzMkluT25lb2YoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcyBuZXN0ZWQgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmVzdGVkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNOZXN0ZWQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzIG5lc3RlZCA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbmVzdGVkLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzIGdldE5lc3RlZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMgbmVzdGVkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHNPckJ1aWxkZXIgZ2V0TmVzdGVkT3JCdWlsZGVyKCk7CgogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcy5PbmVvZkZpZWxkc0Nhc2UgZ2V0T25lb2ZGaWVsZHNDYXNlKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdERlcHJlY2F0ZWRGaWVsZHMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMpCiAgICAgIFRlc3REZXByZWNhdGVkRmllbGRzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0RGVwcmVjYXRlZEZpZWxkcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0RGVwcmVjYXRlZEZpZWxkcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3REZXByZWNhdGVkRmllbGRzKCkgewogICAgICBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0RGVwcmVjYXRlZEZpZWxkcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REZXByZWNhdGVkRmllbGRzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdERlcHJlY2F0ZWRGaWVsZHNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwcml2YXRlIGludCBvbmVvZkZpZWxkc0Nhc2VfID0gMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9uZW9mRmllbGRzXzsKICAgIHB1YmxpYyBlbnVtIE9uZW9mRmllbGRzQ2FzZQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2UuSW50ZXJuYWxPbmVPZkVudW0gewogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgREVQUkVDQVRFRF9JTlQzMl9JTl9PTkVPRigyKSwKICAgICAgT05FT0ZGSUVMRFNfTk9UX1NFVCgwKTsKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CiAgICAgIHByaXZhdGUgT25lb2ZGaWVsZHNDYXNlKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1iZXIgb2YgdGhlIGVudW0gdG8gbG9vayBmb3IuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1iZXIuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgT25lb2ZGaWVsZHNDYXNlIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgT25lb2ZGaWVsZHNDYXNlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDI6IHJldHVybiBERVBSRUNBVEVEX0lOVDMyX0lOX09ORU9GOwogICAgICAgICAgY2FzZSAwOiByZXR1cm4gT05FT0ZGSUVMRFNfTk9UX1NFVDsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgT25lb2ZGaWVsZHNDYXNlCiAgICBnZXRPbmVvZkZpZWxkc0Nhc2UoKSB7CiAgICAgIHJldHVybiBPbmVvZkZpZWxkc0Nhc2UuZm9yTnVtYmVyKAogICAgICAgICAgb25lb2ZGaWVsZHNDYXNlXyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVQUkVDQVRFRF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgZGVwcmVjYXRlZEludDMyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRlcHJlY2F0ZWRfaW50MzIgPSAxIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9pbnQzMiBpcyBkZXByZWNhdGVkLgogICAgICogICAgIFNlZSBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG87bD0xNzUKICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVwcmVjYXRlZEludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBib29sZWFuIGhhc0RlcHJlY2F0ZWRJbnQzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkZXByZWNhdGVkX2ludDMyID0gMSBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBkZXByZWNhdGVkIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzLmRlcHJlY2F0ZWRfaW50MzIgaXMgZGVwcmVjYXRlZC4KICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc1CiAgICAgKiBAcmV0dXJuIFRoZSBkZXByZWNhdGVkSW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgaW50IGdldERlcHJlY2F0ZWRJbnQzMigpIHsKICAgICAgcmV0dXJuIGRlcHJlY2F0ZWRJbnQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVQUkVDQVRFRF9SRVBFQVRFRF9TVFJJTkdfRklFTERfTlVNQkVSID0gNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nXyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgPSA0IFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgaXMgZGVwcmVjYXRlZC4KICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc2CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXREZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdMaXN0KCkgewogICAgICByZXR1cm4gZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGRlcHJlY2F0ZWRfcmVwZWF0ZWRfc3RyaW5nID0gNCBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBkZXByZWNhdGVkIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzLmRlcHJlY2F0ZWRfcmVwZWF0ZWRfc3RyaW5nIGlzIGRlcHJlY2F0ZWQuCiAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3NgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIGludCBnZXREZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdDb3VudCgpIHsKICAgICAgcmV0dXJuIGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgPSA0IFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgaXMgZGVwcmVjYXRlZC4KICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc2CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXREZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmcoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBkZXByZWNhdGVkX3JlcGVhdGVkX3N0cmluZyA9IDQgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX3JlcGVhdGVkX3N0cmluZyBpcyBkZXByZWNhdGVkLgogICAgICogICAgIFNlZSBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG87bD0xNzYKICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldERlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ0J5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERVBSRUNBVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkX21lc3NhZ2UgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9tZXNzYWdlIGlzIGRlcHJlY2F0ZWQuCiAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3NwogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZXByZWNhdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgYm9vbGVhbiBoYXNEZXByZWNhdGVkTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZGVwcmVjYXRlZF9tZXNzYWdlID0gMyBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBkZXByZWNhdGVkIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzLmRlcHJlY2F0ZWRfbWVzc2FnZSBpcyBkZXByZWNhdGVkLgogICAgICogICAgIFNlZSBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG87bD0xNzcKICAgICAqIEByZXR1cm4gVGhlIGRlcHJlY2F0ZWRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZ2V0RGVwcmVjYXRlZE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBkZXByZWNhdGVkTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBkZXByZWNhdGVkTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkX21lc3NhZ2UgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0RGVwcmVjYXRlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBkZXByZWNhdGVkTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBkZXByZWNhdGVkTWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVQUkVDQVRFRF9JTlQzMl9JTl9PTkVPRl9GSUVMRF9OVU1CRVIgPSAyOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBkZXByZWNhdGVkX2ludDMyX2luX29uZW9mID0gMiBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBkZXByZWNhdGVkIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzLmRlcHJlY2F0ZWRfaW50MzJfaW5fb25lb2YgaXMgZGVwcmVjYXRlZC4KICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc5CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRlcHJlY2F0ZWRJbnQzMkluT25lb2YgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIGJvb2xlYW4gaGFzRGVwcmVjYXRlZEludDMySW5PbmVvZigpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRzQ2FzZV8gPT0gMjsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZGVwcmVjYXRlZF9pbnQzMl9pbl9vbmVvZiA9IDIgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX2ludDMyX2luX29uZW9mIGlzIGRlcHJlY2F0ZWQuCiAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3OQogICAgICogQHJldHVybiBUaGUgZGVwcmVjYXRlZEludDMySW5PbmVvZi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBpbnQgZ2V0RGVwcmVjYXRlZEludDMySW5PbmVvZigpIHsKICAgICAgaWYgKG9uZW9mRmllbGRzQ2FzZV8gPT0gMikgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRzXzsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBORVNURURfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcyBuZXN0ZWRfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMgbmVzdGVkID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lc3RlZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc05lc3RlZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMgbmVzdGVkID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBuZXN0ZWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzIGdldE5lc3RlZCgpIHsKICAgICAgcmV0dXJuIG5lc3RlZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBuZXN0ZWRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMgbmVzdGVkID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzT3JCdWlsZGVyIGdldE5lc3RlZE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG5lc3RlZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBuZXN0ZWRfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgZGVwcmVjYXRlZEludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRzQ2FzZV8gPT0gMikgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKAogICAgICAgICAgICAyLCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRzXykpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMywgZ2V0RGVwcmVjYXRlZE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA0LCBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdfLmdldFJhdyhpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg1LCBnZXROZXN0ZWQoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgZGVwcmVjYXRlZEludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRzQ2FzZV8gPT0gMikgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoCiAgICAgICAgICAgICAgMiwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSBvbmVvZkZpZWxkc18pKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgZ2V0RGVwcmVjYXRlZE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ18uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXREZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1LCBnZXROZXN0ZWQoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcyBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzKSBvYmo7CgogICAgICBpZiAoaGFzRGVwcmVjYXRlZEludDMyKCkgIT0gb3RoZXIuaGFzRGVwcmVjYXRlZEludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RlcHJlY2F0ZWRJbnQzMigpKSB7CiAgICAgICAgaWYgKGdldERlcHJlY2F0ZWRJbnQzMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldERlcHJlY2F0ZWRJbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXREZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRGVwcmVjYXRlZE1lc3NhZ2UoKSAhPSBvdGhlci5oYXNEZXByZWNhdGVkTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEZXByZWNhdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXREZXByZWNhdGVkTWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RGVwcmVjYXRlZE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzTmVzdGVkKCkgIT0gb3RoZXIuaGFzTmVzdGVkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc05lc3RlZCgpKSB7CiAgICAgICAgaWYgKCFnZXROZXN0ZWQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE5lc3RlZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0T25lb2ZGaWVsZHNDYXNlKCkuZXF1YWxzKG90aGVyLmdldE9uZW9mRmllbGRzQ2FzZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBzd2l0Y2ggKG9uZW9mRmllbGRzQ2FzZV8pIHsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICBpZiAoZ2V0RGVwcmVjYXRlZEludDMySW5PbmVvZigpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RGVwcmVjYXRlZEludDMySW5PbmVvZigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNEZXByZWNhdGVkSW50MzIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFUFJFQ0FURURfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldERlcHJlY2F0ZWRJbnQzMigpOwogICAgICB9CiAgICAgIGlmIChnZXREZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFUFJFQ0FURURfUkVQRUFURURfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRGVwcmVjYXRlZE1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERFUFJFQ0FURURfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RGVwcmVjYXRlZE1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNOZXN0ZWQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE5FU1RFRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TmVzdGVkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBzd2l0Y2ggKG9uZW9mRmllbGRzQ2FzZV8pIHsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBERVBSRUNBVEVEX0lOVDMyX0lOX09ORU9GX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldERlcHJlY2F0ZWRJbnQzMkluT25lb2YoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REZXByZWNhdGVkRmllbGRzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REZXByZWNhdGVkRmllbGRzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldERlcHJlY2F0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXROZXN0ZWRGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGRlcHJlY2F0ZWRJbnQzMl8gPSAwOwogICAgICAgIGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ18gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgZGVwcmVjYXRlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAoZGVwcmVjYXRlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBkZXByZWNhdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGRlcHJlY2F0ZWRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBuZXN0ZWRfID0gbnVsbDsKICAgICAgICBpZiAobmVzdGVkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbmVzdGVkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgbmVzdGVkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkc0Nhc2VfID0gMDsKICAgICAgICBvbmVvZkZpZWxkc18gPSBudWxsOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RGVwcmVjYXRlZEZpZWxkc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHModGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBidWlsZFBhcnRpYWxPbmVvZnMocmVzdWx0KTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kZXByZWNhdGVkSW50MzJfID0gZGVwcmVjYXRlZEludDMyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ18gPSBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRlcHJlY2F0ZWRNZXNzYWdlXyA9IGRlcHJlY2F0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gZGVwcmVjYXRlZE1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBkZXByZWNhdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubmVzdGVkXyA9IG5lc3RlZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG5lc3RlZF8KICAgICAgICAgICAgICA6IG5lc3RlZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxPbmVvZnMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcyByZXN1bHQpIHsKICAgICAgICByZXN1bHQub25lb2ZGaWVsZHNDYXNlXyA9IG9uZW9mRmllbGRzQ2FzZV87CiAgICAgICAgcmVzdWx0Lm9uZW9mRmllbGRzXyA9IHRoaXMub25lb2ZGaWVsZHNfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNEZXByZWNhdGVkSW50MzIoKSkgewogICAgICAgICAgc2V0RGVwcmVjYXRlZEludDMyKG90aGVyLmdldERlcHJlY2F0ZWRJbnQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5kZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ18gPSBvdGhlci5kZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVEZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICAgICAgZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nXy5hZGRBbGwob3RoZXIuZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0RlcHJlY2F0ZWRNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlRGVwcmVjYXRlZE1lc3NhZ2Uob3RoZXIuZ2V0RGVwcmVjYXRlZE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNOZXN0ZWQoKSkgewogICAgICAgICAgbWVyZ2VOZXN0ZWQob3RoZXIuZ2V0TmVzdGVkKCkpOwogICAgICAgIH0KICAgICAgICBzd2l0Y2ggKG90aGVyLmdldE9uZW9mRmllbGRzQ2FzZSgpKSB7CiAgICAgICAgICBjYXNlIERFUFJFQ0FURURfSU5UMzJfSU5fT05FT0Y6IHsKICAgICAgICAgICAgc2V0RGVwcmVjYXRlZEludDMySW5PbmVvZihvdGhlci5nZXREZXByZWNhdGVkSW50MzJJbk9uZW9mKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgT05FT0ZGSUVMRFNfTk9UX1NFVDogewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBkZXByZWNhdGVkSW50MzJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRzXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZHNDYXNlXyA9IDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXREZXByZWNhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZURlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nXy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0TmVzdGVkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MgogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IG9uZW9mRmllbGRzQ2FzZV8gPSAwOwogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb25lb2ZGaWVsZHNfOwogICAgICBwdWJsaWMgT25lb2ZGaWVsZHNDYXNlCiAgICAgICAgICBnZXRPbmVvZkZpZWxkc0Nhc2UoKSB7CiAgICAgICAgcmV0dXJuIE9uZW9mRmllbGRzQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICAgIG9uZW9mRmllbGRzQ2FzZV8pOwogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mRmllbGRzKCkgewogICAgICAgIG9uZW9mRmllbGRzQ2FzZV8gPSAwOwogICAgICAgIG9uZW9mRmllbGRzXyA9IG51bGw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBkZXByZWNhdGVkSW50MzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRlcHJlY2F0ZWRfaW50MzIgPSAxIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX2ludDMyIGlzIGRlcHJlY2F0ZWQuCiAgICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc1CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVwcmVjYXRlZEludDMyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBib29sZWFuIGhhc0RlcHJlY2F0ZWRJbnQzMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRlcHJlY2F0ZWRfaW50MzIgPSAxIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX2ludDMyIGlzIGRlcHJlY2F0ZWQuCiAgICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc1CiAgICAgICAqIEByZXR1cm4gVGhlIGRlcHJlY2F0ZWRJbnQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBpbnQgZ2V0RGVwcmVjYXRlZEludDMyKCkgewogICAgICAgIHJldHVybiBkZXByZWNhdGVkSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkZXByZWNhdGVkX2ludDMyID0gMSBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9pbnQzMiBpcyBkZXByZWNhdGVkLgogICAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3NQogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlcHJlY2F0ZWRJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgQnVpbGRlciBzZXREZXByZWNhdGVkSW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGRlcHJlY2F0ZWRJbnQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRlcHJlY2F0ZWRfaW50MzIgPSAxIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX2ludDMyIGlzIGRlcHJlY2F0ZWQuCiAgICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc1CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgQnVpbGRlciBjbGVhckRlcHJlY2F0ZWRJbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgZGVwcmVjYXRlZEludDMyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QoZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGRlcHJlY2F0ZWRfcmVwZWF0ZWRfc3RyaW5nID0gNCBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgaXMgZGVwcmVjYXRlZC4KICAgICAgICogICAgIFNlZSBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG87bD0xNzYKICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0RGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nTGlzdCgpIHsKICAgICAgICBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGRlcHJlY2F0ZWRfcmVwZWF0ZWRfc3RyaW5nID0gNCBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgaXMgZGVwcmVjYXRlZC4KICAgICAgICogICAgIFNlZSBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG87bD0xNzYKICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBpbnQgZ2V0RGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgPSA0IFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX3JlcGVhdGVkX3N0cmluZyBpcyBkZXByZWNhdGVkLgogICAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3NgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXREZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmcoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ18uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGRlcHJlY2F0ZWRfcmVwZWF0ZWRfc3RyaW5nID0gNCBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgaXMgZGVwcmVjYXRlZC4KICAgICAgICogICAgIFNlZSBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG87bD0xNzYKICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXREZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGRlcHJlY2F0ZWRfcmVwZWF0ZWRfc3RyaW5nID0gNCBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgaXMgZGVwcmVjYXRlZC4KICAgICAgICogICAgIFNlZSBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG87bD0xNzYKICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgQnVpbGRlciBzZXREZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmcoCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZURlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ18uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgPSA0IFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX3JlcGVhdGVkX3N0cmluZyBpcyBkZXByZWNhdGVkLgogICAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3NgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgQnVpbGRlciBhZGREZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVEZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgPSA0IFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX3JlcGVhdGVkX3N0cmluZyBpcyBkZXByZWNhdGVkLgogICAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3NgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIEJ1aWxkZXIgYWRkQWxsRGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZURlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBkZXByZWNhdGVkX3JlcGVhdGVkX3N0cmluZyA9IDQgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBkZXByZWNhdGVkIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzLmRlcHJlY2F0ZWRfcmVwZWF0ZWRfc3RyaW5nIGlzIGRlcHJlY2F0ZWQuCiAgICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc2CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgQnVpbGRlciBjbGVhckRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZygpIHsKICAgICAgICBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmdfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZGVwcmVjYXRlZF9yZXBlYXRlZF9zdHJpbmcgPSA0IFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX3JlcGVhdGVkX3N0cmluZyBpcyBkZXByZWNhdGVkLgogICAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3NgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSBkZXByZWNhdGVkUmVwZWF0ZWRTdHJpbmcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIEJ1aWxkZXIgYWRkRGVwcmVjYXRlZFJlcGVhdGVkU3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZURlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIGRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZ18uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkTWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gZGVwcmVjYXRlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkX21lc3NhZ2UgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX21lc3NhZ2UgaXMgZGVwcmVjYXRlZC4KICAgICAgICogICAgIFNlZSBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG87bD0xNzcKICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkZXByZWNhdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIGJvb2xlYW4gaGFzRGVwcmVjYXRlZE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZGVwcmVjYXRlZF9tZXNzYWdlID0gMyBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9tZXNzYWdlIGlzIGRlcHJlY2F0ZWQuCiAgICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc3CiAgICAgICAqIEByZXR1cm4gVGhlIGRlcHJlY2F0ZWRNZXNzYWdlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGdldERlcHJlY2F0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChkZXByZWNhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBkZXByZWNhdGVkTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBkZXByZWNhdGVkTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBkZXByZWNhdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkX21lc3NhZ2UgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBCdWlsZGVyIHNldERlcHJlY2F0ZWRNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAoZGVwcmVjYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGRlcHJlY2F0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBkZXByZWNhdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkX21lc3NhZ2UgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBCdWlsZGVyIHNldERlcHJlY2F0ZWRNZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChkZXByZWNhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGRlcHJlY2F0ZWRNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBkZXByZWNhdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkX21lc3NhZ2UgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBCdWlsZGVyIG1lcmdlRGVwcmVjYXRlZE1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChkZXByZWNhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSAmJgogICAgICAgICAgICBkZXByZWNhdGVkTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBkZXByZWNhdGVkTWVzc2FnZV8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXREZXByZWNhdGVkTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZGVwcmVjYXRlZE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGRlcHJlY2F0ZWRNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGRlcHJlY2F0ZWRNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkX21lc3NhZ2UgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGVwcmVjYXRlZE1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGRlcHJlY2F0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKGRlcHJlY2F0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZGVwcmVjYXRlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBkZXByZWNhdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkX21lc3NhZ2UgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0RGVwcmVjYXRlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0RGVwcmVjYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBkZXByZWNhdGVkX21lc3NhZ2UgPSAzIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldERlcHJlY2F0ZWRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChkZXByZWNhdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBkZXByZWNhdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGRlcHJlY2F0ZWRNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZGVwcmVjYXRlZE1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGRlcHJlY2F0ZWRfbWVzc2FnZSA9IDMgW2RlcHJlY2F0ZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RGVwcmVjYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGRlcHJlY2F0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZGVwcmVjYXRlZE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldERlcHJlY2F0ZWRNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBkZXByZWNhdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZGVwcmVjYXRlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGRlcHJlY2F0ZWRfaW50MzJfaW5fb25lb2YgPSAyIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX2ludDMyX2luX29uZW9mIGlzIGRlcHJlY2F0ZWQuCiAgICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc5CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGVwcmVjYXRlZEludDMySW5PbmVvZiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIGJvb2xlYW4gaGFzRGVwcmVjYXRlZEludDMySW5PbmVvZigpIHsKICAgICAgICByZXR1cm4gb25lb2ZGaWVsZHNDYXNlXyA9PSAyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBkZXByZWNhdGVkX2ludDMyX2luX29uZW9mID0gMiBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9pbnQzMl9pbl9vbmVvZiBpcyBkZXByZWNhdGVkLgogICAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3OQogICAgICAgKiBAcmV0dXJuIFRoZSBkZXByZWNhdGVkSW50MzJJbk9uZW9mLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBpbnQgZ2V0RGVwcmVjYXRlZEludDMySW5PbmVvZigpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZHNDYXNlXyA9PSAyKSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSBvbmVvZkZpZWxkc187CiAgICAgICAgfQogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBkZXByZWNhdGVkX2ludDMyX2luX29uZW9mID0gMiBbZGVwcmVjYXRlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQGRlcHJlY2F0ZWQgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMuZGVwcmVjYXRlZF9pbnQzMl9pbl9vbmVvZiBpcyBkZXByZWNhdGVkLgogICAgICAgKiAgICAgU2VlIGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdC5wcm90bztsPTE3OQogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRlcHJlY2F0ZWRJbnQzMkluT25lb2YgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIEJ1aWxkZXIgc2V0RGVwcmVjYXRlZEludDMySW5PbmVvZihpbnQgdmFsdWUpIHsKCiAgICAgICAgb25lb2ZGaWVsZHNDYXNlXyA9IDI7CiAgICAgICAgb25lb2ZGaWVsZHNfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGRlcHJlY2F0ZWRfaW50MzJfaW5fb25lb2YgPSAyIFtkZXByZWNhdGVkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAZGVwcmVjYXRlZCBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcy5kZXByZWNhdGVkX2ludDMyX2luX29uZW9mIGlzIGRlcHJlY2F0ZWQuCiAgICAgICAqICAgICBTZWUgZ29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvO2w9MTc5CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgQnVpbGRlciBjbGVhckRlcHJlY2F0ZWRJbnQzMkluT25lb2YoKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRzQ2FzZV8gPT0gMikgewogICAgICAgICAgb25lb2ZGaWVsZHNDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkc18gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMgbmVzdGVkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzT3JCdWlsZGVyPiBuZXN0ZWRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcyBuZXN0ZWQgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuZXN0ZWQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmVzdGVkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzIG5lc3RlZCA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBuZXN0ZWQuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcyBnZXROZXN0ZWQoKSB7CiAgICAgICAgaWYgKG5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBuZXN0ZWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbmVzdGVkXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG5lc3RlZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcyBuZXN0ZWQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE5lc3RlZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzIHZhbHVlKSB7CiAgICAgICAgaWYgKG5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgbmVzdGVkXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBuZXN0ZWRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMgbmVzdGVkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXROZXN0ZWQoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG5lc3RlZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbmVzdGVkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzIG5lc3RlZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VOZXN0ZWQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcyB2YWx1ZSkgewogICAgICAgIGlmIChuZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkgJiYKICAgICAgICAgICAgbmVzdGVkXyAhPSBudWxsICYmCiAgICAgICAgICAgIG5lc3RlZF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXROZXN0ZWRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG5lc3RlZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgbmVzdGVkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG5lc3RlZF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRGaWVsZHMgbmVzdGVkID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck5lc3RlZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgbmVzdGVkXyA9IG51bGw7CiAgICAgICAgaWYgKG5lc3RlZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG5lc3RlZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG5lc3RlZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcyBuZXN0ZWQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzLkJ1aWxkZXIgZ2V0TmVzdGVkQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE5lc3RlZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzIG5lc3RlZCA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHNPckJ1aWxkZXIgZ2V0TmVzdGVkT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChuZXN0ZWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbmVzdGVkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbmVzdGVkXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbmVzdGVkXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcyBuZXN0ZWQgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXROZXN0ZWRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG5lc3RlZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkRmllbGRzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TmVzdGVkKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBuZXN0ZWRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG5lc3RlZEJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkRmllbGRzKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZEZpZWxkcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRGaWVsZHMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3REZXByZWNhdGVkRmllbGRzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3REZXByZWNhdGVkRmllbGRzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdERlcHJlY2F0ZWRGaWVsZHMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RGVwcmVjYXRlZEZpZWxkcz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RGVwcmVjYXRlZEZpZWxkcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZEZpZWxkcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIGludGVyZmFjZSBUZXN0RGVwcmVjYXRlZE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZE1lc3NhZ2V9CiAgICovCiAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdERlcHJlY2F0ZWRNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REZXByZWNhdGVkTWVzc2FnZSkKICAgICAgVGVzdERlcHJlY2F0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0RGVwcmVjYXRlZE1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdERlcHJlY2F0ZWRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdERlcHJlY2F0ZWRNZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3REZXByZWNhdGVkTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REZXByZWNhdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REZXByZWNhdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkTWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRNZXNzYWdlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REZXByZWNhdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RGVwcmVjYXRlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RGVwcmVjYXRlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRNZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkTWVzc2FnZSh0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdERlcHJlY2F0ZWRNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkTWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdERlcHJlY2F0ZWRNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REZXByZWNhdGVkTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RGVwcmVjYXRlZE1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdERlcHJlY2F0ZWRNZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdERlcHJlY2F0ZWRNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdERlcHJlY2F0ZWRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3REZXByZWNhdGVkTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RGVwcmVjYXRlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBGb3JlaWduTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBjID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjLgogICAgICovCiAgICBpbnQgZ2V0QygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGQuCiAgICAgKi8KICAgIGludCBnZXREKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogRGVmaW5lIHRoZXNlIGFmdGVyIFRlc3RBbGxUeXBlcyB0byBtYWtlIHN1cmUgdGhlIGNvbXBpbGVyIGNhbiBoYW5kbGUKICAgKiB0aGF0LgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGb3JlaWduTWVzc2FnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSkKICAgICAgRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEZvcmVpZ25NZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIEZvcmVpZ25NZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgRm9yZWlnbk1lc3NhZ2UoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgRm9yZWlnbk1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb3JlaWduTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ19GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgY18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBjID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNDKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0QygpIHsKICAgICAgcmV0dXJuIGNfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgaW50IGRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEQoKSB7CiAgICAgIHJldHVybiBkXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyLCBkXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgY18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMiwgZF8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKGhhc0MoKSAhPSBvdGhlci5oYXNDKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0MoKSkgewogICAgICAgIGlmIChnZXRDKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0QoKSAhPSBvdGhlci5oYXNEKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0QoKSkgewogICAgICAgIGlmIChnZXREKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzQygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QygpOwogICAgICB9CiAgICAgIGlmIChoYXNEKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogRGVmaW5lIHRoZXNlIGFmdGVyIFRlc3RBbGxUeXBlcyB0byBtYWtlIHN1cmUgdGhlIGNvbXBpbGVyIGNhbiBoYW5kbGUKICAgICAqIHRoYXQuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRm9yZWlnbk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGNfID0gMDsKICAgICAgICBkXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNfID0gY187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZF8gPSBkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzQygpKSB7CiAgICAgICAgICBzZXRDKG90aGVyLmdldEMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEKCkpIHsKICAgICAgICAgIHNldEQob3RoZXIuZ2V0RCgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBjXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICBkXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGMgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGMgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRDKCkgewogICAgICAgIHJldHVybiBjXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYyA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDKGludCB2YWx1ZSkgewoKICAgICAgICBjXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEQoKSB7CiAgICAgICAgcmV0dXJuIGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEQoaW50IHZhbHVlKSB7CgogICAgICAgIGRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgZF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvcmVpZ25NZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZvcmVpZ25NZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgRm9yZWlnbk1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb3JlaWduTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb3JlaWduTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RSZXNlcnZlZEZpZWxkc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVzZXJ2ZWRGaWVsZHMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXNlcnZlZEZpZWxkc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RSZXNlcnZlZEZpZWxkcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVzZXJ2ZWRGaWVsZHMpCiAgICAgIFRlc3RSZXNlcnZlZEZpZWxkc09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFJlc2VydmVkRmllbGRzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RSZXNlcnZlZEZpZWxkcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RSZXNlcnZlZEZpZWxkcygpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0UmVzZXJ2ZWRGaWVsZHMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVzZXJ2ZWRGaWVsZHNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVzZXJ2ZWRGaWVsZHNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXNlcnZlZEZpZWxkcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVzZXJ2ZWRGaWVsZHMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVzZXJ2ZWRGaWVsZHMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzKSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXNlcnZlZEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXNlcnZlZEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVzZXJ2ZWRGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXNlcnZlZEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXNlcnZlZEZpZWxkcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVzZXJ2ZWRGaWVsZHMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXNlcnZlZEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXNlcnZlZEZpZWxkc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXNlcnZlZEZpZWxkcykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXNlcnZlZEZpZWxkc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVzZXJ2ZWRGaWVsZHNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlc2VydmVkRmllbGRzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXNlcnZlZEZpZWxkcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlc2VydmVkRmllbGRzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXNlcnZlZEZpZWxkcyBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXNlcnZlZEZpZWxkcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXNlcnZlZEZpZWxkcyByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVzZXJ2ZWRGaWVsZHModGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXNlcnZlZEZpZWxkcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVzZXJ2ZWRGaWVsZHMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVzZXJ2ZWRGaWVsZHMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVzZXJ2ZWRGaWVsZHMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXNlcnZlZEZpZWxkcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlc2VydmVkRmllbGRzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVzZXJ2ZWRGaWVsZHMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVzZXJ2ZWRGaWVsZHMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlc2VydmVkRmllbGRzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RSZXNlcnZlZEZpZWxkcz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RSZXNlcnZlZEZpZWxkcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXNlcnZlZEZpZWxkcz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVzZXJ2ZWRGaWVsZHM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlc2VydmVkRmllbGRzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEFsbEV4dGVuc2lvbnNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLgogICAgICAgICAgRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXI8VGVzdEFsbEV4dGVuc2lvbnM+IHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0QWxsRXh0ZW5zaW9ucyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVNZXNzYWdlPAogICAgICAgIFRlc3RBbGxFeHRlbnNpb25zPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMpCiAgICAgIFRlc3RBbGxFeHRlbnNpb25zT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0QWxsRXh0ZW5zaW9ucy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0QWxsRXh0ZW5zaW9ucyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0QWxsRXh0ZW5zaW9ucygpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0QWxsRXh0ZW5zaW9ucygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxFeHRlbnNpb25zX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbEV4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLkV4dGVuZGFibGVNZXNzYWdlPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnM+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDUzNjg3MDkxMiwgb3V0cHV0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplKCk7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucykgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLCBCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxFeHRlbnNpb25zX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxFeHRlbnNpb25zX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLCBUeXBlPiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBhZGRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VD4gQnVpbGRlciBjbGVhckV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywgVD4gZXh0ZW5zaW9uKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRXh0ZW5zaW9uKGV4dGVuc2lvbik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VFeHRlbnNpb25GaWVsZHMob3RoZXIpOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEFsbEV4dGVuc2lvbnM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEFsbEV4dGVuc2lvbnM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0QWxsRXh0ZW5zaW9ucyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RBbGxFeHRlbnNpb25zPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RBbGxFeHRlbnNpb25zPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgT3B0aW9uYWxHcm91cF9leHRlbnNpb25PckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuT3B0aW9uYWxHcm91cF9leHRlbnNpb24pCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNBKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICovCiAgICBpbnQgZ2V0QSgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKQogICAgICBPcHRpb25hbEdyb3VwX2V4dGVuc2lvbk9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgT3B0aW9uYWxHcm91cF9leHRlbnNpb24ubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgT3B0aW9uYWxHcm91cF9leHRlbnNpb24oY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBPcHRpb25hbEdyb3VwX2V4dGVuc2lvbigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBPcHRpb25hbEdyb3VwX2V4dGVuc2lvbigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT3B0aW9uYWxHcm91cF9leHRlbnNpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBX0ZJRUxEX05VTUJFUiA9IDE3OwogICAgcHJpdmF0ZSBpbnQgYV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRBKCkgewogICAgICByZXR1cm4gYV87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxNywgYV8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDE3LCBhXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKSBvYmo7CgogICAgICBpZiAoaGFzQSgpICE9IG90aGVyLmhhc0EoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQSgpKSB7CiAgICAgICAgaWYgKGdldEEoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRBKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBBX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT3B0aW9uYWxHcm91cF9leHRlbnNpb25PckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT3B0aW9uYWxHcm91cF9leHRlbnNpb25fZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT3B0aW9uYWxHcm91cF9leHRlbnNpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbi5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT3B0aW9uYWxHcm91cF9leHRlbnNpb24ubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGFfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT3B0aW9uYWxHcm91cF9leHRlbnNpb25fZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuYV8gPSBhXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT3B0aW9uYWxHcm91cF9leHRlbnNpb24pIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT3B0aW9uYWxHcm91cF9leHRlbnNpb24pb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzQSgpKSB7CiAgICAgICAgICBzZXRBKG90aGVyLmdldEEoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTM2OiB7CiAgICAgICAgICAgICAgICBhXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzNgogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBhXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgIHJldHVybiBhXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBhIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QShpbnQgdmFsdWUpIHsKCiAgICAgICAgYV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgYV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgT3B0aW9uYWxHcm91cF9leHRlbnNpb24gcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPcHRpb25hbEdyb3VwX2V4dGVuc2lvbj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPcHRpb25hbEdyb3VwX2V4dGVuc2lvbj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDQ3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gNDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgaW50IGdldEEoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuUmVwZWF0ZWRHcm91cF9leHRlbnNpb259CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBSZXBlYXRlZEdyb3VwX2V4dGVuc2lvbiBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbikKICAgICAgUmVwZWF0ZWRHcm91cF9leHRlbnNpb25PckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgUmVwZWF0ZWRHcm91cF9leHRlbnNpb24oKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgUmVwZWF0ZWRHcm91cF9leHRlbnNpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQV9GSUVMRF9OVU1CRVIgPSA0NzsKICAgIHByaXZhdGUgaW50IGFfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDQ3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDQ3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0QSgpIHsKICAgICAgcmV0dXJuIGFfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNDcsIGFfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg0NywgYV8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24pKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbikgb2JqOwoKICAgICAgaWYgKGhhc0EoKSAhPSBvdGhlci5oYXNBKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgIGlmIChnZXRBKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzQSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuUmVwZWF0ZWRHcm91cF9leHRlbnNpb259CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24uY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24uQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBhXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbiBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbiBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmFfID0gYV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0EoKSkgewogICAgICAgICAgc2V0QShvdGhlci5nZXRBKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDM3NjogewogICAgICAgICAgICAgICAgYV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNzYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgYV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDQ3OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA0Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0QSgpIHsKICAgICAgICByZXR1cm4gYV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA0Nzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEEoaW50IHZhbHVlKSB7CgogICAgICAgIGFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gNDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGFfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuUmVwZWF0ZWRHcm91cF9leHRlbnNpb24pCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXBlYXRlZEdyb3VwX2V4dGVuc2lvbj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxSZXBlYXRlZEdyb3VwX2V4dGVuc2lvbj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVwZWF0ZWRHcm91cF9leHRlbnNpb24+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVwZWF0ZWRHcm91cF9leHRlbnNpb24+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLgogICAgICAgICAgRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXI8VGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucz4gewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNBKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgKi8KICAgIGludCBnZXRBKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGIgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRCTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGIgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGIuCiAgICAgKi8KICAgIGludCBnZXRCQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBiID0gMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0QihpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVNZXNzYWdlPAogICAgICAgIFRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnM+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zKQogICAgICBUZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zKCkgewogICAgICBiXyA9IGVtcHR5SW50TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBhXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRBKCkgewogICAgICByZXR1cm4gYV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQl9GSUVMRF9OVU1CRVIgPSAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBiXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgYiA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgYi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldEJMaXN0KCkgewogICAgICByZXR1cm4gYl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgYiA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgYi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRCQ291bnQoKSB7CiAgICAgIHJldHVybiBiXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgYiA9IDM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBiIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRCKGludCBpbmRleCkgewogICAgICByZXR1cm4gYl8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5FeHRlbmRhYmxlTWVzc2FnZTxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnM+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGFfKTsKICAgICAgfQogICAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCgzLCBvdXRwdXQpOwogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMigzLCBiXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDUsIG91dHB1dCk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIGFfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRCTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldEJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHNpemUgKz0gZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplKCk7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucykgb2JqOwoKICAgICAgaWYgKGhhc0EoKSAhPSBvdGhlci5oYXNBKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgIGlmIChnZXRBKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRCTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RXh0ZW5zaW9uRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldEV4dGVuc2lvbkZpZWxkcygpKSkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEEoKTsKICAgICAgfQogICAgICBpZiAoZ2V0QkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Qkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSBoYXNoRmllbGRzKGhhc2gsIGdldEV4dGVuc2lvbkZpZWxkcygpKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMsIEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgYV8gPSAwOwogICAgICAgIGJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnModGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmFfID0gYV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICBiXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQuYl8gPSBiXzsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zLCBUeXBlPiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucywgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFQ+IEJ1aWxkZXIgY2xlYXJFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucywgVD4gZXh0ZW5zaW9uKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRXh0ZW5zaW9uKGV4dGVuc2lvbik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0EoKSkgewogICAgICAgICAgc2V0QShvdGhlci5nZXRBKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLmJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBiXyA9IG90aGVyLmJfOwogICAgICAgICAgICBiXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZUJJc011dGFibGUoKTsKICAgICAgICAgICAgYl8uYWRkQWxsKG90aGVyLmJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlRXh0ZW5zaW9uRmllbGRzKG90aGVyKTsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgYV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAyOTogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlQklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgYl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI5CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZUJJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgYl8uYWRkSW50KGlucHV0LnJlYWRGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGFfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgIHJldHVybiBhXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRBKGludCB2YWx1ZSkgewoKICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGFfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgYl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFiXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgYl8gPSBtYWtlTXV0YWJsZUNvcHkoYl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUJJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFiXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgYl8gPSBtYWtlTXV0YWJsZUNvcHkoYl8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIGIgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgYi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldEJMaXN0KCkgewogICAgICAgIGJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gYl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgYiA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBiLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRCQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBiID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBiIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0QihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gYl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBiID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBiIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZUJJc011dGFibGUoKTsKICAgICAgICBiXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgYiA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRCKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVCSXNNdXRhYmxlKCk7CiAgICAgICAgYl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgYiA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBiIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsQigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZUJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgYl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBiID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQigpIHsKICAgICAgICBiXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9ucz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENfRklFTERfTlVNQkVSID0gMjsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMsCiAgICAgICAgamF2YS5sYW5nLkludGVnZXI+IGMgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAwLAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgICBudWxsKTsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERfRklFTERfTlVNQkVSID0gNDsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnMsCiAgICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+PiBkID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMSwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgICAgbnVsbCk7CiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RHcm91cE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0R3JvdXApCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxncm91cCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxHcm91cCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsZ3JvdXAuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAgZ2V0T3B0aW9uYWxHcm91cCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cE9yQnVpbGRlciBnZXRPcHRpb25hbEdyb3VwT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEZvcmVpZ25FbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEZvcmVpZ25FbnVtKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIGdldE9wdGlvbmFsRm9yZWlnbkVudW0oKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEdyb3VwfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEdyb3VwIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RHcm91cCkKICAgICAgVGVzdEdyb3VwT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0R3JvdXAubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdEdyb3VwKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdEdyb3VwKCkgewogICAgICBvcHRpb25hbEZvcmVpZ25FbnVtXyA9IDQ7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdEdyb3VwKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEdyb3VwX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgT3B0aW9uYWxHcm91cE9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RHcm91cC5PcHRpb25hbEdyb3VwKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE3OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzQSgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIGludCBnZXRBKCk7CgogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogZmFzdCB0YWJsZSBzaXplIG11c3QgYmUgYXQgbGVhc3QgMTYsIGZvciB0aGlzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB6eiA9IDg5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB6eiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc1p6KCk7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBmYXN0IHRhYmxlIHNpemUgbXVzdCBiZSBhdCBsZWFzdCAxNiwgZm9yIHRoaXMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHp6ID0gODk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB6ei4KICAgICAgICovCiAgICAgIGludCBnZXRaeigpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBPcHRpb25hbEdyb3VwIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCkKICAgICAgICBPcHRpb25hbEdyb3VwT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgT3B0aW9uYWxHcm91cC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIE9wdGlvbmFsR3JvdXAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBPcHRpb25hbEdyb3VwKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE9wdGlvbmFsR3JvdXAoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RHcm91cF9PcHRpb25hbEdyb3VwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RHcm91cF9PcHRpb25hbEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFfRklFTERfTlVNQkVSID0gMTc7CiAgICAgIHByaXZhdGUgaW50IGFfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEEoKSB7CiAgICAgICAgcmV0dXJuIGFfOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBaWl9GSUVMRF9OVU1CRVIgPSA4OTsKICAgICAgcHJpdmF0ZSBpbnQgenpfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGZhc3QgdGFibGUgc2l6ZSBtdXN0IGJlIGF0IGxlYXN0IDE2LCBmb3IgdGhpcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgenogPSA4OTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgenogZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNaeigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGZhc3QgdGFibGUgc2l6ZSBtdXN0IGJlIGF0IGxlYXN0IDE2LCBmb3IgdGhpcwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgenogPSA4OTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHp6LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFp6KCkgewogICAgICAgIHJldHVybiB6el87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxNywgYV8pOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDg5LCB6el8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxNywgYV8pOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg4OSwgenpfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwKSBvYmo7CgogICAgICAgIGlmIChoYXNBKCkgIT0gb3RoZXIuaGFzQSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgICAgaWYgKGdldEEoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEEoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzWnooKSAhPSBvdGhlci5oYXNaeigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc1p6KCkpIHsKICAgICAgICAgIGlmIChnZXRaeigpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0WnooKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBKCk7CiAgICAgICAgfQogICAgICAgIGlmIChoYXNaeigpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBaWl9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRaeigpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RHcm91cC5PcHRpb25hbEdyb3VwfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCkKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXBPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEdyb3VwX09wdGlvbmFsR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RHcm91cF9PcHRpb25hbEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBhXyA9IDA7CiAgICAgICAgICB6el8gPSAwOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0R3JvdXBfT3B0aW9uYWxHcm91cF9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCBidWlsZCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LmFfID0gYV87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC56el8gPSB6el87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXApb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc0EoKSkgewogICAgICAgICAgICBzZXRBKG90aGVyLmdldEEoKSk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAob3RoZXIuaGFzWnooKSkgewogICAgICAgICAgICBzZXRaeihvdGhlci5nZXRaeigpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMTM2OiB7CiAgICAgICAgICAgICAgICAgIGFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM2CiAgICAgICAgICAgICAgICBjYXNlIDcxMjogewogICAgICAgICAgICAgICAgICB6el8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA3MTIKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IGFfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTc7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxNzs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgICAgcmV0dXJuIGFfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTc7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYSB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEEoaW50IHZhbHVlKSB7CgogICAgICAgICAgYV8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxNzs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQSgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIGFfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGludCB6el8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogZmFzdCB0YWJsZSBzaXplIG11c3QgYmUgYXQgbGVhc3QgMTYsIGZvciB0aGlzCiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICoKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB6eiA9IDg5OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHp6IGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzWnooKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogZmFzdCB0YWJsZSBzaXplIG11c3QgYmUgYXQgbGVhc3QgMTYsIGZvciB0aGlzCiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICoKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB6eiA9IDg5OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSB6ei4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRaeigpIHsKICAgICAgICAgIHJldHVybiB6el87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogZmFzdCB0YWJsZSBzaXplIG11c3QgYmUgYXQgbGVhc3QgMTYsIGZvciB0aGlzCiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICoKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiB6eiA9IDg5OzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHp6IHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0WnooaW50IHZhbHVlKSB7CgogICAgICAgICAgenpfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIGZhc3QgdGFibGUgc2l6ZSBtdXN0IGJlIGF0IGxlYXN0IDE2LCBmb3IgdGhpcwogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgenogPSA4OTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyWnooKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICB6el8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RHcm91cC5PcHRpb25hbEdyb3VwKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE9wdGlvbmFsR3JvdXA+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxPcHRpb25hbEdyb3VwPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE9wdGlvbmFsR3JvdXAgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPcHRpb25hbEdyb3VwPiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T3B0aW9uYWxHcm91cD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMR1JPVVBfRklFTERfTlVNQkVSID0gMTY7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAgb3B0aW9uYWxHcm91cF87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbGdyb3VwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxHcm91cCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsZ3JvdXAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwIGdldE9wdGlvbmFsR3JvdXAoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEdyb3VwXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsR3JvdXBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXBPckJ1aWxkZXIgZ2V0T3B0aW9uYWxHcm91cE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsR3JvdXBfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxHcm91cF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRk9SRUlHTl9FTlVNX0ZJRUxEX05VTUJFUiA9IDIyOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxGb3JlaWduRW51bV8gPSA0OwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEZvcmVpZ25FbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZvcmVpZ25FbnVtKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIGdldE9wdGlvbmFsRm9yZWlnbkVudW0oKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIob3B0aW9uYWxGb3JlaWduRW51bV8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLkZPUkVJR05fRk9PIDogcmVzdWx0OwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlR3JvdXAoMTYsIGdldE9wdGlvbmFsR3JvdXAoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgyMiwgb3B0aW9uYWxGb3JlaWduRW51bV8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlR3JvdXBTaXplKDE2LCBnZXRPcHRpb25hbEdyb3VwKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSgyMiwgb3B0aW9uYWxGb3JlaWduRW51bV8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cCkgb2JqOwoKICAgICAgaWYgKGhhc09wdGlvbmFsR3JvdXAoKSAhPSBvdGhlci5oYXNPcHRpb25hbEdyb3VwKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsR3JvdXAoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxHcm91cCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxHcm91cCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEZvcmVpZ25FbnVtKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxGb3JlaWduRW51bSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEZvcmVpZ25FbnVtKCkpIHsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduRW51bV8gIT0gb3RoZXIub3B0aW9uYWxGb3JlaWduRW51bV8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNPcHRpb25hbEdyb3VwKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTEdST1VQX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEdyb3VwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduRW51bSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRk9SRUlHTl9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBvcHRpb25hbEZvcmVpZ25FbnVtXzsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cCBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0R3JvdXB9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0R3JvdXApCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXBPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEdyb3VwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RHcm91cF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRPcHRpb25hbEdyb3VwRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbEdyb3VwXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEdyb3VwQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxHcm91cEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxGb3JlaWduRW51bV8gPSA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0R3JvdXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cCh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEdyb3VwXyA9IG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbEdyb3VwXwogICAgICAgICAgICAgIDogb3B0aW9uYWxHcm91cEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxGb3JlaWduRW51bV8gPSBvcHRpb25hbEZvcmVpZ25FbnVtXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsR3JvdXAoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbEdyb3VwKG90aGVyLmdldE9wdGlvbmFsR3JvdXAoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEZvcmVpZ25FbnVtKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsRm9yZWlnbkVudW0ob3RoZXIuZ2V0T3B0aW9uYWxGb3JlaWduRW51bSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMzE6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRHcm91cCgxNiwKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEdyb3VwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzEKICAgICAgICAgICAgICBjYXNlIDE3NjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMjIsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBvcHRpb25hbEZvcmVpZ25FbnVtXyA9IHRtcFJhdzsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE3NgogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAgb3B0aW9uYWxHcm91cF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cE9yQnVpbGRlcj4gb3B0aW9uYWxHcm91cEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDE2IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxncm91cCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEdyb3VwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDE2IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsZ3JvdXAuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCBnZXRPcHRpb25hbEdyb3VwKCkgewogICAgICAgIGlmIChvcHRpb25hbEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsR3JvdXBfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxHcm91cF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEdyb3VwQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDE2IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEdyb3VwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxHcm91cF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxHcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxHcm91cCgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxHcm91cChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxHcm91cF8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbEdyb3VwXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsR3JvdXBCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsR3JvdXBfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxHcm91cF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxHcm91cCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb3B0aW9uYWxHcm91cF8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEdyb3VwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxHcm91cEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwLkJ1aWxkZXIgZ2V0T3B0aW9uYWxHcm91cEJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbEdyb3VwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTYgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwT3JCdWlsZGVyIGdldE9wdGlvbmFsR3JvdXBPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsR3JvdXBfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEdyb3VwXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxNiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAuT3B0aW9uYWxHcm91cC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsR3JvdXBGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEdyb3VwQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cC5PcHRpb25hbEdyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwLk9wdGlvbmFsR3JvdXBPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEdyb3VwKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbEdyb3VwXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbEdyb3VwQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsRm9yZWlnbkVudW1fID0gNDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGb3JlaWduRW51bSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsRm9yZWlnbkVudW0oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZm9yZWlnbl9lbnVtID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ25FbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBnZXRPcHRpb25hbEZvcmVpZ25FbnVtKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIob3B0aW9uYWxGb3JlaWduRW51bV8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uRk9SRUlHTl9GT08gOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxGb3JlaWduRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRm9yZWlnbkVudW0ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9wdGlvbmFsRm9yZWlnbkVudW1fID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9mb3JlaWduX2VudW0gPSAyMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxGb3JlaWduRW51bSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb3B0aW9uYWxGb3JlaWduRW51bV8gPSA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RHcm91cCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEdyb3VwKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXAoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEdyb3VwPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RHcm91cD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RHcm91cCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RHcm91cD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0R3JvdXA+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEdyb3VwRXh0ZW5zaW9uT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RHcm91cEV4dGVuc2lvbikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxUZXN0R3JvdXBFeHRlbnNpb24+IHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEdyb3VwRXh0ZW5zaW9ufQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEdyb3VwRXh0ZW5zaW9uIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZU1lc3NhZ2U8CiAgICAgICAgVGVzdEdyb3VwRXh0ZW5zaW9uPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEdyb3VwRXh0ZW5zaW9uKQogICAgICBUZXN0R3JvdXBFeHRlbnNpb25PckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RHcm91cEV4dGVuc2lvbi5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0R3JvdXBFeHRlbnNpb24oY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXBFeHRlbnNpb24sID8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RHcm91cEV4dGVuc2lvbigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0R3JvdXBFeHRlbnNpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0R3JvdXBFeHRlbnNpb25fZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0R3JvdXBFeHRlbnNpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXBFeHRlbnNpb24uQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuRXh0ZW5kYWJsZU1lc3NhZ2U8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXBFeHRlbnNpb24+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDUzNjg3MDkxMiwgb3V0cHV0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplKCk7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwRXh0ZW5zaW9uKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbikgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXBFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwRXh0ZW5zaW9uIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXBFeHRlbnNpb24gcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwRXh0ZW5zaW9uIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwRXh0ZW5zaW9uIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RHcm91cEV4dGVuc2lvbn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwRXh0ZW5zaW9uLCBCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0R3JvdXBFeHRlbnNpb24pCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXBFeHRlbnNpb25PckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEdyb3VwRXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RHcm91cEV4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXBFeHRlbnNpb24uQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbi5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RHcm91cEV4dGVuc2lvbl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXBFeHRlbnNpb24gYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXBFeHRlbnNpb24gcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXBFeHRlbnNpb24gcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwRXh0ZW5zaW9uKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiwgVHlwZT4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXBFeHRlbnNpb24sIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VD4gQnVpbGRlciBjbGVhckV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0R3JvdXBFeHRlbnNpb24sIFQ+IGV4dGVuc2lvbikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckV4dGVuc2lvbihleHRlbnNpb24pOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwRXh0ZW5zaW9uKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0R3JvdXBFeHRlbnNpb24pCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RHcm91cEV4dGVuc2lvbikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwRXh0ZW5zaW9uIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEdyb3VwRXh0ZW5zaW9uKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RHcm91cEV4dGVuc2lvbj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0R3JvdXBFeHRlbnNpb24+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0R3JvdXBFeHRlbnNpb24gcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0R3JvdXBFeHRlbnNpb24+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEdyb3VwRXh0ZW5zaW9uPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3ROZXN0ZWRFeHRlbnNpb25PckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEV4dGVuc2lvbikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEV4dGVuc2lvbn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3ROZXN0ZWRFeHRlbnNpb24gZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEV4dGVuc2lvbikKICAgICAgVGVzdE5lc3RlZEV4dGVuc2lvbk9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE5lc3RlZEV4dGVuc2lvbi5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TmVzdGVkRXh0ZW5zaW9uKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE5lc3RlZEV4dGVuc2lvbigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TmVzdGVkRXh0ZW5zaW9uKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEV4dGVuc2lvbl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRFeHRlbnNpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIE9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEV4dGVuc2lvbi5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbikKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc0EoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgICAqLwogICAgICBpbnQgZ2V0QSgpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9ufQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKQogICAgICAgIE9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgT3B0aW9uYWxHcm91cF9leHRlbnNpb24ubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBPcHRpb25hbEdyb3VwX2V4dGVuc2lvbihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkRXh0ZW5zaW9uX09wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRFeHRlbnNpb25fT3B0aW9uYWxHcm91cF9leHRlbnNpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24uQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFfRklFTERfTlVNQkVSID0gMTc7CiAgICAgIHByaXZhdGUgaW50IGFfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEEoKSB7CiAgICAgICAgcmV0dXJuIGFfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMTcsIGFfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMTcsIGFfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKSBvYmo7CgogICAgICAgIGlmIChoYXNBKCkgIT0gb3RoZXIuaGFzQSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgICAgaWYgKGdldEEoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEEoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBKCk7CiAgICAgICAgfQogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbi5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbi5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbi5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbi5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9ufQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKQogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRFeHRlbnNpb25fT3B0aW9uYWxHcm91cF9leHRlbnNpb25fZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRFeHRlbnNpb25fT3B0aW9uYWxHcm91cF9leHRlbnNpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbi5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbi5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbi5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGFfID0gMDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEV4dGVuc2lvbl9PcHRpb25hbEdyb3VwX2V4dGVuc2lvbl9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbi5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiBidWlsZCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbi5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbi5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5hXyA9IGFfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbi5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbilvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc0EoKSkgewogICAgICAgICAgICBzZXRBKG90aGVyLmdldEEoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDEzNjogewogICAgICAgICAgICAgICAgICBhXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzNgogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBpbnQgYV8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxNzs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE3OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldEEoKSB7CiAgICAgICAgICByZXR1cm4gYV87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxNzs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBhIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QShpbnQgdmFsdWUpIHsKCiAgICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE3OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgYV8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEV4dGVuc2lvbi5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbikKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24oKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPcHRpb25hbEdyb3VwX2V4dGVuc2lvbj4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T3B0aW9uYWxHcm91cF9leHRlbnNpb24+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPcHRpb25hbEdyb3VwX2V4dGVuc2lvbj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24pKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbiBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24pIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24gcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRFeHRlbnNpb259CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkRXh0ZW5zaW9uKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkRXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRFeHRlbnNpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24ubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkRXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbiBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24gcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24gYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24pb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEV4dGVuc2lvbikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEV4dGVuc2lvbikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbiBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbiBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3ROZXN0ZWRFeHRlbnNpb24+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdE5lc3RlZEV4dGVuc2lvbj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3ROZXN0ZWRFeHRlbnNpb24gcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TmVzdGVkRXh0ZW5zaW9uPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3ROZXN0ZWRFeHRlbnNpb24+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEV4dGVuc2lvbiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBURVNUX0ZJRUxEX05VTUJFUiA9IDEwMDI7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBDaGVjayBmb3IgYnVnIHdoZXJlIHN0cmluZyBleHRlbnNpb25zIGRlY2xhcmVkIGluIHRlc3RlZCBzY29wZSBkaWQgbm90CiAgICAgKiBjb21waWxlLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nPiB0ZXN0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMCwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MsCiAgICAgICAgICBudWxsKTsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5FU1RFRF9TVFJJTkdfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDEwMDM7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBVc2VkIHRvIHRlc3QgaWYgZ2VuZXJhdGVkIGV4dGVuc2lvbiBuYW1lIGlzIGNvcnJlY3Qgd2hlbiB0aGVyZSBhcmUKICAgICAqIHVuZGVyc2NvcmVzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nPiBuZXN0ZWRTdHJpbmdFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAxLAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZy5jbGFzcywKICAgICAgICAgIG51bGwpOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxHUk9VUF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTY7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEdyb3VwRXh0ZW5zaW9uIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uT3B0aW9uYWxHcm91cF9leHRlbnNpb24+IG9wdGlvbmFsR3JvdXBFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRFeHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAyLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uLmNsYXNzLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0ZPUkVJR05fRU5VTV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMjI7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEdyb3VwRXh0ZW5zaW9uIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RHcm91cEV4dGVuc2lvbiwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtPiBvcHRpb25hbEZvcmVpZ25FbnVtRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkRXh0ZW5zaW9uLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMywKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uY2xhc3MsCiAgICAgICAgICBudWxsKTsKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdENoaWxkRXh0ZW5zaW9uT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0EoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0QSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRCKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0QkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRXh0ZW5zaW9uIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEV4dGVuc2lvbigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEV4dGVuc2lvbi4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucyBnZXRPcHRpb25hbEV4dGVuc2lvbigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnNPckJ1aWxkZXIgZ2V0T3B0aW9uYWxFeHRlbnNpb25PckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9ufQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdENoaWxkRXh0ZW5zaW9uIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbikKICAgICAgVGVzdENoaWxkRXh0ZW5zaW9uT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0Q2hpbGRFeHRlbnNpb24ubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdENoaWxkRXh0ZW5zaW9uKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdENoaWxkRXh0ZW5zaW9uKCkgewogICAgICBhXyA9ICIiOwogICAgICBiXyA9ICIiOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RDaGlsZEV4dGVuc2lvbigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDaGlsZEV4dGVuc2lvbl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDaGlsZEV4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQV9GSUVMRF9OVU1CRVIgPSAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgYV8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgYV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRBQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQl9GSUVMRF9OVU1CRVIgPSAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgYl8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0IoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgYl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRCQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGJfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgb3B0aW9uYWxFeHRlbnNpb25fOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRXh0ZW5zaW9uIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxFeHRlbnNpb24oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIG9wdGlvbmFsX2V4dGVuc2lvbiA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxFeHRlbnNpb24uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIGdldE9wdGlvbmFsRXh0ZW5zaW9uKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxFeHRlbnNpb25fID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxFeHRlbnNpb25fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zT3JCdWlsZGVyIGdldE9wdGlvbmFsRXh0ZW5zaW9uT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxFeHRlbnNpb25fID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxFeHRlbnNpb25fOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmIChoYXNPcHRpb25hbEV4dGVuc2lvbigpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbEV4dGVuc2lvbigpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEsIGFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDIsIGJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDMsIGdldE9wdGlvbmFsRXh0ZW5zaW9uKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDEsIGFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDIsIGJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgZ2V0T3B0aW9uYWxFeHRlbnNpb24oKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24pKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uKSBvYmo7CgogICAgICBpZiAoaGFzQSgpICE9IG90aGVyLmhhc0EoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQSgpKSB7CiAgICAgICAgaWYgKCFnZXRBKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRBKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0IoKSAhPSBvdGhlci5oYXNCKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0IoKSkgewogICAgICAgIGlmICghZ2V0QigpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0QigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEV4dGVuc2lvbigpICE9IG90aGVyLmhhc09wdGlvbmFsRXh0ZW5zaW9uKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsRXh0ZW5zaW9uKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsRXh0ZW5zaW9uKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEV4dGVuc2lvbigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNCKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxFeHRlbnNpb24oKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxFeHRlbnNpb24oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24gcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25fZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbi5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldE9wdGlvbmFsRXh0ZW5zaW9uRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBhXyA9ICIiOwogICAgICAgIGJfID0gIiI7CiAgICAgICAgb3B0aW9uYWxFeHRlbnNpb25fID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEV4dGVuc2lvbkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbiBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24odGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24gcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuYV8gPSBhXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5iXyA9IGJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRXh0ZW5zaW9uXyA9IG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxFeHRlbnNpb25fCiAgICAgICAgICAgICAgOiBvcHRpb25hbEV4dGVuc2lvbkJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24pb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24gb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNBKCkpIHsKICAgICAgICAgIGFfID0gb3RoZXIuYV87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0IoKSkgewogICAgICAgICAgYl8gPSBvdGhlci5iXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxFeHRlbnNpb24oKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbEV4dGVuc2lvbihvdGhlci5nZXRPcHRpb25hbEV4dGVuc2lvbigpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmIChoYXNPcHRpb25hbEV4dGVuc2lvbigpKSB7CiAgICAgICAgICBpZiAoIWdldE9wdGlvbmFsRXh0ZW5zaW9uKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBhXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgYl8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsRXh0ZW5zaW9uRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgYV8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBhXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBhLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0QUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBhIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgYV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRBKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBhIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGJfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzQigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRCKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBiXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldEJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBiXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBiXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJCKCkgewogICAgICAgIGJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0QigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgYiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgYl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucyBvcHRpb25hbEV4dGVuc2lvbl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9uc09yQnVpbGRlcj4gb3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyBvcHRpb25hbF9leHRlbnNpb24gPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEV4dGVuc2lvbiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEV4dGVuc2lvbigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyBvcHRpb25hbF9leHRlbnNpb24gPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxFeHRlbnNpb24uCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucyBnZXRPcHRpb25hbEV4dGVuc2lvbigpIHsKICAgICAgICBpZiAob3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxFeHRlbnNpb25fID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxFeHRlbnNpb25fOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbEV4dGVuc2lvbl8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEV4dGVuc2lvbl8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsRXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxFeHRlbnNpb25fICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxFeHRlbnNpb25fICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsRXh0ZW5zaW9uXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEV4dGVuc2lvbkJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbEV4dGVuc2lvbl8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsRXh0ZW5zaW9uKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvcHRpb25hbEV4dGVuc2lvbl8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEV4dGVuc2lvbkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucy5CdWlsZGVyIGdldE9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsRXh0ZW5zaW9uRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9uc09yQnVpbGRlciBnZXRPcHRpb25hbEV4dGVuc2lvbk9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEV4dGVuc2lvbl8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsRXh0ZW5zaW9uXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyBvcHRpb25hbF9leHRlbnNpb24gPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9uc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbEV4dGVuc2lvbkZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEV4dGVuc2lvbkJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxFeHRlbnNpb24oKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsRXh0ZW5zaW9uXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbEV4dGVuc2lvbkJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24gREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdENoaWxkRXh0ZW5zaW9uPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RDaGlsZEV4dGVuc2lvbj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RDaGlsZEV4dGVuc2lvbiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RDaGlsZEV4dGVuc2lvbj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0Q2hpbGRFeHRlbnNpb24+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdENoaWxkRXh0ZW5zaW9uRGF0YU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRBKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0QUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNCKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBiLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRCQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBvcHRpb25hbF9leHRlbnNpb24gPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxFeHRlbnNpb24gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsRXh0ZW5zaW9uKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBvcHRpb25hbF9leHRlbnNpb24gPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRXh0ZW5zaW9uLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIGdldE9wdGlvbmFsRXh0ZW5zaW9uKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBvcHRpb25hbF9leHRlbnNpb24gPSAzOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YU9yQnVpbGRlciBnZXRPcHRpb25hbEV4dGVuc2lvbk9yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIEVtdWxhdGVzIHdpcmVmb3JtYXQgZGF0YSBvZiBUZXN0Q2hpbGRFeHRlbnNpb24gd2l0aCBkeW5hbWljIGV4dGVuc2lvbgogICAqIChEeW5hbWljRXh0ZW5zaW9uKS4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGF9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0Q2hpbGRFeHRlbnNpb25EYXRhIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEpCiAgICAgIFRlc3RDaGlsZEV4dGVuc2lvbkRhdGFPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RDaGlsZEV4dGVuc2lvbkRhdGEubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdENoaWxkRXh0ZW5zaW9uRGF0YShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RDaGlsZEV4dGVuc2lvbkRhdGEoKSB7CiAgICAgIGFfID0gIiI7CiAgICAgIGJfID0gIiI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDaGlsZEV4dGVuc2lvbkRhdGFfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25EYXRhX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBOZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBkeW5hbWljID0gNDA5NzA3MDA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkeW5hbWljIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzRHluYW1pYygpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zIGR5bmFtaWMgPSA0MDk3MDcwMDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkeW5hbWljLgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBnZXREeW5hbWljKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgZHluYW1pYyA9IDQwOTcwNzAwODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zT3JCdWlsZGVyIGdldER5bmFtaWNPckJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGF9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSkKICAgICAgICBOZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBOZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBOZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBOZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25EYXRhX05lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25EYXRhX05lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwdWJsaWMgaW50ZXJmYWNlIE5lc3RlZER5bmFtaWNFeHRlbnNpb25zT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucykKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIGJvb2xlYW4gaGFzQSgpOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICAgICAqLwogICAgICAgIGludCBnZXRBKCk7CgogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGIgPSAyOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGIgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIGJvb2xlYW4gaGFzQigpOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGIgPSAyOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICAgICAqLwogICAgICAgIGludCBnZXRCKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBOZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zKQogICAgICAgICAgTmVzdGVkRHluYW1pY0V4dGVuc2lvbnNPckJ1aWxkZXIgewogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgICAvLyBVc2UgTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgICBwcml2YXRlIE5lc3RlZER5bmFtaWNFeHRlbnNpb25zKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMoKSB7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICAgIHJldHVybiBuZXcgTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uRGF0YV9OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFfTmVzdGVkRHluYW1pY0V4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDaGlsZEV4dGVuc2lvbkRhdGFfTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhX05lc3RlZER5bmFtaWNFeHRlbnNpb25zX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgICAgcHJpdmF0ZSBpbnQgYV8gPSAwOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgICAgcmV0dXJuIGFfOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQl9GSUVMRF9OVU1CRVIgPSAyOwogICAgICAgIHByaXZhdGUgaW50IGJfID0gMDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiID0gMjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzQigpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYiA9IDI7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGIuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0QigpIHsKICAgICAgICAgIHJldHVybiBiXzsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGFfKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyLCBiXyk7CiAgICAgICAgICB9CiAgICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgICBzaXplID0gMDsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBhXyk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMiwgYl8pOwogICAgICAgICAgfQogICAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgfQogICAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucykpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgICAgfQogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zKSBvYmo7CgogICAgICAgICAgaWYgKGhhc0EoKSAhPSBvdGhlci5oYXNBKCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICAgICAgaWYgKGdldEEoKQogICAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoaGFzQigpICE9IG90aGVyLmhhc0IoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgaWYgKGhhc0IoKSkgewogICAgICAgICAgICBpZiAoZ2V0QigpCiAgICAgICAgICAgICAgICAhPSBvdGhlci5nZXRCKCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICAgIH0KICAgICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEEoKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChoYXNCKCkpIHsKICAgICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQl9GSUVMRF9OVU1CRVI7CiAgICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEIoKTsKICAgICAgICAgIH0KICAgICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgcHJvdG90eXBlKSB7CiAgICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnN9CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMpCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnNPckJ1aWxkZXIgewogICAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uRGF0YV9OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFfTmVzdGVkRHluYW1pY0V4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25EYXRhX05lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YV9OZXN0ZWREeW5hbWljRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgICB9CgogICAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMubmV3QnVpbGRlcigpCiAgICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgICAgfQoKICAgICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgICAgYV8gPSAwOwogICAgICAgICAgICBiXyA9IDA7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDaGlsZEV4dGVuc2lvbkRhdGFfTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhX05lc3RlZER5bmFtaWNFeHRlbnNpb25zX2Rlc2NyaXB0b3I7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgYnVpbGQoKSB7CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnModGhpcyk7CiAgICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgIH0KCiAgICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zIHJlc3VsdCkgewogICAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICAgIHJlc3VsdC5hXyA9IGFfOwogICAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgICAgIHJlc3VsdC5iXyA9IGJfOwogICAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucykgewogICAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMpb3RoZXIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBvdGhlcikgewogICAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIGlmIChvdGhlci5oYXNBKCkpIHsKICAgICAgICAgICAgICBzZXRBKG90aGVyLmdldEEoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG90aGVyLmhhc0IoKSkgewogICAgICAgICAgICAgIHNldEIob3RoZXIuZ2V0QigpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgICAgICBhXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgICAgIGJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgICBwcml2YXRlIGludCBhXyA7CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAgICAgKi8KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICAgIH0KICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICAgICAqLwogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgICAgICByZXR1cm4gYV87CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYSB0byBzZXQuCiAgICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEEoaW50IHZhbHVlKSB7CgogICAgICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgICAgYV8gPSAwOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CgogICAgICAgICAgcHJpdmF0ZSBpbnQgYl8gOwogICAgICAgICAgLyoqCiAgICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiID0gMjs8L2NvZGU+CiAgICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGIgZmllbGQgaXMgc2V0LgogICAgICAgICAgICovCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNCKCkgewogICAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGIgPSAyOzwvY29kZT4KICAgICAgICAgICAqIEByZXR1cm4gVGhlIGIuCiAgICAgICAgICAgKi8KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0QigpIHsKICAgICAgICAgICAgcmV0dXJuIGJfOwogICAgICAgICAgfQogICAgICAgICAgLyoqCiAgICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiID0gMjs8L2NvZGU+CiAgICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGIgdG8gc2V0LgogICAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRCKGludCB2YWx1ZSkgewoKICAgICAgICAgICAgYl8gPSB2YWx1ZTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGIgPSAyOzwvY29kZT4KICAgICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJCKCkgewogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICAgIGJfID0gMDsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgICB9CgoKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zKQogICAgICAgIH0KCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zKQogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgICBzdGF0aWMgewogICAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWREeW5hbWljRXh0ZW5zaW9ucz4KICAgICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkRHluYW1pY0V4dGVuc2lvbnM+KCkgewogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIE5lc3RlZER5bmFtaWNFeHRlbnNpb25zIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkRHluYW1pY0V4dGVuc2lvbnM+IHBhcnNlcigpIHsKICAgICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZER5bmFtaWNFeHRlbnNpb25zPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgICAgfQoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFlOQU1JQ19GSUVMRF9OVU1CRVIgPSA0MDk3MDcwMDg7CiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBkeW5hbWljXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBkeW5hbWljID0gNDA5NzA3MDA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkeW5hbWljIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHluYW1pYygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBkeW5hbWljID0gNDA5NzA3MDA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZHluYW1pYy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgZ2V0RHluYW1pYygpIHsKICAgICAgICByZXR1cm4gZHluYW1pY18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBkeW5hbWljXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zIGR5bmFtaWMgPSA0MDk3MDcwMDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9uc09yQnVpbGRlciBnZXREeW5hbWljT3JCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBkeW5hbWljXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGR5bmFtaWNfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg0MDk3MDcwMDgsIGdldER5bmFtaWMoKSk7CiAgICAgICAgfQogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNDA5NzA3MDA4LCBnZXREeW5hbWljKCkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEpIG9iajsKCiAgICAgICAgaWYgKGhhc0R5bmFtaWMoKSAhPSBvdGhlci5oYXNEeW5hbWljKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzRHluYW1pYygpKSB7CiAgICAgICAgICBpZiAoIWdldER5bmFtaWMoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RHluYW1pYygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaWYgKGhhc0R5bmFtaWMoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFlOQU1JQ19GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREeW5hbWljKCkuaGFzaENvZGUoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEpCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDaGlsZEV4dGVuc2lvbkRhdGFfTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25EYXRhX05lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICAgIGdldER5bmFtaWNGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgZHluYW1pY18gPSBudWxsOwogICAgICAgICAgaWYgKGR5bmFtaWNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICAgIGR5bmFtaWNCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIGR5bmFtaWNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDaGlsZEV4dGVuc2lvbkRhdGFfTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIGJ1aWxkKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQuZHluYW1pY18gPSBkeW5hbWljQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgICAgPyBkeW5hbWljXwogICAgICAgICAgICAgICAgOiBkeW5hbWljQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSlvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzRHluYW1pYygpKSB7CiAgICAgICAgICAgIG1lcmdlRHluYW1pYyhvdGhlci5nZXREeW5hbWljKCkpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAtMTAxNzMxMTIzMDogewogICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgIGdldER5bmFtaWNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgLTEwMTczMTEyMzAKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBkeW5hbWljXzsKICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9uc09yQnVpbGRlcj4gZHluYW1pY0J1aWxkZXJfOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBkeW5hbWljID0gNDA5NzA3MDA4OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR5bmFtaWMgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0R5bmFtaWMoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBkeW5hbWljID0gNDA5NzA3MDA4OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBkeW5hbWljLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zIGdldER5bmFtaWMoKSB7CiAgICAgICAgICBpZiAoZHluYW1pY0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGR5bmFtaWNfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZHluYW1pY187CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gZHluYW1pY0J1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zIGR5bmFtaWMgPSA0MDk3MDcwMDg7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER5bmFtaWMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyB2YWx1ZSkgewogICAgICAgICAgaWYgKGR5bmFtaWNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZHluYW1pY18gPSB2YWx1ZTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGR5bmFtaWNCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBkeW5hbWljID0gNDA5NzA3MDA4OzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXREeW5hbWljKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgICBpZiAoZHluYW1pY0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZHluYW1pY18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGR5bmFtaWNCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBkeW5hbWljID0gNDA5NzA3MDA4OzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUR5bmFtaWMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyB2YWx1ZSkgewogICAgICAgICAgaWYgKGR5bmFtaWNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICAgIGR5bmFtaWNfICE9IG51bGwgJiYKICAgICAgICAgICAgICBkeW5hbWljXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgICAgZ2V0RHluYW1pY0J1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGR5bmFtaWNfID0gdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGR5bmFtaWNCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGR5bmFtaWNfICE9IG51bGwpIHsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgZHluYW1pYyA9IDQwOTcwNzAwODs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEeW5hbWljKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgZHluYW1pY18gPSBudWxsOwogICAgICAgICAgaWYgKGR5bmFtaWNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICAgIGR5bmFtaWNCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIGR5bmFtaWNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgZHluYW1pYyA9IDQwOTcwNzAwODs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMuQnVpbGRlciBnZXREeW5hbWljQnVpbGRlcigpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIGdldER5bmFtaWNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucyBkeW5hbWljID0gNDA5NzA3MDA4OzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9uc09yQnVpbGRlciBnZXREeW5hbWljT3JCdWlsZGVyKCkgewogICAgICAgICAgaWYgKGR5bmFtaWNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBkeW5hbWljQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGR5bmFtaWNfID09IG51bGwgPwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGR5bmFtaWNfOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnMgZHluYW1pYyA9IDQwOTcwNzAwODs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnNPckJ1aWxkZXI+IAogICAgICAgICAgICBnZXREeW5hbWljRmllbGRCdWlsZGVyKCkgewogICAgICAgICAgaWYgKGR5bmFtaWNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGR5bmFtaWNCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5OZXN0ZWREeW5hbWljRXh0ZW5zaW9ucy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLk5lc3RlZER5bmFtaWNFeHRlbnNpb25zT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgICBnZXREeW5hbWljKCksCiAgICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgICBkeW5hbWljXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gZHluYW1pY0J1aWxkZXJfOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGFfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRBKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGFfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBhLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0QUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBhXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJfRklFTERfTlVNQkVSID0gMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGJfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNCKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRCKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBiLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0QkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBiXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIG9wdGlvbmFsRXh0ZW5zaW9uXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIG9wdGlvbmFsX2V4dGVuc2lvbiA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEV4dGVuc2lvbiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsRXh0ZW5zaW9uKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBvcHRpb25hbF9leHRlbnNpb24gPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRXh0ZW5zaW9uLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSBnZXRPcHRpb25hbEV4dGVuc2lvbigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsRXh0ZW5zaW9uXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsRXh0ZW5zaW9uXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIG9wdGlvbmFsX2V4dGVuc2lvbiA9IDM7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YU9yQnVpbGRlciBnZXRPcHRpb25hbEV4dGVuc2lvbk9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsRXh0ZW5zaW9uXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsRXh0ZW5zaW9uXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMSwgYV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMiwgYl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMywgZ2V0T3B0aW9uYWxFeHRlbnNpb24oKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMSwgYV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMiwgYl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzLCBnZXRPcHRpb25hbEV4dGVuc2lvbigpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEpIG9iajsKCiAgICAgIGlmIChoYXNBKCkgIT0gb3RoZXIuaGFzQSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBpZiAoIWdldEEoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzQigpICE9IG90aGVyLmhhc0IoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQigpKSB7CiAgICAgICAgaWYgKCFnZXRCKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRCKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsRXh0ZW5zaW9uKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxFeHRlbnNpb24oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxFeHRlbnNpb24oKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxFeHRlbnNpb24oKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsRXh0ZW5zaW9uKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzQSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0IoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEV4dGVuc2lvbigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfRVhURU5TSU9OX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEV4dGVuc2lvbigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBFbXVsYXRlcyB3aXJlZm9ybWF0IGRhdGEgb2YgVGVzdENoaWxkRXh0ZW5zaW9uIHdpdGggZHluYW1pYyBleHRlbnNpb24KICAgICAqIChEeW5hbWljRXh0ZW5zaW9uKS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGF9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25EYXRhX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDaGlsZEV4dGVuc2lvbkRhdGFfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0T3B0aW9uYWxFeHRlbnNpb25GaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGFfID0gIiI7CiAgICAgICAgYl8gPSAiIjsKICAgICAgICBvcHRpb25hbEV4dGVuc2lvbl8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEV4dGVuc2lvbkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25EYXRhX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5hXyA9IGFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmJfID0gYl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxFeHRlbnNpb25fID0gb3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbEV4dGVuc2lvbl8KICAgICAgICAgICAgICA6IG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNBKCkpIHsKICAgICAgICAgIGFfID0gb3RoZXIuYV87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0IoKSkgewogICAgICAgICAgYl8gPSBvdGhlci5iXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxFeHRlbnNpb24oKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbEV4dGVuc2lvbihvdGhlci5nZXRPcHRpb25hbEV4dGVuc2lvbigpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgYV8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGJfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEV4dGVuc2lvbkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGFfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRBKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBhXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldEFCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBhXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBKCkgewogICAgICAgIGFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0QSgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgYSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgYV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBiXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0IoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0QigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGJfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgYl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRCQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBiXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgYl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRCKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgYl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQigpIHsKICAgICAgICBiXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldEIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRCQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEgb3B0aW9uYWxFeHRlbnNpb25fOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFPckJ1aWxkZXI+IG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxFeHRlbnNpb24gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxFeHRlbnNpb24oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRXh0ZW5zaW9uLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEgZ2V0T3B0aW9uYWxFeHRlbnNpb24oKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsRXh0ZW5zaW9uXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsRXh0ZW5zaW9uXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIG9wdGlvbmFsX2V4dGVuc2lvbiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEV4dGVuc2lvbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxFeHRlbnNpb25fID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIG9wdGlvbmFsX2V4dGVuc2lvbiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxFeHRlbnNpb25fID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIG9wdGlvbmFsX2V4dGVuc2lvbiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbEV4dGVuc2lvbihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsRXh0ZW5zaW9uXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsRXh0ZW5zaW9uXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbEV4dGVuc2lvbl8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxFeHRlbnNpb25fICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIG9wdGlvbmFsX2V4dGVuc2lvbiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEV4dGVuc2lvbigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb3B0aW9uYWxFeHRlbnNpb25fID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEV4dGVuc2lvbkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIG9wdGlvbmFsX2V4dGVuc2lvbiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuQnVpbGRlciBnZXRPcHRpb25hbEV4dGVuc2lvbkJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbEV4dGVuc2lvbkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhIG9wdGlvbmFsX2V4dGVuc2lvbiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFPckJ1aWxkZXIgZ2V0T3B0aW9uYWxFeHRlbnNpb25PckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxFeHRlbnNpb25fID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEV4dGVuc2lvbl87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEgb3B0aW9uYWxfZXh0ZW5zaW9uID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxFeHRlbnNpb25GaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRXh0ZW5zaW9uQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGEuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLk5lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsRXh0ZW5zaW9uKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbEV4dGVuc2lvbl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxFeHRlbnNpb25CdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdENoaWxkRXh0ZW5zaW9uRGF0YT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0Q2hpbGRFeHRlbnNpb25EYXRhPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RDaGlsZEV4dGVuc2lvbkRhdGE+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdENoaWxkRXh0ZW5zaW9uRGF0YT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICovCiAgICBpbnQgZ2V0QSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbiBjaGlsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQ2hpbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbiBjaGlsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY2hpbGQuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIGdldENoaWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb24gY2hpbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25PckJ1aWxkZXIgZ2V0Q2hpbGRPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9ufQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbikKICAgICAgVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb24ubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgYV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0QSgpIHsKICAgICAgcmV0dXJuIGFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENISUxEX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIGNoaWxkXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbiBjaGlsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0NoaWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb24gY2hpbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNoaWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24gZ2V0Q2hpbGQoKSB7CiAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uLmdldERlZmF1bHRJbnN0YW5jZSgpIDogY2hpbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uIGNoaWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbk9yQnVpbGRlciBnZXRDaGlsZE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKGhhc0NoaWxkKCkpIHsKICAgICAgICBpZiAoIWdldENoaWxkKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIsIGdldENoaWxkKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIGFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgZ2V0Q2hpbGQoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb24pKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uKSBvYmo7CgogICAgICBpZiAoaGFzQSgpICE9IG90aGVyLmhhc0EoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQSgpKSB7CiAgICAgICAgaWYgKGdldEEoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRBKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzQ2hpbGQoKSAhPSBvdGhlci5oYXNDaGlsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNDaGlsZCgpKSB7CiAgICAgICAgaWYgKCFnZXRDaGlsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Q2hpbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBBX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0NoaWxkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDSElMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Q2hpbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb24gcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25fZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbi5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldENoaWxkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBhXyA9IDA7CiAgICAgICAgY2hpbGRfID0gbnVsbDsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbiBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb24odGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb24gcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuYV8gPSBhXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5jaGlsZF8gPSBjaGlsZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGNoaWxkXwogICAgICAgICAgICAgIDogY2hpbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb24pIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzQSgpKSB7CiAgICAgICAgICBzZXRBKG90aGVyLmdldEEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNDaGlsZCgpKSB7CiAgICAgICAgICBtZXJnZUNoaWxkKG90aGVyLmdldENoaWxkKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKGhhc0NoaWxkKCkpIHsKICAgICAgICAgIGlmICghZ2V0Q2hpbGQoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgYV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0Q2hpbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGFfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgIHJldHVybiBhXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRBKGludCB2YWx1ZSkgewoKICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGFfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbiBjaGlsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbi5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbk9yQnVpbGRlcj4gY2hpbGRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb24gY2hpbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb24gY2hpbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY2hpbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24gZ2V0Q2hpbGQoKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb24gY2hpbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENoaWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uIHZhbHVlKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBjaGlsZF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uIGNoaWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDaGlsZCgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgY2hpbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbiBjaGlsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VDaGlsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbiB2YWx1ZSkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSAmJgogICAgICAgICAgICBjaGlsZF8gIT0gbnVsbCAmJgogICAgICAgICAgICBjaGlsZF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0Q2hpbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNoaWxkXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChjaGlsZF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uIGNoaWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNoaWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBjaGlsZF8gPSBudWxsOwogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgY2hpbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uIGNoaWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24uQnVpbGRlciBnZXRDaGlsZEJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRDaGlsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbiBjaGlsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uT3JCdWlsZGVyIGdldENoaWxkT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb24gY2hpbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbi5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbk9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRDaGlsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb24sIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0Q2hpbGQoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGNoaWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb24gREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb24+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNBKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgKi8KICAgIGludCBnZXRBKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBjaGlsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQ2hpbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgY2hpbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNoaWxkLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgZ2V0Q2hpbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgY2hpbGQgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhT3JCdWlsZGVyIGdldENoaWxkT3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogRW11bGF0ZXMgd2lyZWZvcm1hdCBkYXRhIG9mIFRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbiB3aXRoIGR5bmFtaWMgZXh0ZW5zaW9uCiAgICogKER5bmFtaWNFeHRlbnNpb24pLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YSkKICAgICAgVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGFfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgYV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0QSgpIHsKICAgICAgcmV0dXJuIGFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENISUxEX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBjaGlsZF87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhIGNoaWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNoaWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQ2hpbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgY2hpbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNoaWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhIGdldENoaWxkKCkgewogICAgICByZXR1cm4gY2hpbGRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhIGNoaWxkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGFPckJ1aWxkZXIgZ2V0Q2hpbGRPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGNoaWxkXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIsIGdldENoaWxkKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIGFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgZ2V0Q2hpbGQoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhKSBvYmo7CgogICAgICBpZiAoaGFzQSgpICE9IG90aGVyLmhhc0EoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQSgpKSB7CiAgICAgICAgaWYgKGdldEEoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRBKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzQ2hpbGQoKSAhPSBvdGhlci5oYXNDaGlsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNDaGlsZCgpKSB7CiAgICAgICAgaWYgKCFnZXRDaGlsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Q2hpbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBBX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0NoaWxkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDSElMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Q2hpbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogRW11bGF0ZXMgd2lyZWZvcm1hdCBkYXRhIG9mIFRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbiB3aXRoIGR5bmFtaWMgZXh0ZW5zaW9uCiAgICAgKiAoRHluYW1pY0V4dGVuc2lvbikuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGFPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldENoaWxkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBhXyA9IDA7CiAgICAgICAgY2hpbGRfID0gbnVsbDsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuYV8gPSBhXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5jaGlsZF8gPSBjaGlsZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGNoaWxkXwogICAgICAgICAgICAgIDogY2hpbGRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0EoKSkgewogICAgICAgICAgc2V0QShvdGhlci5nZXRBKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzQ2hpbGQoKSkgewogICAgICAgICAgbWVyZ2VDaGlsZChvdGhlci5nZXRDaGlsZCgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBhXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRDaGlsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgYV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEEoKSB7CiAgICAgICAgcmV0dXJuIGFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEEoaW50IHZhbHVlKSB7CgogICAgICAgIGFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgYV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBjaGlsZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YU9yQnVpbGRlcj4gY2hpbGRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhIGNoaWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2hpbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzQ2hpbGQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBjaGlsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgZ2V0Q2hpbGQoKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLmdldERlZmF1bHRJbnN0YW5jZSgpIDogY2hpbGRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gY2hpbGRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBjaGlsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Q2hpbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhIHZhbHVlKSB7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBjaGlsZF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBjaGlsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Q2hpbGQoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBjaGlsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBjaGlsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VDaGlsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgdmFsdWUpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkgJiYKICAgICAgICAgICAgY2hpbGRfICE9IG51bGwgJiYKICAgICAgICAgICAgY2hpbGRfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRDaGlsZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY2hpbGRfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKGNoaWxkXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhIGNoaWxkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNoaWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBjaGlsZF8gPSBudWxsOwogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgY2hpbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBjaGlsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YS5CdWlsZGVyIGdldENoaWxkQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldENoaWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSBjaGlsZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YU9yQnVpbGRlciBnZXRDaGlsZE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY2hpbGRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBjaGlsZF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLmdldERlZmF1bHRJbnN0YW5jZSgpIDogY2hpbGRfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEgY2hpbGQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENoaWxkRXh0ZW5zaW9uRGF0YU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRDaGlsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDaGlsZEV4dGVuc2lvbkRhdGEuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2hpbGRFeHRlbnNpb25EYXRhT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0Q2hpbGQoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGNoaWxkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGE+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25EYXRhPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGEgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0UmVxdWlyZWRFbnVtT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW0pCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVxdWlyZWRfZW51bSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXF1aXJlZEVudW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1JlcXVpcmVkRW51bSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVxdWlyZWRfZW51bSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRFbnVtLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIGdldFJlcXVpcmVkRW51bSgpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEEgZHVtbXkgb3B0aW9uYWwgZmllbGQuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0EoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEEgZHVtbXkgb3B0aW9uYWwgZmllbGQuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICovCiAgICBpbnQgZ2V0QSgpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFJlcXVpcmVkIGFuZCBjbG9zZWQgZW51bSBmaWVsZHMgYXJlIGNvbnNpZGVyZWQgdW5rbm93biBmaWVsZHMgaWYgdGhlIHZhbHVlIGlzCiAgICogbm90IHZhbGlkLiBXZSBuZWVkIHRvIG1ha2Ugc3VyZSBpdCBmdW5jdGlvbnMgYXMgZXhwZWN0ZWQuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFJlcXVpcmVkRW51bSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtKQogICAgICBUZXN0UmVxdWlyZWRFbnVtT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0UmVxdWlyZWRFbnVtLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RSZXF1aXJlZEVudW0oY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0UmVxdWlyZWRFbnVtKCkgewogICAgICByZXF1aXJlZEVudW1fID0gNDsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0UmVxdWlyZWRFbnVtKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkRW51bV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEVudW1fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0uY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRVUlSRURfRU5VTV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgcmVxdWlyZWRFbnVtXyA9IDQ7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSByZXF1aXJlZF9lbnVtID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzUmVxdWlyZWRFbnVtKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSByZXF1aXJlZF9lbnVtID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0UmVxdWlyZWRFbnVtKCkgewogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uZm9yTnVtYmVyKHJlcXVpcmVkRW51bV8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLkZPUkVJR05fRk9PIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgaW50IGFfID0gMDsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEEgZHVtbXkgb3B0aW9uYWwgZmllbGQuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBIGR1bW15IG9wdGlvbmFsIGZpZWxkLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRBKCkgewogICAgICByZXR1cm4gYV87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFoYXNSZXF1aXJlZEVudW0oKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgxLCByZXF1aXJlZEVudW1fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyLCBhXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSgxLCByZXF1aXJlZEVudW1fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIsIGFfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0pKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0pIG9iajsKCiAgICAgIGlmIChoYXNSZXF1aXJlZEVudW0oKSAhPSBvdGhlci5oYXNSZXF1aXJlZEVudW0oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtKCkpIHsKICAgICAgICBpZiAocmVxdWlyZWRFbnVtXyAhPSBvdGhlci5yZXF1aXJlZEVudW1fKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0EoKSAhPSBvdGhlci5oYXNBKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgIGlmIChnZXRBKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVFVSVJFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXF1aXJlZEVudW1fOwogICAgICB9CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBBX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0gcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0gcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBSZXF1aXJlZCBhbmQgY2xvc2VkIGVudW0gZmllbGRzIGFyZSBjb25zaWRlcmVkIHVua25vd24gZmllbGRzIGlmIHRoZSB2YWx1ZSBpcwogICAgICogbm90IHZhbGlkLiBXZSBuZWVkIHRvIG1ha2Ugc3VyZSBpdCBmdW5jdGlvbnMgYXMgZXhwZWN0ZWQuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1PckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkRW51bV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRFbnVtX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICByZXF1aXJlZEVudW1fID0gNDsKICAgICAgICBhXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEVudW1fZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0odGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnJlcXVpcmVkRW51bV8gPSByZXF1aXJlZEVudW1fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmFfID0gYV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0pIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0gb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzUmVxdWlyZWRFbnVtKCkpIHsKICAgICAgICAgIHNldFJlcXVpcmVkRW51bShvdGhlci5nZXRSZXF1aXJlZEVudW0oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNBKCkpIHsKICAgICAgICAgIHNldEEob3RoZXIuZ2V0QSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghaGFzUmVxdWlyZWRFbnVtKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXF1aXJlZEVudW1fID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIGFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgcmVxdWlyZWRFbnVtXyA9IDQ7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVxdWlyZWRfZW51bSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc1JlcXVpcmVkRW51bSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSByZXF1aXJlZF9lbnVtID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRW51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0UmVxdWlyZWRFbnVtKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIocmVxdWlyZWRFbnVtXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5GT1JFSUdOX0ZPTyA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcXVpcmVkX2VudW0gPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXF1aXJlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXF1aXJlZEVudW0ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJlcXVpcmVkRW51bV8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcXVpcmVkX2VudW0gPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXF1aXJlZEVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHJlcXVpcmVkRW51bV8gPSA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBhXyA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBIGR1bW15IG9wdGlvbmFsIGZpZWxkLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQSBkdW1teSBvcHRpb25hbCBmaWVsZC4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgIHJldHVybiBhXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQSBkdW1teSBvcHRpb25hbCBmaWVsZC4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBhIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QShpbnQgdmFsdWUpIHsKCiAgICAgICAgYV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEEgZHVtbXkgb3B0aW9uYWwgZmllbGQuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgYV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW0pCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW0pCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0gREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0gZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVxdWlyZWRFbnVtPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RSZXF1aXJlZEVudW0+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UmVxdWlyZWRFbnVtIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlcXVpcmVkRW51bT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVxdWlyZWRFbnVtPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0UmVxdWlyZWRFbnVtTm9NYXNrT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1Ob01hc2spCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU5vTWFzay5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW0gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRFbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW0oKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1Ob01hc2suTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEVudW0uCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzay5OZXN0ZWRFbnVtIGdldFJlcXVpcmVkRW51bSgpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEEgZHVtbXkgb3B0aW9uYWwgZmllbGQuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0EoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEEgZHVtbXkgb3B0aW9uYWwgZmllbGQuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICovCiAgICBpbnQgZ2V0QSgpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRlc3RSZXF1aXJlZEVudW0gKyB1c2luZyBlbnVtIHZhbHVlcyB0aGF0IHdvbid0IGZpdCB0byA2NCBiaXRtYXNrLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU5vTWFza30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RSZXF1aXJlZEVudW1Ob01hc2sgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU5vTWFzaykKICAgICAgVGVzdFJlcXVpcmVkRW51bU5vTWFza09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFJlcXVpcmVkRW51bU5vTWFzay5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0UmVxdWlyZWRFbnVtTm9NYXNrKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFJlcXVpcmVkRW51bU5vTWFzaygpIHsKICAgICAgcmVxdWlyZWRFbnVtXyA9IDA7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFJlcXVpcmVkRW51bU5vTWFzaygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEVudW1Ob01hc2tfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRFbnVtTm9NYXNrX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrLk5lc3RlZEVudW19CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIE5lc3RlZEVudW0KICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5VTlNQRUNJRklFRCA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgVU5TUEVDSUZJRUQoMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEZPTygyKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDEwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVIoMTAwKSwKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEludGVudGlvbmFsbHkgbmVnYXRpdmUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5CQVogPSAtMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVooLTEpLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+VU5TUEVDSUZJRUQgPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOU1BFQ0lGSUVEX1ZBTFVFID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX1ZBTFVFID0gMjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDEwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVJfVkFMVUUgPSAxMDA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBJbnRlbnRpb25hbGx5IG5lZ2F0aXZlLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+QkFaID0gLTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFaX1ZBTFVFID0gLTE7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBVTlNQRUNJRklFRDsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIEZPTzsKICAgICAgICAgIGNhc2UgMTAwOiByZXR1cm4gQkFSOwogICAgICAgICAgY2FzZSAtMTogcmV0dXJuIEJBWjsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE5lc3RlZEVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBOZXN0ZWRFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIE5lc3RlZEVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIE5lc3RlZEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTmVzdGVkRW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgTmVzdGVkRW51bShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1Ob01hc2suTmVzdGVkRW51bSkKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRVUlSRURfRU5VTV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgcmVxdWlyZWRFbnVtXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXF1aXJlZEVudW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc1JlcXVpcmVkRW51bSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU5vTWFzay5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW0gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrLk5lc3RlZEVudW0gZ2V0UmVxdWlyZWRFbnVtKCkgewogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suTmVzdGVkRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suTmVzdGVkRW51bS5mb3JOdW1iZXIocmVxdWlyZWRFbnVtXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzay5OZXN0ZWRFbnVtLlVOU1BFQ0lGSUVEIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgaW50IGFfID0gMDsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEEgZHVtbXkgb3B0aW9uYWwgZmllbGQuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBIGR1bW15IG9wdGlvbmFsIGZpZWxkLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRBKCkgewogICAgICByZXR1cm4gYV87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFoYXNSZXF1aXJlZEVudW0oKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgxLCByZXF1aXJlZEVudW1fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyLCBhXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSgxLCByZXF1aXJlZEVudW1fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIsIGFfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2spKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzayBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2spIG9iajsKCiAgICAgIGlmIChoYXNSZXF1aXJlZEVudW0oKSAhPSBvdGhlci5oYXNSZXF1aXJlZEVudW0oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtKCkpIHsKICAgICAgICBpZiAocmVxdWlyZWRFbnVtXyAhPSBvdGhlci5yZXF1aXJlZEVudW1fKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0EoKSAhPSBvdGhlci5oYXNBKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgIGlmIChnZXRBKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVFVSVJFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXF1aXJlZEVudW1fOwogICAgICB9CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBBX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzayBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzayBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzayBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzayBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzayBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0UmVxdWlyZWRFbnVtICsgdXNpbmcgZW51bSB2YWx1ZXMgdGhhdCB3b24ndCBmaXQgdG8gNjQgYml0bWFzay4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1Ob01hc2t9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFza09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRFbnVtTm9NYXNrX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEVudW1Ob01hc2tfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2submV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHJlcXVpcmVkRW51bV8gPSAwOwogICAgICAgIGFfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkRW51bU5vTWFza19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzayh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucmVxdWlyZWRFbnVtXyA9IHJlcXVpcmVkRW51bV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuYV8gPSBhXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzaykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzayBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNSZXF1aXJlZEVudW0oKSkgewogICAgICAgICAgc2V0UmVxdWlyZWRFbnVtKG90aGVyLmdldFJlcXVpcmVkRW51bSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0EoKSkgewogICAgICAgICAgc2V0QShvdGhlci5nZXRBKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKCFoYXNSZXF1aXJlZEVudW0oKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suTmVzdGVkRW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrLk5lc3RlZEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVxdWlyZWRFbnVtXyA9IHRtcFJhdzsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICBhXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IHJlcXVpcmVkRW51bV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1Ob01hc2suTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRFbnVtIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzUmVxdWlyZWRFbnVtKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1Ob01hc2suTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRW51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzay5OZXN0ZWRFbnVtIGdldFJlcXVpcmVkRW51bSgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suTmVzdGVkRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suTmVzdGVkRW51bS5mb3JOdW1iZXIocmVxdWlyZWRFbnVtXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrLk5lc3RlZEVudW0uVU5TUEVDSUZJRUQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcXVpcmVkRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcXVpcmVkRW51bShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJlcXVpcmVkRW51bV8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1Ob01hc2suTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVxdWlyZWRFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICByZXF1aXJlZEVudW1fID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYV8gOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQSBkdW1teSBvcHRpb25hbCBmaWVsZC4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEEgZHVtbXkgb3B0aW9uYWwgZmllbGQuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0QSgpIHsKICAgICAgICByZXR1cm4gYV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEEgZHVtbXkgb3B0aW9uYWwgZmllbGQuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEEoaW50IHZhbHVlKSB7CgogICAgICAgIGFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBIGR1bW15IG9wdGlvbmFsIGZpZWxkLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGFfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzaygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlcXVpcmVkRW51bU5vTWFzaz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0UmVxdWlyZWRFbnVtTm9NYXNrPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdFJlcXVpcmVkRW51bU5vTWFzayBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXF1aXJlZEVudW1Ob01hc2s+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlcXVpcmVkRW51bU5vTWFzaz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFJlcXVpcmVkRW51bU11bHRpT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBJbnRlbnRpb25hbGx5IHBsYWNlZCBpbiBkZXNjZW5kaW5nIGZpZWxkIG51bWJlciB0byBmb3JjZSBzb3J0aW5nIGluIGNsb3NlZAogICAgICogZW51bSB2ZXJpZmljYXRpb24uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1JlcXVpcmVkRW51bTQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEludGVudGlvbmFsbHkgcGxhY2VkIGluIGRlc2NlbmRpbmcgZmllbGQgbnVtYmVyIHRvIGZvcmNlIHNvcnRpbmcgaW4gY2xvc2VkCiAgICAgKiBlbnVtIHZlcmlmaWNhdGlvbi4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRW51bTQuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpLk5lc3RlZEVudW0gZ2V0UmVxdWlyZWRFbnVtNCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYV8zID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNBMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhXzMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGEzLgogICAgICovCiAgICBpbnQgZ2V0QTMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRFbnVtMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUmVxdWlyZWRFbnVtMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bV8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEVudW0yLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtIGdldFJlcXVpcmVkRW51bTIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSByZXF1aXJlZF9lbnVtXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRFbnVtMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUmVxdWlyZWRFbnVtMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVxdWlyZWRfZW51bV8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEVudW0xLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIGdldFJlcXVpcmVkRW51bTEoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFJlcXVpcmVkRW51bU11bHRpIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aSkKICAgICAgVGVzdFJlcXVpcmVkRW51bU11bHRpT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0UmVxdWlyZWRFbnVtTXVsdGkubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFJlcXVpcmVkRW51bU11bHRpKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFJlcXVpcmVkRW51bU11bHRpKCkgewogICAgICByZXF1aXJlZEVudW00XyA9IDA7CiAgICAgIHJlcXVpcmVkRW51bTJfID0gMDsKICAgICAgcmVxdWlyZWRFbnVtMV8gPSA0OwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RSZXF1aXJlZEVudW1NdWx0aSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEVudW1NdWx0aV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEVudW1NdWx0aV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtfQogICAgICovCiAgICBwdWJsaWMgZW51bSBOZXN0ZWRFbnVtCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgICAvKioKICAgICAgICogPGNvZGU+VU5TUEVDSUZJRUQgPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIFVOU1BFQ0lGSUVEKDApLAogICAgICAvKioKICAgICAgICogPGNvZGU+Rk9PID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBGT08oMSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEJBUigyKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBWiA9IDEwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVooMTAwKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlVOU1BFQ0lGSUVEID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlNQRUNJRklFRF9WQUxVRSA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19WQUxVRSA9IDE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9WQUxVRSA9IDI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVogPSAxMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFaX1ZBTFVFID0gMTAwOwoKCiAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAwOiByZXR1cm4gVU5TUEVDSUZJRUQ7CiAgICAgICAgICBjYXNlIDE6IHJldHVybiBGT087CiAgICAgICAgICBjYXNlIDI6IHJldHVybiBCQVI7CiAgICAgICAgICBjYXNlIDEwMDogcmV0dXJuIEJBWjsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE5lc3RlZEVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBOZXN0ZWRFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIE5lc3RlZEVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIE5lc3RlZEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBOZXN0ZWRFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBOZXN0ZWRFbnVtKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpLk5lc3RlZEVudW0pCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUVVJUkVEX0VOVU1fNF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBpbnQgcmVxdWlyZWRFbnVtNF8gPSAwOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogSW50ZW50aW9uYWxseSBwbGFjZWQgaW4gZGVzY2VuZGluZyBmaWVsZCBudW1iZXIgdG8gZm9yY2Ugc29ydGluZyBpbiBjbG9zZWQKICAgICAqIGVudW0gdmVyaWZpY2F0aW9uLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXF1aXJlZEVudW00IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW00KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBJbnRlbnRpb25hbGx5IHBsYWNlZCBpbiBkZXNjZW5kaW5nIGZpZWxkIG51bWJlciB0byBmb3JjZSBzb3J0aW5nIGluIGNsb3NlZAogICAgICogZW51bSB2ZXJpZmljYXRpb24uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEVudW00LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtIGdldFJlcXVpcmVkRW51bTQoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpLk5lc3RlZEVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuTmVzdGVkRW51bS5mb3JOdW1iZXIocmVxdWlyZWRFbnVtNF8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtLlVOU1BFQ0lGSUVEIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFfM19GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBpbnQgYTNfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYV8zID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYV8zID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRBMygpIHsKICAgICAgcmV0dXJuIGEzXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFVSVJFRF9FTlVNXzJfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgaW50IHJlcXVpcmVkRW51bTJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXF1aXJlZEVudW0yIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW0yKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRW51bTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpLk5lc3RlZEVudW0gZ2V0UmVxdWlyZWRFbnVtMigpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtLmZvck51bWJlcihyZXF1aXJlZEVudW0yXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpLk5lc3RlZEVudW0uVU5TUEVDSUZJRUQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRVUlSRURfRU5VTV8xX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCByZXF1aXJlZEVudW0xXyA9IDQ7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSByZXF1aXJlZF9lbnVtXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRFbnVtMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzUmVxdWlyZWRFbnVtMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVxdWlyZWRfZW51bV8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEVudW0xLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIGdldFJlcXVpcmVkRW51bTEoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIocmVxdWlyZWRFbnVtMV8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLkZPUkVJR05fRk9PIDogcmVzdWx0OwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmICghaGFzUmVxdWlyZWRFbnVtNCgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFoYXNSZXF1aXJlZEVudW0yKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc1JlcXVpcmVkRW51bTEoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgxLCByZXF1aXJlZEVudW0xXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgyLCByZXF1aXJlZEVudW0yXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMywgYTNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDQsIHJlcXVpcmVkRW51bTRfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDEsIHJlcXVpcmVkRW51bTFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMiwgcmVxdWlyZWRFbnVtMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMywgYTNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoNCwgcmVxdWlyZWRFbnVtNF8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSkgb2JqOwoKICAgICAgaWYgKGhhc1JlcXVpcmVkRW51bTQoKSAhPSBvdGhlci5oYXNSZXF1aXJlZEVudW00KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1JlcXVpcmVkRW51bTQoKSkgewogICAgICAgIGlmIChyZXF1aXJlZEVudW00XyAhPSBvdGhlci5yZXF1aXJlZEVudW00XykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNBMygpICE9IG90aGVyLmhhc0EzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0EzKCkpIHsKICAgICAgICBpZiAoZ2V0QTMoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRBMygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1JlcXVpcmVkRW51bTIoKSAhPSBvdGhlci5oYXNSZXF1aXJlZEVudW0yKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1JlcXVpcmVkRW51bTIoKSkgewogICAgICAgIGlmIChyZXF1aXJlZEVudW0yXyAhPSBvdGhlci5yZXF1aXJlZEVudW0yXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNSZXF1aXJlZEVudW0xKCkgIT0gb3RoZXIuaGFzUmVxdWlyZWRFbnVtMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNSZXF1aXJlZEVudW0xKCkpIHsKICAgICAgICBpZiAocmVxdWlyZWRFbnVtMV8gIT0gb3RoZXIucmVxdWlyZWRFbnVtMV8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNSZXF1aXJlZEVudW00KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVFVSVJFRF9FTlVNXzRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcXVpcmVkRW51bTRfOwogICAgICB9CiAgICAgIGlmIChoYXNBMygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQV8zX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBMygpOwogICAgICB9CiAgICAgIGlmIChoYXNSZXF1aXJlZEVudW0yKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVFVSVJFRF9FTlVNXzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcXVpcmVkRW51bTJfOwogICAgICB9CiAgICAgIGlmIChoYXNSZXF1aXJlZEVudW0xKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVFVSVJFRF9FTlVNXzFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcXVpcmVkRW51bTFfOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRFbnVtTXVsdGlfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkRW51bU11bHRpX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICByZXF1aXJlZEVudW00XyA9IDA7CiAgICAgICAgYTNfID0gMDsKICAgICAgICByZXF1aXJlZEVudW0yXyA9IDA7CiAgICAgICAgcmVxdWlyZWRFbnVtMV8gPSA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRFbnVtTXVsdGlfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5yZXF1aXJlZEVudW00XyA9IHJlcXVpcmVkRW51bTRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmEzXyA9IGEzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5yZXF1aXJlZEVudW0yXyA9IHJlcXVpcmVkRW51bTJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnJlcXVpcmVkRW51bTFfID0gcmVxdWlyZWRFbnVtMV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNSZXF1aXJlZEVudW00KCkpIHsKICAgICAgICAgIHNldFJlcXVpcmVkRW51bTQob3RoZXIuZ2V0UmVxdWlyZWRFbnVtNCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0EzKCkpIHsKICAgICAgICAgIHNldEEzKG90aGVyLmdldEEzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUmVxdWlyZWRFbnVtMigpKSB7CiAgICAgICAgICBzZXRSZXF1aXJlZEVudW0yKG90aGVyLmdldFJlcXVpcmVkRW51bTIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNSZXF1aXJlZEVudW0xKCkpIHsKICAgICAgICAgIHNldFJlcXVpcmVkRW51bTEob3RoZXIuZ2V0UmVxdWlyZWRFbnVtMSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghaGFzUmVxdWlyZWRFbnVtNCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzUmVxdWlyZWRFbnVtMigpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzUmVxdWlyZWRFbnVtMSgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVxdWlyZWRFbnVtMV8gPSB0bXBSYXc7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMiwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcXVpcmVkRW51bTJfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBhM18gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgMzI6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuTmVzdGVkRW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuTmVzdGVkRW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDQsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXF1aXJlZEVudW00XyA9IHRtcFJhdzsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IHJlcXVpcmVkRW51bTRfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEludGVudGlvbmFsbHkgcGxhY2VkIGluIGRlc2NlbmRpbmcgZmllbGQgbnVtYmVyIHRvIGZvcmNlIHNvcnRpbmcgaW4gY2xvc2VkCiAgICAgICAqIGVudW0gdmVyaWZpY2F0aW9uLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bTQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW00KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogSW50ZW50aW9uYWxseSBwbGFjZWQgaW4gZGVzY2VuZGluZyBmaWVsZCBudW1iZXIgdG8gZm9yY2Ugc29ydGluZyBpbiBjbG9zZWQKICAgICAgICogZW51bSB2ZXJpZmljYXRpb24uCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRW51bTQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtIGdldFJlcXVpcmVkRW51bTQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtLmZvck51bWJlcihyZXF1aXJlZEVudW00Xyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuTmVzdGVkRW51bS5VTlNQRUNJRklFRCA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogSW50ZW50aW9uYWxseSBwbGFjZWQgaW4gZGVzY2VuZGluZyBmaWVsZCBudW1iZXIgdG8gZm9yY2Ugc29ydGluZyBpbiBjbG9zZWQKICAgICAgICogZW51bSB2ZXJpZmljYXRpb24uCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVxdWlyZWRFbnVtNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcXVpcmVkRW51bTQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHJlcXVpcmVkRW51bTRfID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEludGVudGlvbmFsbHkgcGxhY2VkIGluIGRlc2NlbmRpbmcgZmllbGQgbnVtYmVyIHRvIGZvcmNlIHNvcnRpbmcgaW4gY2xvc2VkCiAgICAgICAqIGVudW0gdmVyaWZpY2F0aW9uLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcXVpcmVkRW51bTQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHJlcXVpcmVkRW51bTRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYTNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGFfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhXzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYTMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0QTMoKSB7CiAgICAgICAgcmV0dXJuIGEzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYV8zID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRBMyhpbnQgdmFsdWUpIHsKCiAgICAgICAgYTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhXzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBMygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgYTNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgcmVxdWlyZWRFbnVtMl8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW0yKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEVudW0yLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuTmVzdGVkRW51bSBnZXRSZXF1aXJlZEVudW0yKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpLk5lc3RlZEVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuTmVzdGVkRW51bS5mb3JOdW1iZXIocmVxdWlyZWRFbnVtMl8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpLk5lc3RlZEVudW0uVU5TUEVDSUZJRUQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtXzIgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXF1aXJlZEVudW0yIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVxdWlyZWRFbnVtMihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgcmVxdWlyZWRFbnVtMl8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcXVpcmVkRW51bTIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIHJlcXVpcmVkRW51bTJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgcmVxdWlyZWRFbnVtMV8gPSA0OwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcXVpcmVkX2VudW1fMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW0xKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcXVpcmVkX2VudW1fMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEVudW0xLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBnZXRSZXF1aXJlZEVudW0xKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIocmVxdWlyZWRFbnVtMV8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uRk9SRUlHTl9GT08gOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSByZXF1aXJlZF9lbnVtXzEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXF1aXJlZEVudW0xIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVxdWlyZWRFbnVtMShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgcmVxdWlyZWRFbnVtMV8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcXVpcmVkX2VudW1fMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcXVpcmVkRW51bTEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIHJlcXVpcmVkRW51bTFfID0gNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTXVsdGkpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXF1aXJlZEVudW1NdWx0aT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0UmVxdWlyZWRFbnVtTXVsdGk+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UmVxdWlyZWRFbnVtTXVsdGkgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVxdWlyZWRFbnVtTXVsdGk+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlcXVpcmVkRW51bU11bHRpPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RSZXF1aXJlZE5vTWFza011bHRpT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEludGVudGlvbmFsbHkgcGxhY2VkIGluIGRlc2NlbmRpbmcgZmllbGQgbnVtYmVyIHRvIGZvcmNlIHNvcnRpbmcgaW4gY2xvc2VkCiAgICAgKiBlbnVtIHZlcmlmaWNhdGlvbi4gQWxzbywgdXNpbmcgbGFyZ2UgZmllbGQgbnVtYmVycyB0byB1c2UgdGFnIG9ubHkKICAgICAqIG1hdGNoaW5nIGZvciByZXF1aXJlZCBmaWVsZHMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDMyIHJlcXVpcmVkX2ZpeGVkMzJfODAgPSA4MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRml4ZWQzMjgwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNSZXF1aXJlZEZpeGVkMzI4MCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogSW50ZW50aW9uYWxseSBwbGFjZWQgaW4gZGVzY2VuZGluZyBmaWVsZCBudW1iZXIgdG8gZm9yY2Ugc29ydGluZyBpbiBjbG9zZWQKICAgICAqIGVudW0gdmVyaWZpY2F0aW9uLiBBbHNvLCB1c2luZyBsYXJnZSBmaWVsZCBudW1iZXJzIHRvIHVzZSB0YWcgb25seQogICAgICogbWF0Y2hpbmcgZm9yIHJlcXVpcmVkIGZpZWxkcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkMzIgcmVxdWlyZWRfZml4ZWQzMl84MCA9IDgwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRml4ZWQzMjgwLgogICAgICovCiAgICBpbnQgZ2V0UmVxdWlyZWRGaXhlZDMyODAoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkMzIgcmVxdWlyZWRfZml4ZWQzMl83MCA9IDcwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRGaXhlZDMyNzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1JlcXVpcmVkRml4ZWQzMjcwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkMzIgcmVxdWlyZWRfZml4ZWQzMl83MCA9IDcwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRml4ZWQzMjcwLgogICAgICovCiAgICBpbnQgZ2V0UmVxdWlyZWRGaXhlZDMyNzAoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bTY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW02NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRFbnVtNjQuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSBnZXRSZXF1aXJlZEVudW02NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1JlcXVpcmVkRW51bTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEVudW00LgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0gZ2V0UmVxdWlyZWRFbnVtNCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYV8zID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNBMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhXzMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGEzLgogICAgICovCiAgICBpbnQgZ2V0QTMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXF1aXJlZEVudW0yIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW0yKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRFbnVtMi4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIGdldFJlcXVpcmVkRW51bTIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSByZXF1aXJlZF9lbnVtXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRFbnVtMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUmVxdWlyZWRFbnVtMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVxdWlyZWRfZW51bV8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEVudW0xLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIGdldFJlcXVpcmVkRW51bTEoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGl9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0UmVxdWlyZWROb01hc2tNdWx0aSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSkKICAgICAgVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGlPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RSZXF1aXJlZE5vTWFza011bHRpLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RSZXF1aXJlZE5vTWFza011bHRpKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkoKSB7CiAgICAgIHJlcXVpcmVkRW51bTY0XyA9IDA7CiAgICAgIHJlcXVpcmVkRW51bTRfID0gMDsKICAgICAgcmVxdWlyZWRFbnVtMl8gPSAwOwogICAgICByZXF1aXJlZEVudW0xXyA9IDQ7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWROb01hc2tNdWx0aV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE5vTWFza011bHRpX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW19CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIE5lc3RlZEVudW0KICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5VTlNQRUNJRklFRCA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgVU5TUEVDSUZJRUQoMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5GT08gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEZPTygxKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQkFSKDIpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QkFaID0gMTAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEJBWigxMDApLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+VU5TUEVDSUZJRUQgPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOU1BFQ0lGSUVEX1ZBTFVFID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSX1ZBTFVFID0gMjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBWiA9IDEwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVpfVkFMVUUgPSAxMDA7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBVTlNQRUNJRklFRDsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIEZPTzsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIEJBUjsKICAgICAgICAgIGNhc2UgMTAwOiByZXR1cm4gQkFaOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIE5lc3RlZEVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxOZXN0ZWRFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgTmVzdGVkRW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gTmVzdGVkRW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTmVzdGVkRW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgTmVzdGVkRW51bShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0pCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUVVJUkVEX0ZJWEVEMzJfODBfRklFTERfTlVNQkVSID0gODA7CiAgICBwcml2YXRlIGludCByZXF1aXJlZEZpeGVkMzI4MF8gPSAwOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogSW50ZW50aW9uYWxseSBwbGFjZWQgaW4gZGVzY2VuZGluZyBmaWVsZCBudW1iZXIgdG8gZm9yY2Ugc29ydGluZyBpbiBjbG9zZWQKICAgICAqIGVudW0gdmVyaWZpY2F0aW9uLiBBbHNvLCB1c2luZyBsYXJnZSBmaWVsZCBudW1iZXJzIHRvIHVzZSB0YWcgb25seQogICAgICogbWF0Y2hpbmcgZm9yIHJlcXVpcmVkIGZpZWxkcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkMzIgcmVxdWlyZWRfZml4ZWQzMl84MCA9IDgwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRGaXhlZDMyODAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZEZpeGVkMzI4MCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogSW50ZW50aW9uYWxseSBwbGFjZWQgaW4gZGVzY2VuZGluZyBmaWVsZCBudW1iZXIgdG8gZm9yY2Ugc29ydGluZyBpbiBjbG9zZWQKICAgICAqIGVudW0gdmVyaWZpY2F0aW9uLiBBbHNvLCB1c2luZyBsYXJnZSBmaWVsZCBudW1iZXJzIHRvIHVzZSB0YWcgb25seQogICAgICogbWF0Y2hpbmcgZm9yIHJlcXVpcmVkIGZpZWxkcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkMzIgcmVxdWlyZWRfZml4ZWQzMl84MCA9IDgwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRml4ZWQzMjgwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcXVpcmVkRml4ZWQzMjgwKCkgewogICAgICByZXR1cm4gcmVxdWlyZWRGaXhlZDMyODBfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUVVJUkVEX0ZJWEVEMzJfNzBfRklFTERfTlVNQkVSID0gNzA7CiAgICBwcml2YXRlIGludCByZXF1aXJlZEZpeGVkMzI3MF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDMyIHJlcXVpcmVkX2ZpeGVkMzJfNzAgPSA3MDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRml4ZWQzMjcwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUmVxdWlyZWRGaXhlZDMyNzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQzMiByZXF1aXJlZF9maXhlZDMyXzcwID0gNzA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRGaXhlZDMyNzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVxdWlyZWRGaXhlZDMyNzAoKSB7CiAgICAgIHJldHVybiByZXF1aXJlZEZpeGVkMzI3MF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRVUlSRURfRU5VTV82NF9GSUVMRF9OVU1CRVIgPSA2NDsKICAgIHByaXZhdGUgaW50IHJlcXVpcmVkRW51bTY0XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bTY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW02NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRFbnVtNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSBnZXRSZXF1aXJlZEVudW02NCgpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bS5mb3JOdW1iZXIocmVxdWlyZWRFbnVtNjRfKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtLlVOU1BFQ0lGSUVEIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUVVJUkVEX0VOVU1fNF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBpbnQgcmVxdWlyZWRFbnVtNF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRFbnVtNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzUmVxdWlyZWRFbnVtNCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRW51bTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSBnZXRSZXF1aXJlZEVudW00KCkgewogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtLmZvck51bWJlcihyZXF1aXJlZEVudW00Xyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bS5VTlNQRUNJRklFRCA6IHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBXzNfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgaW50IGEzXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGFfMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0EzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGFfMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYTMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0QTMoKSB7CiAgICAgIHJldHVybiBhM187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRVUlSRURfRU5VTV8yX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGludCByZXF1aXJlZEVudW0yXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXF1aXJlZEVudW0yIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW0yKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRFbnVtMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIGdldFJlcXVpcmVkRW51bTIoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0uZm9yTnVtYmVyKHJlcXVpcmVkRW51bTJfKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtLlVOU1BFQ0lGSUVEIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUVVJUkVEX0VOVU1fMV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgcmVxdWlyZWRFbnVtMV8gPSA0OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcmVxdWlyZWRfZW51bV8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc1JlcXVpcmVkRW51bTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcXVpcmVkX2VudW1fMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRFbnVtMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBnZXRSZXF1aXJlZEVudW0xKCkgewogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uZm9yTnVtYmVyKHJlcXVpcmVkRW51bTFfKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5GT1JFSUdOX0ZPTyA6IHJlc3VsdDsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWhhc1JlcXVpcmVkRml4ZWQzMjgwKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc1JlcXVpcmVkRml4ZWQzMjcwKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc1JlcXVpcmVkRW51bTY0KCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWhhc1JlcXVpcmVkRW51bTQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzUmVxdWlyZWRFbnVtMigpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFoYXNSZXF1aXJlZEVudW0xKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMSwgcmVxdWlyZWRFbnVtMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMiwgcmVxdWlyZWRFbnVtMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDMsIGEzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSg0LCByZXF1aXJlZEVudW00Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSg2NCwgcmVxdWlyZWRFbnVtNjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDMyKDcwLCByZXF1aXJlZEZpeGVkMzI3MF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzIoODAsIHJlcXVpcmVkRml4ZWQzMjgwXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSgxLCByZXF1aXJlZEVudW0xXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDIsIHJlcXVpcmVkRW51bTJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDMsIGEzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDQsIHJlcXVpcmVkRW51bTRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoNjQsIHJlcXVpcmVkRW51bTY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkMzJTaXplKDcwLCByZXF1aXJlZEZpeGVkMzI3MF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGaXhlZDMyU2l6ZSg4MCwgcmVxdWlyZWRGaXhlZDMyODBfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkpIG9iajsKCiAgICAgIGlmIChoYXNSZXF1aXJlZEZpeGVkMzI4MCgpICE9IG90aGVyLmhhc1JlcXVpcmVkRml4ZWQzMjgwKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1JlcXVpcmVkRml4ZWQzMjgwKCkpIHsKICAgICAgICBpZiAoZ2V0UmVxdWlyZWRGaXhlZDMyODAoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRSZXF1aXJlZEZpeGVkMzI4MCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1JlcXVpcmVkRml4ZWQzMjcwKCkgIT0gb3RoZXIuaGFzUmVxdWlyZWRGaXhlZDMyNzAoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUmVxdWlyZWRGaXhlZDMyNzAoKSkgewogICAgICAgIGlmIChnZXRSZXF1aXJlZEZpeGVkMzI3MCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldFJlcXVpcmVkRml4ZWQzMjcwKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtNjQoKSAhPSBvdGhlci5oYXNSZXF1aXJlZEVudW02NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNSZXF1aXJlZEVudW02NCgpKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bTY0XyAhPSBvdGhlci5yZXF1aXJlZEVudW02NF8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtNCgpICE9IG90aGVyLmhhc1JlcXVpcmVkRW51bTQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtNCgpKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bTRfICE9IG90aGVyLnJlcXVpcmVkRW51bTRfKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0EzKCkgIT0gb3RoZXIuaGFzQTMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQTMoKSkgewogICAgICAgIGlmIChnZXRBMygpCiAgICAgICAgICAgICE9IG90aGVyLmdldEEzKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtMigpICE9IG90aGVyLmhhc1JlcXVpcmVkRW51bTIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtMigpKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bTJfICE9IG90aGVyLnJlcXVpcmVkRW51bTJfKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1JlcXVpcmVkRW51bTEoKSAhPSBvdGhlci5oYXNSZXF1aXJlZEVudW0xKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1JlcXVpcmVkRW51bTEoKSkgewogICAgICAgIGlmIChyZXF1aXJlZEVudW0xXyAhPSBvdGhlci5yZXF1aXJlZEVudW0xXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc1JlcXVpcmVkRml4ZWQzMjgwKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVFVSVJFRF9GSVhFRDMyXzgwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXF1aXJlZEZpeGVkMzI4MCgpOwogICAgICB9CiAgICAgIGlmIChoYXNSZXF1aXJlZEZpeGVkMzI3MCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVRVUlSRURfRklYRUQzMl83MF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVxdWlyZWRGaXhlZDMyNzAoKTsKICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtNjQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUVVJUkVEX0VOVU1fNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcXVpcmVkRW51bTY0XzsKICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtNCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVRVUlSRURfRU5VTV80X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXF1aXJlZEVudW00XzsKICAgICAgfQogICAgICBpZiAoaGFzQTMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFfM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QTMoKTsKICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVRVUlSRURfRU5VTV8yX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXF1aXJlZEVudW0yXzsKICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVRVUlSRURfRU5VTV8xX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXF1aXJlZEVudW0xXzsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWROb01hc2tNdWx0aV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWROb01hc2tNdWx0aV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgcmVxdWlyZWRGaXhlZDMyODBfID0gMDsKICAgICAgICByZXF1aXJlZEZpeGVkMzI3MF8gPSAwOwogICAgICAgIHJlcXVpcmVkRW51bTY0XyA9IDA7CiAgICAgICAgcmVxdWlyZWRFbnVtNF8gPSAwOwogICAgICAgIGEzXyA9IDA7CiAgICAgICAgcmVxdWlyZWRFbnVtMl8gPSAwOwogICAgICAgIHJlcXVpcmVkRW51bTFfID0gNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGlfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucmVxdWlyZWRGaXhlZDMyODBfID0gcmVxdWlyZWRGaXhlZDMyODBfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnJlcXVpcmVkRml4ZWQzMjcwXyA9IHJlcXVpcmVkRml4ZWQzMjcwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5yZXF1aXJlZEVudW02NF8gPSByZXF1aXJlZEVudW02NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucmVxdWlyZWRFbnVtNF8gPSByZXF1aXJlZEVudW00XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5hM18gPSBhM187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucmVxdWlyZWRFbnVtMl8gPSByZXF1aXJlZEVudW0yXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5yZXF1aXJlZEVudW0xXyA9IHJlcXVpcmVkRW51bTFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNSZXF1aXJlZEZpeGVkMzI4MCgpKSB7CiAgICAgICAgICBzZXRSZXF1aXJlZEZpeGVkMzI4MChvdGhlci5nZXRSZXF1aXJlZEZpeGVkMzI4MCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1JlcXVpcmVkRml4ZWQzMjcwKCkpIHsKICAgICAgICAgIHNldFJlcXVpcmVkRml4ZWQzMjcwKG90aGVyLmdldFJlcXVpcmVkRml4ZWQzMjcwKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUmVxdWlyZWRFbnVtNjQoKSkgewogICAgICAgICAgc2V0UmVxdWlyZWRFbnVtNjQob3RoZXIuZ2V0UmVxdWlyZWRFbnVtNjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNSZXF1aXJlZEVudW00KCkpIHsKICAgICAgICAgIHNldFJlcXVpcmVkRW51bTQob3RoZXIuZ2V0UmVxdWlyZWRFbnVtNCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0EzKCkpIHsKICAgICAgICAgIHNldEEzKG90aGVyLmdldEEzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUmVxdWlyZWRFbnVtMigpKSB7CiAgICAgICAgICBzZXRSZXF1aXJlZEVudW0yKG90aGVyLmdldFJlcXVpcmVkRW51bTIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNSZXF1aXJlZEVudW0xKCkpIHsKICAgICAgICAgIHNldFJlcXVpcmVkRW51bTEob3RoZXIuZ2V0UmVxdWlyZWRFbnVtMSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghaGFzUmVxdWlyZWRGaXhlZDMyODAoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWhhc1JlcXVpcmVkRml4ZWQzMjcwKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFoYXNSZXF1aXJlZEVudW02NCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzUmVxdWlyZWRFbnVtNCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzUmVxdWlyZWRFbnVtMigpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzUmVxdWlyZWRFbnVtMSgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVxdWlyZWRFbnVtMV8gPSB0bXBSYXc7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDIsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXF1aXJlZEVudW0yXyA9IHRtcFJhdzsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgYTNfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQKICAgICAgICAgICAgICBjYXNlIDMyOiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoNCwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcXVpcmVkRW51bTRfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzIKICAgICAgICAgICAgICBjYXNlIDUxMjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDY0LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVxdWlyZWRFbnVtNjRfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTEyCiAgICAgICAgICAgICAgY2FzZSA1NjU6IHsKICAgICAgICAgICAgICAgIHJlcXVpcmVkRml4ZWQzMjcwXyA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTY1CiAgICAgICAgICAgICAgY2FzZSA2NDU6IHsKICAgICAgICAgICAgICAgIHJlcXVpcmVkRml4ZWQzMjgwXyA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjQ1CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IHJlcXVpcmVkRml4ZWQzMjgwXyA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBJbnRlbnRpb25hbGx5IHBsYWNlZCBpbiBkZXNjZW5kaW5nIGZpZWxkIG51bWJlciB0byBmb3JjZSBzb3J0aW5nIGluIGNsb3NlZAogICAgICAgKiBlbnVtIHZlcmlmaWNhdGlvbi4gQWxzbywgdXNpbmcgbGFyZ2UgZmllbGQgbnVtYmVycyB0byB1c2UgdGFnIG9ubHkKICAgICAgICogbWF0Y2hpbmcgZm9yIHJlcXVpcmVkIGZpZWxkcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkMzIgcmVxdWlyZWRfZml4ZWQzMl84MCA9IDgwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXF1aXJlZEZpeGVkMzI4MCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1JlcXVpcmVkRml4ZWQzMjgwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogSW50ZW50aW9uYWxseSBwbGFjZWQgaW4gZGVzY2VuZGluZyBmaWVsZCBudW1iZXIgdG8gZm9yY2Ugc29ydGluZyBpbiBjbG9zZWQKICAgICAgICogZW51bSB2ZXJpZmljYXRpb24uIEFsc28sIHVzaW5nIGxhcmdlIGZpZWxkIG51bWJlcnMgdG8gdXNlIHRhZyBvbmx5CiAgICAgICAqIG1hdGNoaW5nIGZvciByZXF1aXJlZCBmaWVsZHMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDMyIHJlcXVpcmVkX2ZpeGVkMzJfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRml4ZWQzMjgwLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFJlcXVpcmVkRml4ZWQzMjgwKCkgewogICAgICAgIHJldHVybiByZXF1aXJlZEZpeGVkMzI4MF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEludGVudGlvbmFsbHkgcGxhY2VkIGluIGRlc2NlbmRpbmcgZmllbGQgbnVtYmVyIHRvIGZvcmNlIHNvcnRpbmcgaW4gY2xvc2VkCiAgICAgICAqIGVudW0gdmVyaWZpY2F0aW9uLiBBbHNvLCB1c2luZyBsYXJnZSBmaWVsZCBudW1iZXJzIHRvIHVzZSB0YWcgb25seQogICAgICAgKiBtYXRjaGluZyBmb3IgcmVxdWlyZWQgZmllbGRzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQzMiByZXF1aXJlZF9maXhlZDMyXzgwID0gODA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcXVpcmVkRml4ZWQzMjgwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVxdWlyZWRGaXhlZDMyODAoaW50IHZhbHVlKSB7CgogICAgICAgIHJlcXVpcmVkRml4ZWQzMjgwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogSW50ZW50aW9uYWxseSBwbGFjZWQgaW4gZGVzY2VuZGluZyBmaWVsZCBudW1iZXIgdG8gZm9yY2Ugc29ydGluZyBpbiBjbG9zZWQKICAgICAgICogZW51bSB2ZXJpZmljYXRpb24uIEFsc28sIHVzaW5nIGxhcmdlIGZpZWxkIG51bWJlcnMgdG8gdXNlIHRhZyBvbmx5CiAgICAgICAqIG1hdGNoaW5nIGZvciByZXF1aXJlZCBmaWVsZHMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDMyIHJlcXVpcmVkX2ZpeGVkMzJfODAgPSA4MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVxdWlyZWRGaXhlZDMyODAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHJlcXVpcmVkRml4ZWQzMjgwXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IHJlcXVpcmVkRml4ZWQzMjcwXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBmaXhlZDMyIHJlcXVpcmVkX2ZpeGVkMzJfNzAgPSA3MDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRGaXhlZDMyNzAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZEZpeGVkMzI3MCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGZpeGVkMzIgcmVxdWlyZWRfZml4ZWQzMl83MCA9IDcwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRGaXhlZDMyNzAuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVxdWlyZWRGaXhlZDMyNzAoKSB7CiAgICAgICAgcmV0dXJuIHJlcXVpcmVkRml4ZWQzMjcwXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQzMiByZXF1aXJlZF9maXhlZDMyXzcwID0gNzA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcXVpcmVkRml4ZWQzMjcwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVxdWlyZWRGaXhlZDMyNzAoaW50IHZhbHVlKSB7CgogICAgICAgIHJlcXVpcmVkRml4ZWQzMjcwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZml4ZWQzMiByZXF1aXJlZF9maXhlZDMyXzcwID0gNzA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcXVpcmVkRml4ZWQzMjcwKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICByZXF1aXJlZEZpeGVkMzI3MF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCByZXF1aXJlZEVudW02NF8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bV82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXF1aXJlZEVudW02NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc1JlcXVpcmVkRW51bTY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bV82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRFbnVtNjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0gZ2V0UmVxdWlyZWRFbnVtNjQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bS5mb3JOdW1iZXIocmVxdWlyZWRFbnVtNjRfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0uVU5TUEVDSUZJRUQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVxdWlyZWRFbnVtNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXF1aXJlZEVudW02NChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICByZXF1aXJlZEVudW02NF8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bV82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXF1aXJlZEVudW02NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgcmVxdWlyZWRFbnVtNjRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgcmVxdWlyZWRFbnVtNF8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bV80ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRFbnVtNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc1JlcXVpcmVkRW51bTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtXzQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRFbnVtNC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSBnZXRSZXF1aXJlZEVudW00KCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0uZm9yTnVtYmVyKHJlcXVpcmVkRW51bTRfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0uVU5TUEVDSUZJRUQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcXVpcmVkRW51bTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXF1aXJlZEVudW00KHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIHJlcXVpcmVkRW51bTRfID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcXVpcmVkRW51bTQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIHJlcXVpcmVkRW51bTRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYTNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGFfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhXzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYTMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0QTMoKSB7CiAgICAgICAgcmV0dXJuIGEzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYV8zID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRBMyhpbnQgdmFsdWUpIHsKCiAgICAgICAgYTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhXzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBMygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgYTNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgcmVxdWlyZWRFbnVtMl8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0gcmVxdWlyZWRfZW51bV8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRFbnVtMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc1JlcXVpcmVkRW51bTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSByZXF1aXJlZF9lbnVtXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRFbnVtMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSBnZXRSZXF1aXJlZEVudW0yKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0uZm9yTnVtYmVyKHJlcXVpcmVkRW51bTJfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLk5lc3RlZEVudW0uVU5TUEVDSUZJRUQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcXVpcmVkRW51bTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXF1aXJlZEVudW0yKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIHJlcXVpcmVkRW51bTJfID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5OZXN0ZWRFbnVtIHJlcXVpcmVkX2VudW1fMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcXVpcmVkRW51bTIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIHJlcXVpcmVkRW51bTJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgcmVxdWlyZWRFbnVtMV8gPSA0OwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcXVpcmVkX2VudW1fMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW0xKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcXVpcmVkX2VudW1fMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEVudW0xLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBnZXRSZXF1aXJlZEVudW0xKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIocmVxdWlyZWRFbnVtMV8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uRk9SRUlHTl9GT08gOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSByZXF1aXJlZF9lbnVtXzEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXF1aXJlZEVudW0xIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVxdWlyZWRFbnVtMShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgcmVxdWlyZWRFbnVtMV8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHJlcXVpcmVkX2VudW1fMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcXVpcmVkRW51bTEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIHJlcXVpcmVkRW51bTFfID0gNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVxdWlyZWROb01hc2tNdWx0aT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0UmVxdWlyZWROb01hc2tNdWx0aT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RSZXF1aXJlZE5vTWFza011bHRpIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlcXVpcmVkTm9NYXNrTXVsdGk+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlcXVpcmVkTm9NYXNrTXVsdGk+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0UmVxdWlyZWRPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNBKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgKi8KICAgIGludCBnZXRBKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEdW1teTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTIuCiAgICAgKi8KICAgIGludCBnZXREdW1teTIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGIgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBiID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICovCiAgICBpbnQgZ2V0QigpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFBhZCB0aGUgZmllbGQgY291bnQgdG8gMzIgc28gdGhhdCB3ZSBjYW4gdGVzdCB0aGF0IElzSW5pdGlhbGl6ZWQoKQogICAgICogcHJvcGVybHkgY2hlY2tzIG11bHRpcGxlIGVsZW1lbnRzIG9mIGhhc19iaXRzXy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15NCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0R1bW15NCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUGFkIHRoZSBmaWVsZCBjb3VudCB0byAzMiBzbyB0aGF0IHdlIGNhbiB0ZXN0IHRoYXQgSXNJbml0aWFsaXplZCgpCiAgICAgKiBwcm9wZXJseSBjaGVja3MgbXVsdGlwbGUgZWxlbWVudHMgb2YgaGFzX2JpdHNfLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTQuCiAgICAgKi8KICAgIGludCBnZXREdW1teTQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15NSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0R1bW15NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTUgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15NS4KICAgICAqLwogICAgaW50IGdldER1bW15NSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk2ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRHVtbXk2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15NiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXk2LgogICAgICovCiAgICBpbnQgZ2V0RHVtbXk2KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTcgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXk3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEdW1teTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk3ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTcuCiAgICAgKi8KICAgIGludCBnZXREdW1teTcoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15OCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0R1bW15OCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTggPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15OC4KICAgICAqLwogICAgaW50IGdldER1bW15OCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk5ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRHVtbXk5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15OSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXk5LgogICAgICovCiAgICBpbnQgZ2V0RHVtbXk5KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTEwID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEdW1teTEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTEwLgogICAgICovCiAgICBpbnQgZ2V0RHVtbXkxMCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxMSA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkxMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRHVtbXkxMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTExID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkxMS4KICAgICAqLwogICAgaW50IGdldER1bW15MTEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTIgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0R1bW15MTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTIuCiAgICAgKi8KICAgIGludCBnZXREdW1teTEyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTEzID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTEzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEdW1teTEzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTEzLgogICAgICovCiAgICBpbnQgZ2V0RHVtbXkxMygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxNCA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkxNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRHVtbXkxNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE0ID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkxNC4KICAgICAqLwogICAgaW50IGdldER1bW15MTQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTUgPSAxNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0R1bW15MTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxNSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTUuCiAgICAgKi8KICAgIGludCBnZXREdW1teTE1KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE2ID0gMTY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTE2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEdW1teTE2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTE2LgogICAgICovCiAgICBpbnQgZ2V0RHVtbXkxNigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxNyA9IDE3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkxNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRHVtbXkxNygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE3ID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkxNy4KICAgICAqLwogICAgaW50IGdldER1bW15MTcoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTggPSAxODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MTggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0R1bW15MTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxOCA9IDE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTguCiAgICAgKi8KICAgIGludCBnZXREdW1teTE4KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE5ID0gMTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTE5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEdW1teTE5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTkgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTE5LgogICAgICovCiAgICBpbnQgZ2V0RHVtbXkxOSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyMCA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkyMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRHVtbXkyMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIwID0gMjA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkyMC4KICAgICAqLwogICAgaW50IGdldER1bW15MjAoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjEgPSAyMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0R1bW15MjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyMSA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjEuCiAgICAgKi8KICAgIGludCBnZXREdW1teTIxKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIyID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTIyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEdW1teTIyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjIgPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTIyLgogICAgICovCiAgICBpbnQgZ2V0RHVtbXkyMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyMyA9IDIzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRHVtbXkyMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIzID0gMjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkyMy4KICAgICAqLwogICAgaW50IGdldER1bW15MjMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjQgPSAyNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0R1bW15MjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyNCA9IDI0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjQuCiAgICAgKi8KICAgIGludCBnZXREdW1teTI0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI1ID0gMjU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTI1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEdW1teTI1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjUgPSAyNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTI1LgogICAgICovCiAgICBpbnQgZ2V0RHVtbXkyNSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyNiA9IDI2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRHVtbXkyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI2ID0gMjY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkyNi4KICAgICAqLwogICAgaW50IGdldER1bW15MjYoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjcgPSAyNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0R1bW15MjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyNyA9IDI3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjcuCiAgICAgKi8KICAgIGludCBnZXREdW1teTI3KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI4ID0gMjg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTI4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEdW1teTI4KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjggPSAyODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTI4LgogICAgICovCiAgICBpbnQgZ2V0RHVtbXkyOCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyOSA9IDI5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRHVtbXkyOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI5ID0gMjk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkyOS4KICAgICAqLwogICAgaW50IGdldER1bW15MjkoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MzAgPSAzMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0R1bW15MzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkzMCA9IDMwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MzAuCiAgICAgKi8KICAgIGludCBnZXREdW1teTMwKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTMxID0gMzE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTMxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEdW1teTMxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MzEgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTMxLgogICAgICovCiAgICBpbnQgZ2V0RHVtbXkzMSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkzMiA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRHVtbXkzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTMyID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkzMi4KICAgICAqLwogICAgaW50IGdldER1bW15MzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGMgPSAzMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0MoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgYyA9IDMzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGMuCiAgICAgKi8KICAgIGludCBnZXRDKCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQWRkIGFuIG9wdGlvbmFsIGNoaWxkIG1lc3NhZ2UgdG8gbWFrZSB0aGlzIG5vbi10cml2aWFsIGZvciBnby9wZGxhenkuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbiA9IDM0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxGb3JlaWduIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEZvcmVpZ24oKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFkZCBhbiBvcHRpb25hbCBjaGlsZCBtZXNzYWdlIHRvIG1ha2UgdGhpcyBub24tdHJpdmlhbCBmb3IgZ28vcGRsYXp5LgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ24gPSAzNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ24uCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0T3B0aW9uYWxGb3JlaWduKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBZGQgYW4gb3B0aW9uYWwgY2hpbGQgbWVzc2FnZSB0byBtYWtlIHRoaXMgbm9uLXRyaXZpYWwgZm9yIGdvL3BkbGF6eS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsRm9yZWlnbk9yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFdlIGhhdmUgc2VwYXJhdGUgbWVzc2FnZXMgZm9yIHRlc3RpbmcgcmVxdWlyZWQgZmllbGRzIGJlY2F1c2UgaXQncwogICAqIGFubm95aW5nIHRvIGhhdmUgdG8gZmlsbCBpbiByZXF1aXJlZCBmaWVsZHMgaW4gVGVzdFByb3RvIGluIG9yZGVyIHRvCiAgICogZG8gYW55dGhpbmcgd2l0aCBpdC4gIE5vdGUgdGhhdCB3ZSBkb24ndCBuZWVkIHRvIHRlc3QgZXZlcnkgdHlwZSBvZgogICAqIHJlcXVpcmVkIGZpbGVkIGJlY2F1c2UgdGhlIGNvZGUgb3V0cHV0IGlzIGJhc2ljYWxseSBpZGVudGljYWwgdG8KICAgKiBvcHRpb25hbCBmaWVsZHMgZm9yIGFsbCB0eXBlcy4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RSZXF1aXJlZCBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQpCiAgICAgIFRlc3RSZXF1aXJlZE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFJlcXVpcmVkLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RSZXF1aXJlZChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RSZXF1aXJlZCgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0UmVxdWlyZWQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMV87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBhXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRBKCkgewogICAgICByZXR1cm4gYV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVNTVkyX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGludCBkdW1teTJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15MigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15Mi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREdW1teTIoKSB7CiAgICAgIHJldHVybiBkdW1teTJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgaW50IGJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgYiA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBiID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEIoKSB7CiAgICAgIHJldHVybiBiXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVU1NWTRfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgaW50IGR1bW15NF8gPSAwOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUGFkIHRoZSBmaWVsZCBjb3VudCB0byAzMiBzbyB0aGF0IHdlIGNhbiB0ZXN0IHRoYXQgSXNJbml0aWFsaXplZCgpCiAgICAgKiBwcm9wZXJseSBjaGVja3MgbXVsdGlwbGUgZWxlbWVudHMgb2YgaGFzX2JpdHNfLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUGFkIHRoZSBmaWVsZCBjb3VudCB0byAzMiBzbyB0aGF0IHdlIGNhbiB0ZXN0IHRoYXQgSXNJbml0aWFsaXplZCgpCiAgICAgKiBwcm9wZXJseSBjaGVja3MgbXVsdGlwbGUgZWxlbWVudHMgb2YgaGFzX2JpdHNfLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXk0KCkgewogICAgICByZXR1cm4gZHVtbXk0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVU1NWTVfRklFTERfTlVNQkVSID0gNTsKICAgIHByaXZhdGUgaW50IGR1bW15NV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTUgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXk1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXk1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15NSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXk1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldER1bW15NSgpIHsKICAgICAgcmV0dXJuIGR1bW15NV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVNTVk2X0ZJRUxEX05VTUJFUiA9IDY7CiAgICBwcml2YXRlIGludCBkdW1teTZfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk2ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15NiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15NigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTYgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15Ni4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREdW1teTYoKSB7CiAgICAgIHJldHVybiBkdW1teTZfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERVTU1ZN19GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBpbnQgZHVtbXk3XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15NyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEdW1teTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk3ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXk3KCkgewogICAgICByZXR1cm4gZHVtbXk3XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVU1NWThfRklFTERfTlVNQkVSID0gODsKICAgIHByaXZhdGUgaW50IGR1bW15OF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTggPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXk4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXk4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15OCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXk4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldER1bW15OCgpIHsKICAgICAgcmV0dXJuIGR1bW15OF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVNTVk5X0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIGludCBkdW1teTlfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk5ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15OSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15OSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTkgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15OS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREdW1teTkoKSB7CiAgICAgIHJldHVybiBkdW1teTlfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERVTU1ZMTBfRklFTERfTlVNQkVSID0gMTA7CiAgICBwcml2YXRlIGludCBkdW1teTEwXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEdW1teTEwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTEwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldER1bW15MTAoKSB7CiAgICAgIHJldHVybiBkdW1teTEwXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVU1NWTExX0ZJRUxEX05VTUJFUiA9IDExOwogICAgcHJpdmF0ZSBpbnQgZHVtbXkxMV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTExID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTExIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkxMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTExID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkxMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREdW1teTExKCkgewogICAgICByZXR1cm4gZHVtbXkxMV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVNTVkxMl9GSUVMRF9OVU1CRVIgPSAxMjsKICAgIHByaXZhdGUgaW50IGR1bW15MTJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15MTIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkxMigpIHsKICAgICAgcmV0dXJuIGR1bW15MTJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERVTU1ZMTNfRklFTERfTlVNQkVSID0gMTM7CiAgICBwcml2YXRlIGludCBkdW1teTEzXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEdW1teTEzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTEzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldER1bW15MTMoKSB7CiAgICAgIHJldHVybiBkdW1teTEzXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVU1NWTE0X0ZJRUxEX05VTUJFUiA9IDE0OwogICAgcHJpdmF0ZSBpbnQgZHVtbXkxNF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE0ID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTE0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkxNCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE0ID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkxNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREdW1teTE0KCkgewogICAgICByZXR1cm4gZHVtbXkxNF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVNTVkxNV9GSUVMRF9OVU1CRVIgPSAxNTsKICAgIHByaXZhdGUgaW50IGR1bW15MTVfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxNSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15MTUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxNSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkxNSgpIHsKICAgICAgcmV0dXJuIGR1bW15MTVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERVTU1ZMTZfRklFTERfTlVNQkVSID0gMTY7CiAgICBwcml2YXRlIGludCBkdW1teTE2XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEdW1teTE2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTE2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldER1bW15MTYoKSB7CiAgICAgIHJldHVybiBkdW1teTE2XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVU1NWTE3X0ZJRUxEX05VTUJFUiA9IDE3OwogICAgcHJpdmF0ZSBpbnQgZHVtbXkxN18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE3ID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTE3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkxNygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE3ID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkxNy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREdW1teTE3KCkgewogICAgICByZXR1cm4gZHVtbXkxN187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVNTVkxOF9GSUVMRF9OVU1CRVIgPSAxODsKICAgIHByaXZhdGUgaW50IGR1bW15MThfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxOCA9IDE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15MTgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxOCA9IDE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkxOCgpIHsKICAgICAgcmV0dXJuIGR1bW15MThfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERVTU1ZMTlfRklFTERfTlVNQkVSID0gMTk7CiAgICBwcml2YXRlIGludCBkdW1teTE5XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTkgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEdW1teTE5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTkgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTE5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldER1bW15MTkoKSB7CiAgICAgIHJldHVybiBkdW1teTE5XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVU1NWTIwX0ZJRUxEX05VTUJFUiA9IDIwOwogICAgcHJpdmF0ZSBpbnQgZHVtbXkyMF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIwID0gMjA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTIwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyMCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwODAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIwID0gMjA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkyMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREdW1teTIwKCkgewogICAgICByZXR1cm4gZHVtbXkyMF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVNTVkyMV9GSUVMRF9OVU1CRVIgPSAyMTsKICAgIHByaXZhdGUgaW50IGR1bW15MjFfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyMSA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15MjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyMSA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkyMSgpIHsKICAgICAgcmV0dXJuIGR1bW15MjFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERVTU1ZMjJfRklFTERfTlVNQkVSID0gMjI7CiAgICBwcml2YXRlIGludCBkdW1teTIyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjIgPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEdW1teTIyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjIgPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTIyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldER1bW15MjIoKSB7CiAgICAgIHJldHVybiBkdW1teTIyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVU1NWTIzX0ZJRUxEX05VTUJFUiA9IDIzOwogICAgcHJpdmF0ZSBpbnQgZHVtbXkyM18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIzID0gMjM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTIzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyMygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIzID0gMjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkyMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREdW1teTIzKCkgewogICAgICByZXR1cm4gZHVtbXkyM187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVNTVkyNF9GSUVMRF9OVU1CRVIgPSAyNDsKICAgIHByaXZhdGUgaW50IGR1bW15MjRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyNCA9IDI0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15MjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyNCA9IDI0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkyNCgpIHsKICAgICAgcmV0dXJuIGR1bW15MjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERVTU1ZMjVfRklFTERfTlVNQkVSID0gMjU7CiAgICBwcml2YXRlIGludCBkdW1teTI1XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjUgPSAyNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEdW1teTI1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjUgPSAyNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTI1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldER1bW15MjUoKSB7CiAgICAgIHJldHVybiBkdW1teTI1XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVU1NWTI2X0ZJRUxEX05VTUJFUiA9IDI2OwogICAgcHJpdmF0ZSBpbnQgZHVtbXkyNl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI2ID0gMjY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTI2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyNigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI2ID0gMjY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkyNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREdW1teTI2KCkgewogICAgICByZXR1cm4gZHVtbXkyNl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVNTVkyN19GSUVMRF9OVU1CRVIgPSAyNzsKICAgIHByaXZhdGUgaW50IGR1bW15MjdfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyNyA9IDI3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15MjcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyNyA9IDI3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkyNygpIHsKICAgICAgcmV0dXJuIGR1bW15MjdfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERVTU1ZMjhfRklFTERfTlVNQkVSID0gMjg7CiAgICBwcml2YXRlIGludCBkdW1teTI4XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjggPSAyODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MjggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEdW1teTI4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjggPSAyODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTI4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldER1bW15MjgoKSB7CiAgICAgIHJldHVybiBkdW1teTI4XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVU1NWTI5X0ZJRUxEX05VTUJFUiA9IDI5OwogICAgcHJpdmF0ZSBpbnQgZHVtbXkyOV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI5ID0gMjk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTI5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyOSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI5ID0gMjk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkyOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREdW1teTI5KCkgewogICAgICByZXR1cm4gZHVtbXkyOV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVNTVkzMF9GSUVMRF9OVU1CRVIgPSAzMDsKICAgIHByaXZhdGUgaW50IGR1bW15MzBfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkzMCA9IDMwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkzMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15MzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDIwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkzMCA9IDMwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15MzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkzMCgpIHsKICAgICAgcmV0dXJuIGR1bW15MzBfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERVTU1ZMzFfRklFTERfTlVNQkVSID0gMzE7CiAgICBwcml2YXRlIGludCBkdW1teTMxXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MzEgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15MzEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEdW1teTMxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MzEgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTMxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldER1bW15MzEoKSB7CiAgICAgIHJldHVybiBkdW1teTMxXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVU1NWTMyX0ZJRUxEX05VTUJFUiA9IDMyOwogICAgcHJpdmF0ZSBpbnQgZHVtbXkzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTMyID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTMyID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREdW1teTMyKCkgewogICAgICByZXR1cm4gZHVtbXkzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ19GSUVMRF9OVU1CRVIgPSAzMzsKICAgIHByaXZhdGUgaW50IGNfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgYyA9IDMzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0MoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgYyA9IDMzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0QygpIHsKICAgICAgcmV0dXJuIGNfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0ZPUkVJR05fRklFTERfTlVNQkVSID0gMzQ7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxGb3JlaWduXzsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFkZCBhbiBvcHRpb25hbCBjaGlsZCBtZXNzYWdlIHRvIG1ha2UgdGhpcyBub24tdHJpdmlhbCBmb3IgZ28vcGRsYXp5LgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ24gPSAzNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRm9yZWlnbiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsRm9yZWlnbigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQWRkIGFuIG9wdGlvbmFsIGNoaWxkIG1lc3NhZ2UgdG8gbWFrZSB0aGlzIG5vbi10cml2aWFsIGZvciBnby9wZGxhenkuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbiA9IDM0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRm9yZWlnbi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0T3B0aW9uYWxGb3JlaWduKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsRm9yZWlnbl87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBZGQgYW4gb3B0aW9uYWwgY2hpbGQgbWVzc2FnZSB0byBtYWtlIHRoaXMgbm9uLXRyaXZpYWwgZm9yIGdvL3BkbGF6eS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduID0gMzQ7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbEZvcmVpZ25PckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEZvcmVpZ25fID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxGb3JlaWduXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWhhc0EoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghaGFzQigpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFoYXNDKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyLCBkdW1teTJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigzLCBiXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNCwgZHVtbXk0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNSwgZHVtbXk1Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNiwgZHVtbXk2Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNywgZHVtbXk3Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoOCwgZHVtbXk4Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoOSwgZHVtbXk5Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMTAsIGR1bW15MTBfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxMSwgZHVtbXkxMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEyLCBkdW1teTEyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMTMsIGR1bW15MTNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxNCwgZHVtbXkxNF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDE1LCBkdW1teTE1Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMTYsIGR1bW15MTZfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxNywgZHVtbXkxN18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDE4LCBkdW1teTE4Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMTksIGR1bW15MTlfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyMCwgZHVtbXkyMF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIxLCBkdW1teTIxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMjIsIGR1bW15MjJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyMywgZHVtbXkyM18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDI0LCBkdW1teTI0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMjUsIGR1bW15MjVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyNiwgZHVtbXkyNl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDI3LCBkdW1teTI3Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMjgsIGR1bW15MjhfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyOSwgZHVtbXkyOV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDMwLCBkdW1teTMwXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMzEsIGR1bW15MzFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigzMiwgZHVtbXkzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDMzLCBjXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgzNCwgZ2V0T3B0aW9uYWxGb3JlaWduKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIGFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIsIGR1bW15Ml8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMywgYl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNCwgZHVtbXk0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg1LCBkdW1teTVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDYsIGR1bW15Nl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNywgZHVtbXk3Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg4LCBkdW1teThfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDksIGR1bW15OV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMTAsIGR1bW15MTBfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDExLCBkdW1teTExXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxMiwgZHVtbXkxMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMTMsIGR1bW15MTNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDE0LCBkdW1teTE0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxNSwgZHVtbXkxNV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMTYsIGR1bW15MTZfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDE3LCBkdW1teTE3Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxOCwgZHVtbXkxOF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMTksIGR1bW15MTlfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIwLCBkdW1teTIwXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgyMSwgZHVtbXkyMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMjIsIGR1bW15MjJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIzLCBkdW1teTIzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgyNCwgZHVtbXkyNF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMjUsIGR1bW15MjVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDI2LCBkdW1teTI2Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgyNywgZHVtbXkyN18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMjgsIGR1bW15MjhfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDI5LCBkdW1teTI5Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgzMCwgZHVtbXkzMF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMzEsIGR1bW15MzFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDMyLCBkdW1teTMyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgzMywgY18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzNCwgZ2V0T3B0aW9uYWxGb3JlaWduKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCkgb2JqOwoKICAgICAgaWYgKGhhc0EoKSAhPSBvdGhlci5oYXNBKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgIGlmIChnZXRBKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0R1bW15MigpICE9IG90aGVyLmhhc0R1bW15MigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTIoKSkgewogICAgICAgIGlmIChnZXREdW1teTIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXREdW1teTIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNCKCkgIT0gb3RoZXIuaGFzQigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNCKCkpIHsKICAgICAgICBpZiAoZ2V0QigpCiAgICAgICAgICAgICE9IG90aGVyLmdldEIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTQoKSAhPSBvdGhlci5oYXNEdW1teTQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRHVtbXk0KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXk0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RHVtbXk0KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXk1KCkgIT0gb3RoZXIuaGFzRHVtbXk1KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0R1bW15NSgpKSB7CiAgICAgICAgaWYgKGdldER1bW15NSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15NSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0R1bW15NigpICE9IG90aGVyLmhhc0R1bW15NigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTYoKSkgewogICAgICAgIGlmIChnZXREdW1teTYoKQogICAgICAgICAgICAhPSBvdGhlci5nZXREdW1teTYoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTcoKSAhPSBvdGhlci5oYXNEdW1teTcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRHVtbXk3KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXk3KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RHVtbXk3KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXk4KCkgIT0gb3RoZXIuaGFzRHVtbXk4KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0R1bW15OCgpKSB7CiAgICAgICAgaWYgKGdldER1bW15OCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15OCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0R1bW15OSgpICE9IG90aGVyLmhhc0R1bW15OSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTkoKSkgewogICAgICAgIGlmIChnZXREdW1teTkoKQogICAgICAgICAgICAhPSBvdGhlci5nZXREdW1teTkoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTEwKCkgIT0gb3RoZXIuaGFzRHVtbXkxMCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTEwKCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkxMCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MTAoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTExKCkgIT0gb3RoZXIuaGFzRHVtbXkxMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTExKCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkxMSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MTEoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTEyKCkgIT0gb3RoZXIuaGFzRHVtbXkxMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTEyKCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkxMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MTIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTEzKCkgIT0gb3RoZXIuaGFzRHVtbXkxMygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTEzKCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkxMygpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MTMoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTE0KCkgIT0gb3RoZXIuaGFzRHVtbXkxNCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTE0KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkxNCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MTQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTE1KCkgIT0gb3RoZXIuaGFzRHVtbXkxNSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTE1KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkxNSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MTUoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTE2KCkgIT0gb3RoZXIuaGFzRHVtbXkxNigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTE2KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkxNigpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MTYoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTE3KCkgIT0gb3RoZXIuaGFzRHVtbXkxNygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTE3KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkxNygpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MTcoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTE4KCkgIT0gb3RoZXIuaGFzRHVtbXkxOCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTE4KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkxOCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MTgoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTE5KCkgIT0gb3RoZXIuaGFzRHVtbXkxOSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTE5KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkxOSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MTkoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTIwKCkgIT0gb3RoZXIuaGFzRHVtbXkyMCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTIwKCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkyMCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MjAoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTIxKCkgIT0gb3RoZXIuaGFzRHVtbXkyMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTIxKCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkyMSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MjEoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTIyKCkgIT0gb3RoZXIuaGFzRHVtbXkyMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTIyKCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkyMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MjIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTIzKCkgIT0gb3RoZXIuaGFzRHVtbXkyMygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTIzKCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkyMygpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MjMoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTI0KCkgIT0gb3RoZXIuaGFzRHVtbXkyNCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTI0KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkyNCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTI1KCkgIT0gb3RoZXIuaGFzRHVtbXkyNSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTI1KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkyNSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MjUoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTI2KCkgIT0gb3RoZXIuaGFzRHVtbXkyNigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTI2KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkyNigpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MjYoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTI3KCkgIT0gb3RoZXIuaGFzRHVtbXkyNygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTI3KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkyNygpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MjcoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTI4KCkgIT0gb3RoZXIuaGFzRHVtbXkyOCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTI4KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkyOCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MjgoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTI5KCkgIT0gb3RoZXIuaGFzRHVtbXkyOSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTI5KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkyOSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MjkoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTMwKCkgIT0gb3RoZXIuaGFzRHVtbXkzMCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTMwKCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkzMCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MzAoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTMxKCkgIT0gb3RoZXIuaGFzRHVtbXkzMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTMxKCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkzMSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MzEoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTMyKCkgIT0gb3RoZXIuaGFzRHVtbXkzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teTMyKCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkzMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldER1bW15MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNDKCkgIT0gb3RoZXIuaGFzQygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNDKCkpIHsKICAgICAgICBpZiAoZ2V0QygpCiAgICAgICAgICAgICE9IG90aGVyLmdldEMoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEZvcmVpZ24oKSAhPSBvdGhlci5oYXNPcHRpb25hbEZvcmVpZ24oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsRm9yZWlnbigpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxGb3JlaWduKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzQSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QSgpOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERVTU1ZMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RHVtbXkyKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0IoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEIoKTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXk0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEVU1NWTRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldER1bW15NCgpOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERVTU1ZNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RHVtbXk1KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0R1bW15NigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVNTVk2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREdW1teTYoKTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXk3KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEVU1NWTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldER1bW15NygpOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTgoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERVTU1ZOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RHVtbXk4KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0R1bW15OSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVNTVk5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREdW1teTkoKTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXkxMCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVNTVkxMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RHVtbXkxMCgpOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTExKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEVU1NWTExX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREdW1teTExKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0R1bW15MTIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERVTU1ZMTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldER1bW15MTIoKTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXkxMygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVNTVkxM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RHVtbXkxMygpOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTE0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEVU1NWTE0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREdW1teTE0KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0R1bW15MTUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERVTU1ZMTVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldER1bW15MTUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXkxNigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVNTVkxNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RHVtbXkxNigpOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTE3KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEVU1NWTE3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREdW1teTE3KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0R1bW15MTgoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERVTU1ZMThfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldER1bW15MTgoKTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXkxOSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVNTVkxOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RHVtbXkxOSgpOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTIwKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEVU1NWTIwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREdW1teTIwKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0R1bW15MjEoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERVTU1ZMjFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldER1bW15MjEoKTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXkyMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVNTVkyMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RHVtbXkyMigpOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTIzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEVU1NWTIzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREdW1teTIzKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0R1bW15MjQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERVTU1ZMjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldER1bW15MjQoKTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXkyNSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVNTVkyNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RHVtbXkyNSgpOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTI2KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEVU1NWTI2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREdW1teTI2KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0R1bW15MjcoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERVTU1ZMjdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldER1bW15MjcoKTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXkyOCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVNTVkyOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RHVtbXkyOCgpOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTI5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEVU1NWTI5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREdW1teTI5KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0R1bW15MzAoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERVTU1ZMzBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldER1bW15MzAoKTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXkzMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFVNTVkzMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RHVtbXkzMSgpOwogICAgICB9CiAgICAgIGlmIChoYXNEdW1teTMyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEVU1NWTMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREdW1teTMyKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0MoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIENfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEMoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxGb3JlaWduKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9GT1JFSUdOX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEZvcmVpZ24oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBXZSBoYXZlIHNlcGFyYXRlIG1lc3NhZ2VzIGZvciB0ZXN0aW5nIHJlcXVpcmVkIGZpZWxkcyBiZWNhdXNlIGl0J3MKICAgICAqIGFubm95aW5nIHRvIGhhdmUgdG8gZmlsbCBpbiByZXF1aXJlZCBmaWVsZHMgaW4gVGVzdFByb3RvIGluIG9yZGVyIHRvCiAgICAgKiBkbyBhbnl0aGluZyB3aXRoIGl0LiAgTm90ZSB0aGF0IHdlIGRvbid0IG5lZWQgdG8gdGVzdCBldmVyeSB0eXBlIG9mCiAgICAgKiByZXF1aXJlZCBmaWxlZCBiZWNhdXNlIHRoZSBjb2RlIG91dHB1dCBpcyBiYXNpY2FsbHkgaWRlbnRpY2FsIHRvCiAgICAgKiBvcHRpb25hbCBmaWVsZHMgZm9yIGFsbCB0eXBlcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldE9wdGlvbmFsRm9yZWlnbkZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgYml0RmllbGQxXyA9IDA7CiAgICAgICAgYV8gPSAwOwogICAgICAgIGR1bW15Ml8gPSAwOwogICAgICAgIGJfID0gMDsKICAgICAgICBkdW1teTRfID0gMDsKICAgICAgICBkdW1teTVfID0gMDsKICAgICAgICBkdW1teTZfID0gMDsKICAgICAgICBkdW1teTdfID0gMDsKICAgICAgICBkdW1teThfID0gMDsKICAgICAgICBkdW1teTlfID0gMDsKICAgICAgICBkdW1teTEwXyA9IDA7CiAgICAgICAgZHVtbXkxMV8gPSAwOwogICAgICAgIGR1bW15MTJfID0gMDsKICAgICAgICBkdW1teTEzXyA9IDA7CiAgICAgICAgZHVtbXkxNF8gPSAwOwogICAgICAgIGR1bW15MTVfID0gMDsKICAgICAgICBkdW1teTE2XyA9IDA7CiAgICAgICAgZHVtbXkxN18gPSAwOwogICAgICAgIGR1bW15MThfID0gMDsKICAgICAgICBkdW1teTE5XyA9IDA7CiAgICAgICAgZHVtbXkyMF8gPSAwOwogICAgICAgIGR1bW15MjFfID0gMDsKICAgICAgICBkdW1teTIyXyA9IDA7CiAgICAgICAgZHVtbXkyM18gPSAwOwogICAgICAgIGR1bW15MjRfID0gMDsKICAgICAgICBkdW1teTI1XyA9IDA7CiAgICAgICAgZHVtbXkyNl8gPSAwOwogICAgICAgIGR1bW15MjdfID0gMDsKICAgICAgICBkdW1teTI4XyA9IDA7CiAgICAgICAgZHVtbXkyOV8gPSAwOwogICAgICAgIGR1bW15MzBfID0gMDsKICAgICAgICBkdW1teTMxXyA9IDA7CiAgICAgICAgZHVtbXkzMl8gPSAwOwogICAgICAgIGNfID0gMDsKICAgICAgICBvcHRpb25hbEZvcmVpZ25fID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxGb3JlaWduQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBpZiAoYml0RmllbGQxXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDEocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5hXyA9IGFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmR1bW15Ml8gPSBkdW1teTJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmJfID0gYl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXk0XyA9IGR1bW15NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXk1XyA9IGR1bW15NV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXk2XyA9IGR1bW15Nl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXk3XyA9IGR1bW15N187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXk4XyA9IGR1bW15OF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXk5XyA9IGR1bW15OV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXkxMF8gPSBkdW1teTEwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kdW1teTExXyA9IGR1bW15MTFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmR1bW15MTJfID0gZHVtbXkxMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXkxM18gPSBkdW1teTEzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kdW1teTE0XyA9IGR1bW15MTRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmR1bW15MTVfID0gZHVtbXkxNV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXkxNl8gPSBkdW1teTE2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kdW1teTE3XyA9IGR1bW15MTdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmR1bW15MThfID0gZHVtbXkxOF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXkxOV8gPSBkdW1teTE5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kdW1teTIwXyA9IGR1bW15MjBfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmR1bW15MjFfID0gZHVtbXkyMV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXkyMl8gPSBkdW1teTIyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kdW1teTIzXyA9IGR1bW15MjNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmR1bW15MjRfID0gZHVtbXkyNF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXkyNV8gPSBkdW1teTI1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kdW1teTI2XyA9IGR1bW15MjZfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmR1bW15MjdfID0gZHVtbXkyN187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXkyOF8gPSBkdW1teTI4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kdW1teTI5XyA9IGR1bW15MjlfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDIwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmR1bW15MzBfID0gZHVtbXkzMF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4NDAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZHVtbXkzMV8gPSBkdW1teTMxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kdW1teTMyXyA9IGR1bW15MzJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDFfID0gYml0RmllbGQxXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQxXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDFfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5jXyA9IGNfOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsRm9yZWlnbl8gPSBvcHRpb25hbEZvcmVpZ25CdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbEZvcmVpZ25fCiAgICAgICAgICAgICAgOiBvcHRpb25hbEZvcmVpZ25CdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQxXyB8PSB0b19iaXRGaWVsZDFfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzQSgpKSB7CiAgICAgICAgICBzZXRBKG90aGVyLmdldEEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEdW1teTIoKSkgewogICAgICAgICAgc2V0RHVtbXkyKG90aGVyLmdldER1bW15MigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0IoKSkgewogICAgICAgICAgc2V0QihvdGhlci5nZXRCKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRHVtbXk0KCkpIHsKICAgICAgICAgIHNldER1bW15NChvdGhlci5nZXREdW1teTQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEdW1teTUoKSkgewogICAgICAgICAgc2V0RHVtbXk1KG90aGVyLmdldER1bW15NSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0R1bW15NigpKSB7CiAgICAgICAgICBzZXREdW1teTYob3RoZXIuZ2V0RHVtbXk2KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRHVtbXk3KCkpIHsKICAgICAgICAgIHNldER1bW15NyhvdGhlci5nZXREdW1teTcoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEdW1teTgoKSkgewogICAgICAgICAgc2V0RHVtbXk4KG90aGVyLmdldER1bW15OCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0R1bW15OSgpKSB7CiAgICAgICAgICBzZXREdW1teTkob3RoZXIuZ2V0RHVtbXk5KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRHVtbXkxMCgpKSB7CiAgICAgICAgICBzZXREdW1teTEwKG90aGVyLmdldER1bW15MTAoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEdW1teTExKCkpIHsKICAgICAgICAgIHNldER1bW15MTEob3RoZXIuZ2V0RHVtbXkxMSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0R1bW15MTIoKSkgewogICAgICAgICAgc2V0RHVtbXkxMihvdGhlci5nZXREdW1teTEyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRHVtbXkxMygpKSB7CiAgICAgICAgICBzZXREdW1teTEzKG90aGVyLmdldER1bW15MTMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEdW1teTE0KCkpIHsKICAgICAgICAgIHNldER1bW15MTQob3RoZXIuZ2V0RHVtbXkxNCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0R1bW15MTUoKSkgewogICAgICAgICAgc2V0RHVtbXkxNShvdGhlci5nZXREdW1teTE1KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRHVtbXkxNigpKSB7CiAgICAgICAgICBzZXREdW1teTE2KG90aGVyLmdldER1bW15MTYoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEdW1teTE3KCkpIHsKICAgICAgICAgIHNldER1bW15MTcob3RoZXIuZ2V0RHVtbXkxNygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0R1bW15MTgoKSkgewogICAgICAgICAgc2V0RHVtbXkxOChvdGhlci5nZXREdW1teTE4KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRHVtbXkxOSgpKSB7CiAgICAgICAgICBzZXREdW1teTE5KG90aGVyLmdldER1bW15MTkoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEdW1teTIwKCkpIHsKICAgICAgICAgIHNldER1bW15MjAob3RoZXIuZ2V0RHVtbXkyMCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0R1bW15MjEoKSkgewogICAgICAgICAgc2V0RHVtbXkyMShvdGhlci5nZXREdW1teTIxKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRHVtbXkyMigpKSB7CiAgICAgICAgICBzZXREdW1teTIyKG90aGVyLmdldER1bW15MjIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEdW1teTIzKCkpIHsKICAgICAgICAgIHNldER1bW15MjMob3RoZXIuZ2V0RHVtbXkyMygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0R1bW15MjQoKSkgewogICAgICAgICAgc2V0RHVtbXkyNChvdGhlci5nZXREdW1teTI0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRHVtbXkyNSgpKSB7CiAgICAgICAgICBzZXREdW1teTI1KG90aGVyLmdldER1bW15MjUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEdW1teTI2KCkpIHsKICAgICAgICAgIHNldER1bW15MjYob3RoZXIuZ2V0RHVtbXkyNigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0R1bW15MjcoKSkgewogICAgICAgICAgc2V0RHVtbXkyNyhvdGhlci5nZXREdW1teTI3KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRHVtbXkyOCgpKSB7CiAgICAgICAgICBzZXREdW1teTI4KG90aGVyLmdldER1bW15MjgoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEdW1teTI5KCkpIHsKICAgICAgICAgIHNldER1bW15Mjkob3RoZXIuZ2V0RHVtbXkyOSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0R1bW15MzAoKSkgewogICAgICAgICAgc2V0RHVtbXkzMChvdGhlci5nZXREdW1teTMwKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRHVtbXkzMSgpKSB7CiAgICAgICAgICBzZXREdW1teTMxKG90aGVyLmdldER1bW15MzEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEdW1teTMyKCkpIHsKICAgICAgICAgIHNldER1bW15MzIob3RoZXIuZ2V0RHVtbXkzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0MoKSkgewogICAgICAgICAgc2V0QyhvdGhlci5nZXRDKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxGb3JlaWduKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxGb3JlaWduKG90aGVyLmdldE9wdGlvbmFsRm9yZWlnbigpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghaGFzQSgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzQigpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghaGFzQygpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBhXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICBkdW1teTJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBiXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgICAgY2FzZSAzMjogewogICAgICAgICAgICAgICAgZHVtbXk0XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyCiAgICAgICAgICAgICAgY2FzZSA0MDogewogICAgICAgICAgICAgICAgZHVtbXk1XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQwCiAgICAgICAgICAgICAgY2FzZSA0ODogewogICAgICAgICAgICAgICAgZHVtbXk2XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQ4CiAgICAgICAgICAgICAgY2FzZSA1NjogewogICAgICAgICAgICAgICAgZHVtbXk3XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU2CiAgICAgICAgICAgICAgY2FzZSA2NDogewogICAgICAgICAgICAgICAgZHVtbXk4XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY0CiAgICAgICAgICAgICAgY2FzZSA3MjogewogICAgICAgICAgICAgICAgZHVtbXk5XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDcyCiAgICAgICAgICAgICAgY2FzZSA4MDogewogICAgICAgICAgICAgICAgZHVtbXkxMF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MAogICAgICAgICAgICAgIGNhc2UgODg6IHsKICAgICAgICAgICAgICAgIGR1bW15MTFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODgKICAgICAgICAgICAgICBjYXNlIDk2OiB7CiAgICAgICAgICAgICAgICBkdW1teTEyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk2CiAgICAgICAgICAgICAgY2FzZSAxMDQ6IHsKICAgICAgICAgICAgICAgIGR1bW15MTNfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA0CiAgICAgICAgICAgICAgY2FzZSAxMTI6IHsKICAgICAgICAgICAgICAgIGR1bW15MTRfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTEyCiAgICAgICAgICAgICAgY2FzZSAxMjA6IHsKICAgICAgICAgICAgICAgIGR1bW15MTVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTIwCiAgICAgICAgICAgICAgY2FzZSAxMjg6IHsKICAgICAgICAgICAgICAgIGR1bW15MTZfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTI4CiAgICAgICAgICAgICAgY2FzZSAxMzY6IHsKICAgICAgICAgICAgICAgIGR1bW15MTdfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTM2CiAgICAgICAgICAgICAgY2FzZSAxNDQ6IHsKICAgICAgICAgICAgICAgIGR1bW15MThfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ0CiAgICAgICAgICAgICAgY2FzZSAxNTI6IHsKICAgICAgICAgICAgICAgIGR1bW15MTlfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTUyCiAgICAgICAgICAgICAgY2FzZSAxNjA6IHsKICAgICAgICAgICAgICAgIGR1bW15MjBfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYwCiAgICAgICAgICAgICAgY2FzZSAxNjg6IHsKICAgICAgICAgICAgICAgIGR1bW15MjFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTY4CiAgICAgICAgICAgICAgY2FzZSAxNzY6IHsKICAgICAgICAgICAgICAgIGR1bW15MjJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTc2CiAgICAgICAgICAgICAgY2FzZSAxODQ6IHsKICAgICAgICAgICAgICAgIGR1bW15MjNfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTg0CiAgICAgICAgICAgICAgY2FzZSAxOTI6IHsKICAgICAgICAgICAgICAgIGR1bW15MjRfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTkyCiAgICAgICAgICAgICAgY2FzZSAyMDA6IHsKICAgICAgICAgICAgICAgIGR1bW15MjVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjAwCiAgICAgICAgICAgICAgY2FzZSAyMDg6IHsKICAgICAgICAgICAgICAgIGR1bW15MjZfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjA4CiAgICAgICAgICAgICAgY2FzZSAyMTY6IHsKICAgICAgICAgICAgICAgIGR1bW15MjdfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjE2CiAgICAgICAgICAgICAgY2FzZSAyMjQ6IHsKICAgICAgICAgICAgICAgIGR1bW15MjhfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjI0CiAgICAgICAgICAgICAgY2FzZSAyMzI6IHsKICAgICAgICAgICAgICAgIGR1bW15MjlfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjMyCiAgICAgICAgICAgICAgY2FzZSAyNDA6IHsKICAgICAgICAgICAgICAgIGR1bW15MzBfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MjAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQwCiAgICAgICAgICAgICAgY2FzZSAyNDg6IHsKICAgICAgICAgICAgICAgIGR1bW15MzFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQ4CiAgICAgICAgICAgICAgY2FzZSAyNTY6IHsKICAgICAgICAgICAgICAgIGR1bW15MzJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjU2CiAgICAgICAgICAgICAgY2FzZSAyNjQ6IHsKICAgICAgICAgICAgICAgIGNfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjY0CiAgICAgICAgICAgICAgY2FzZSAyNzQ6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsRm9yZWlnbkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjc0CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQxXzsKCiAgICAgIHByaXZhdGUgaW50IGFfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgIHJldHVybiBhXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRBKGludCB2YWx1ZSkgewoKICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGFfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEdW1teTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZHVtbXkyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldER1bW15MigpIHsKICAgICAgICByZXR1cm4gZHVtbXkyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RHVtbXkyKGludCB2YWx1ZSkgewoKICAgICAgICBkdW1teTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEdW1teTIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGR1bW15Ml8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBiID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0IoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBiID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0QigpIHsKICAgICAgICByZXR1cm4gYl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGIgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBiIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QihpbnQgdmFsdWUpIHsKCiAgICAgICAgYl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGIgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJCKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBiXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGR1bW15NF8gOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUGFkIHRoZSBmaWVsZCBjb3VudCB0byAzMiBzbyB0aGF0IHdlIGNhbiB0ZXN0IHRoYXQgSXNJbml0aWFsaXplZCgpCiAgICAgICAqIHByb3Blcmx5IGNoZWNrcyBtdWx0aXBsZSBlbGVtZW50cyBvZiBoYXNfYml0c18uCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEdW1teTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBQYWQgdGhlIGZpZWxkIGNvdW50IHRvIDMyIHNvIHRoYXQgd2UgY2FuIHRlc3QgdGhhdCBJc0luaXRpYWxpemVkKCkKICAgICAgICogcHJvcGVybHkgY2hlY2tzIG11bHRpcGxlIGVsZW1lbnRzIG9mIGhhc19iaXRzXy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15NCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXk0KCkgewogICAgICAgIHJldHVybiBkdW1teTRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBQYWQgdGhlIGZpZWxkIGNvdW50IHRvIDMyIHNvIHRoYXQgd2UgY2FuIHRlc3QgdGhhdCBJc0luaXRpYWxpemVkKCkKICAgICAgICogcHJvcGVybHkgY2hlY2tzIG11bHRpcGxlIGVsZW1lbnRzIG9mIGhhc19iaXRzXy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15NCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGR1bW15NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15NChpbnQgdmFsdWUpIHsKCiAgICAgICAgZHVtbXk0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUGFkIHRoZSBmaWVsZCBjb3VudCB0byAzMiBzbyB0aGF0IHdlIGNhbiB0ZXN0IHRoYXQgSXNJbml0aWFsaXplZCgpCiAgICAgICAqIHByb3Blcmx5IGNoZWNrcyBtdWx0aXBsZSBlbGVtZW50cyBvZiBoYXNfYml0c18uCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEdW1teTQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGR1bW15NF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBkdW1teTVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15NSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15NSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15NSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXk1KCkgewogICAgICAgIHJldHVybiBkdW1teTVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTUgPSA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkdW1teTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREdW1teTUoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15NSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15NSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgZHVtbXk1XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGR1bW15Nl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk2ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXk2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXk2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk2ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15Ni4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXREdW1teTYoKSB7CiAgICAgICAgcmV0dXJuIGR1bW15Nl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15NiA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGR1bW15NiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15NihpbnQgdmFsdWUpIHsKCiAgICAgICAgZHVtbXk2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk2ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRHVtbXk2KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBkdW1teTZfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXk3XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTcgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEdW1teTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTcgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZHVtbXk3LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldER1bW15NygpIHsKICAgICAgICByZXR1cm4gZHVtbXk3XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk3ID0gNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXk3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RHVtbXk3KGludCB2YWx1ZSkgewoKICAgICAgICBkdW1teTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTcgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEdW1teTcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGR1bW15N18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBkdW1teThfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15OCA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15OCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15OCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15OCA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkdW1teTguCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXk4KCkgewogICAgICAgIHJldHVybiBkdW1teThfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTggPSA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkdW1teTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREdW1teTgoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15OF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15OCA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15OCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgZHVtbXk4XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGR1bW15OV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk5ID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXk5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXk5KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk5ID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15OS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXREdW1teTkoKSB7CiAgICAgICAgcmV0dXJuIGR1bW15OV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15OSA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGR1bW15OSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15OShpbnQgdmFsdWUpIHsKCiAgICAgICAgZHVtbXk5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXk5ID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRHVtbXk5KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBkdW1teTlfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkxMF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxMCA9IDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTEwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkxMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTAuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkxMCgpIHsKICAgICAgICByZXR1cm4gZHVtbXkxMF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkxMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MTAoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTEwID0gMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MTAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGR1bW15MTBfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkxMV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxMSA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTExIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkxMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTEgPSAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkxMSgpIHsKICAgICAgICByZXR1cm4gZHVtbXkxMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTEgPSAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkxMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MTEoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTExID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MTEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIGR1bW15MTFfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkxMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxMiA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTEyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkxMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkxMigpIHsKICAgICAgICByZXR1cm4gZHVtbXkxMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkxMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MTIoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTEyID0gMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MTIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIGR1bW15MTJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkxM18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxMyA9IDEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTEzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkxMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkxMygpIHsKICAgICAgICByZXR1cm4gZHVtbXkxM187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkxMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MTMoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTEzID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MTMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIGR1bW15MTNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkxNF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxNCA9IDE0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTE0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkxNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkxNCgpIHsKICAgICAgICByZXR1cm4gZHVtbXkxNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkxNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MTQoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE0ID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MTQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIGR1bW15MTRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkxNV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxNSA9IDE1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTE1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkxNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkxNSgpIHsKICAgICAgICByZXR1cm4gZHVtbXkxNV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkxNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MTUoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE1ID0gMTU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MTUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIGR1bW15MTVfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkxNl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxNiA9IDE2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTE2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkxNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTYuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkxNigpIHsKICAgICAgICByZXR1cm4gZHVtbXkxNl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkxNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MTYoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE2ID0gMTY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MTYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDgwMDApOwogICAgICAgIGR1bW15MTZfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkxN18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxNyA9IDE3OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTE3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkxNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkxNygpIHsKICAgICAgICByZXR1cm4gZHVtbXkxN187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkxNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MTcoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE3ID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MTcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIGR1bW15MTdfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkxOF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxOCA9IDE4OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTE4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkxOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTggPSAxODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTguCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkxOCgpIHsKICAgICAgICByZXR1cm4gZHVtbXkxOF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTggPSAxODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkxOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MTgoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE4ID0gMTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MTgoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIGR1bW15MThfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkxOV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkxOSA9IDE5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTE5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkxOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTkgPSAxOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MTkuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkxOSgpIHsKICAgICAgICByZXR1cm4gZHVtbXkxOV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MTkgPSAxOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkxOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MTkoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTE5ID0gMTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MTkoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwNDAwMDApOwogICAgICAgIGR1bW15MTlfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkyMF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyMCA9IDIwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTIwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjAgPSAyMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjAuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkyMCgpIHsKICAgICAgICByZXR1cm4gZHVtbXkyMF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjAgPSAyMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkyMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MjAoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIwID0gMjA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MjAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIGR1bW15MjBfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkyMV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyMSA9IDIxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTIxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjEgPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkyMSgpIHsKICAgICAgICByZXR1cm4gZHVtbXkyMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjEgPSAyMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkyMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MjEoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIxID0gMjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MjEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAxMDAwMDApOwogICAgICAgIGR1bW15MjFfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkyMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyMiA9IDIyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTIyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjIgPSAyMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkyMigpIHsKICAgICAgICByZXR1cm4gZHVtbXkyMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjIgPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MjIoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIyID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MjIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAyMDAwMDApOwogICAgICAgIGR1bW15MjJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkyM18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyMyA9IDIzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTIzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyMygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjMgPSAyMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkyMygpIHsKICAgICAgICByZXR1cm4gZHVtbXkyM187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjMgPSAyMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkyMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MjMoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTIzID0gMjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MjMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA0MDAwMDApOwogICAgICAgIGR1bW15MjNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkyNF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyNCA9IDI0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTI0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkyNCgpIHsKICAgICAgICByZXR1cm4gZHVtbXkyNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkyNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MjQoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI0ID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA4MDAwMDApOwogICAgICAgIGR1bW15MjRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkyNV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyNSA9IDI1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTI1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjUgPSAyNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkyNSgpIHsKICAgICAgICByZXR1cm4gZHVtbXkyNV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjUgPSAyNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkyNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MjUoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI1ID0gMjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MjUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDEwMDAwMDApOwogICAgICAgIGR1bW15MjVfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkyNl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyNiA9IDI2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTI2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjYgPSAyNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjYuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkyNigpIHsKICAgICAgICByZXR1cm4gZHVtbXkyNl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjYgPSAyNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkyNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MjYoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI2ID0gMjY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MjYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDIwMDAwMDApOwogICAgICAgIGR1bW15MjZfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkyN18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyNyA9IDI3OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTI3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyNygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjcgPSAyNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkyNygpIHsKICAgICAgICByZXR1cm4gZHVtbXkyN187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjcgPSAyNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkyNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MjcoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI3ID0gMjc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MjcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgIGR1bW15MjdfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkyOF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyOCA9IDI4OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTI4IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwODAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjggPSAyODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjguCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkyOCgpIHsKICAgICAgICByZXR1cm4gZHVtbXkyOF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjggPSAyODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkyOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MjgoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI4ID0gMjg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MjgoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDgwMDAwMDApOwogICAgICAgIGR1bW15MjhfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkyOV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkyOSA9IDI5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTI5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkyOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjkgPSAyOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MjkuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkyOSgpIHsKICAgICAgICByZXR1cm4gZHVtbXkyOV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MjkgPSAyOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkyOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MjkoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTI5ID0gMjk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MjkoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MTAwMDAwMDApOwogICAgICAgIGR1bW15MjlfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkzMF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkzMCA9IDMwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTMwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkzMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MzAuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkzMCgpIHsKICAgICAgICByZXR1cm4gZHVtbXkzMF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkzMCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MzAoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTMwID0gMzA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MzAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MjAwMDAwMDApOwogICAgICAgIGR1bW15MzBfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkzMV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkzMSA9IDMxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTMxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkzMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHg0MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MzEgPSAzMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MzEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkzMSgpIHsKICAgICAgICByZXR1cm4gZHVtbXkzMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MzEgPSAzMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkzMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MzEoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTMxID0gMzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MzEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4NDAwMDAwMDApOwogICAgICAgIGR1bW15MzFfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZHVtbXkzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkzMiA9IDMyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teTMyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkzMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHg4MDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MzIgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR1bW15MzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkzMigpIHsKICAgICAgICByZXR1cm4gZHVtbXkzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15MzIgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZHVtbXkzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGR1bW15MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teTMyID0gMzI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckR1bW15MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4ODAwMDAwMDApOwogICAgICAgIGR1bW15MzJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgY18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgYyA9IDMzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGMgPSAzMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0QygpIHsKICAgICAgICByZXR1cm4gY187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGludDMyIGMgPSAzMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEMoaW50IHZhbHVlKSB7CgogICAgICAgIGNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBjID0gMzM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckMoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsRm9yZWlnbl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gb3B0aW9uYWxGb3JlaWduQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBZGQgYW4gb3B0aW9uYWwgY2hpbGQgbWVzc2FnZSB0byBtYWtlIHRoaXMgbm9uLXRyaXZpYWwgZm9yIGdvL3BkbGF6eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRm9yZWlnbiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEZvcmVpZ24oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBZGQgYW4gb3B0aW9uYWwgY2hpbGQgbWVzc2FnZSB0byBtYWtlIHRoaXMgbm9uLXRyaXZpYWwgZm9yIGdvL3BkbGF6eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduID0gMzQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEZvcmVpZ24uCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRPcHRpb25hbEZvcmVpZ24oKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEZvcmVpZ25fID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxGb3JlaWduXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsRm9yZWlnbkJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFkZCBhbiBvcHRpb25hbCBjaGlsZCBtZXNzYWdlIHRvIG1ha2UgdGhpcyBub24tdHJpdmlhbCBmb3IgZ28vcGRsYXp5LgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ24gPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEZvcmVpZ24ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbl8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQWRkIGFuIG9wdGlvbmFsIGNoaWxkIG1lc3NhZ2UgdG8gbWFrZSB0aGlzIG5vbi10cml2aWFsIGZvciBnby9wZGxhenkuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfZm9yZWlnbiA9IDM0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRm9yZWlnbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxGb3JlaWduQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25CdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBZGQgYW4gb3B0aW9uYWwgY2hpbGQgbWVzc2FnZSB0byBtYWtlIHRoaXMgbm9uLXRyaXZpYWwgZm9yIGdvL3BkbGF6eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduID0gMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbEZvcmVpZ24ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwMikgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxGb3JlaWduXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbl8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbEZvcmVpZ25CdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsRm9yZWlnbl8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxGb3JlaWduQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsRm9yZWlnbl8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBZGQgYW4gb3B0aW9uYWwgY2hpbGQgbWVzc2FnZSB0byBtYWtlIHRoaXMgbm9uLXRyaXZpYWwgZm9yIGdvL3BkbGF6eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduID0gMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEZvcmVpZ24oKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9wdGlvbmFsRm9yZWlnbl8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25CdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25CdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25CdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBZGQgYW4gb3B0aW9uYWwgY2hpbGQgbWVzc2FnZSB0byBtYWtlIHRoaXMgbm9uLXRyaXZpYWwgZm9yIGdvL3BkbGF6eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduID0gMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbEZvcmVpZ25CdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxGb3JlaWduRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBZGQgYW4gb3B0aW9uYWwgY2hpbGQgbWVzc2FnZSB0byBtYWtlIHRoaXMgbm9uLXRyaXZpYWwgZm9yIGdvL3BkbGF6eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9mb3JlaWduID0gMzQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0T3B0aW9uYWxGb3JlaWduT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25CdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxGb3JlaWduXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxGb3JlaWduXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFkZCBhbiBvcHRpb25hbCBjaGlsZCBtZXNzYWdlIHRvIG1ha2UgdGhpcyBub24tdHJpdmlhbCBmb3IgZ28vcGRsYXp5LgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX2ZvcmVpZ24gPSAzNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxGb3JlaWduRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEZvcmVpZ25CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEZvcmVpZ25CdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsRm9yZWlnbigpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxGb3JlaWduXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbEZvcmVpZ25CdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXF1aXJlZD4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0UmVxdWlyZWQ+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UmVxdWlyZWQgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVxdWlyZWQ+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlcXVpcmVkPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTSU5HTEVfRklFTERfTlVNQkVSID0gMTAwMDsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4gc2luZ2xlID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAwLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuY2xhc3MsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNVUxUSV9GSUVMRF9OVU1CRVIgPSAxMDAxOwogICAgLyoqCiAgICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPj4gbXVsdGkgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSwKICAgICAgICAgIDEsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5jbGFzcywKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFJlcXVpcmVkRm9yZWlnbk9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRGb3JlaWduKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxNZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBnZXRPcHRpb25hbE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyIGdldE9wdGlvbmFsTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiAKICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBnZXRSZXBlYXRlZE1lc3NhZ2UoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZE1lc3NhZ2VDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciBnZXRSZXBlYXRlZE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15ID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEdW1teSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teSA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkuCiAgICAgKi8KICAgIGludCBnZXREdW1teSgpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1pc3NpbmcgcmVxdWlyZWQgZmllbGRzIG11c3Qgbm90IGFmZmVjdCB2ZXJpZmljYXRpb24gb2YgY2hpbGQgbWVzc2FnZXMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1pc3NpbmcgcmVxdWlyZWQgZmllbGRzIG11c3Qgbm90IGFmZmVjdCB2ZXJpZmljYXRpb24gb2YgY2hpbGQgbWVzc2FnZXMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbExhenlNZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBnZXRPcHRpb25hbExhenlNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNaXNzaW5nIHJlcXVpcmVkIGZpZWxkcyBtdXN0IG5vdCBhZmZlY3QgdmVyaWZpY2F0aW9uIG9mIGNoaWxkIG1lc3NhZ2VzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPcHRpb25hbExhenlNZXNzYWdlT3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEZvcmVpZ259CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0UmVxdWlyZWRGb3JlaWduIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEZvcmVpZ24pCiAgICAgIFRlc3RSZXF1aXJlZEZvcmVpZ25PckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RSZXF1aXJlZEZvcmVpZ24ubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFJlcXVpcmVkRm9yZWlnbihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RSZXF1aXJlZEZvcmVpZ24oKSB7CiAgICAgIHJlcGVhdGVkTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFJlcXVpcmVkRm9yZWlnbigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEZvcmVpZ25fZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRGb3JlaWduX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24uQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgb3B0aW9uYWxNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldE9wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiByZXBlYXRlZE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiBnZXRSZXBlYXRlZE1lc3NhZ2VMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZE1lc3NhZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldFJlcGVhdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciBnZXRSZXBlYXRlZE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFVNTVlfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgaW50IGR1bW15XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15ID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR1bW15IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRHVtbXkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR1bW15LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldER1bW15KCkgewogICAgICByZXR1cm4gZHVtbXlfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0xBWllfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcyBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1pc3NpbmcgcmVxdWlyZWQgZmllbGRzIG11c3Qgbm90IGFmZmVjdCB2ZXJpZmljYXRpb24gb2YgY2hpbGQgbWVzc2FnZXMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbExhenlNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBNaXNzaW5nIHJlcXVpcmVkIGZpZWxkcyBtdXN0IG5vdCBhZmZlY3QgdmVyaWZpY2F0aW9uIG9mIGNoaWxkIG1lc3NhZ2VzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxMYXp5TWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbExhenlNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE1pc3NpbmcgcmVxdWlyZWQgZmllbGRzIG11c3Qgbm90IGFmZmVjdCB2ZXJpZmljYXRpb24gb2YgY2hpbGQgbWVzc2FnZXMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPcHRpb25hbExhenlNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKGhhc09wdGlvbmFsTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbE1lc3NhZ2UoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ2V0UmVwZWF0ZWRNZXNzYWdlQ291bnQoKTsgaSsrKSB7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZE1lc3NhZ2UoaSkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgZ2V0T3B0aW9uYWxNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMiwgcmVwZWF0ZWRNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDMsIGR1bW15Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg0LCBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0T3B0aW9uYWxNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCByZXBlYXRlZE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgzLCBkdW1teV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg0LCBnZXRPcHRpb25hbExhenlNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbikgb2JqOwoKICAgICAgaWYgKGhhc09wdGlvbmFsTWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFJlcGVhdGVkTWVzc2FnZUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZE1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teSgpICE9IG90aGVyLmhhc0R1bW15KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0R1bW15KCkpIHsKICAgICAgICBpZiAoZ2V0RHVtbXkoKQogICAgICAgICAgICAhPSBvdGhlci5nZXREdW1teSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSAhPSBvdGhlci5oYXNPcHRpb25hbExhenlNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRNZXNzYWdlQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZE1lc3NhZ2VMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERVTU1ZX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREdW1teSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbExhenlNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9MQVpZX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24gcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24gcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbiBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbiBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRGb3JlaWdufQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRm9yZWlnbikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ25PckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkRm9yZWlnbl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRGb3JlaWduX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldE9wdGlvbmFsTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgZHVtbXlfID0gMDsKICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEZvcmVpZ25fZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbiBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24odGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIHJlc3VsdCkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTWVzc2FnZV8pOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRNZXNzYWdlXyA9IHJlcGVhdGVkTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZE1lc3NhZ2VfID0gcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbiByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbE1lc3NhZ2VfID0gb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxNZXNzYWdlXwogICAgICAgICAgICAgIDogb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kdW1teV8gPSBkdW1teV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxMYXp5TWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24pb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbi5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsTWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsTWVzc2FnZShvdGhlci5nZXRPcHRpb25hbE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZE1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfLmFkZEFsbChvdGhlci5yZXBlYXRlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkTWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEdW1teSgpKSB7CiAgICAgICAgICBzZXREdW1teShvdGhlci5nZXREdW1teSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbExhenlNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoaGFzT3B0aW9uYWxNZXNzYWdlKCkpIHsKICAgICAgICAgIGlmICghZ2V0T3B0aW9uYWxNZXNzYWdlKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBnZXRSZXBlYXRlZE1lc3NhZ2VDb3VudCgpOyBpKyspIHsKICAgICAgICAgIGlmICghZ2V0UmVwZWF0ZWRNZXNzYWdlKGkpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBkdW1teV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgb3B0aW9uYWxNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPiBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldE9wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZV8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgZ2V0T3B0aW9uYWxNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXIgZ2V0T3B0aW9uYWxNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiByZXBlYXRlZE1lc3NhZ2VfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPihyZXBlYXRlZE1lc3NhZ2VfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ+IGdldFJlcGVhdGVkTWVzc2FnZUxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE1lc3NhZ2VfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRNZXNzYWdlQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBnZXRSZXBlYXRlZE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE1lc3NhZ2UoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE1lc3NhZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZE1lc3NhZ2VfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyIGdldFJlcGVhdGVkTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyIGdldFJlcGVhdGVkTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE1lc3NhZ2VfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgYWRkUmVwZWF0ZWRNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyIGFkZFJlcGVhdGVkTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRNZXNzYWdlQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBkdW1teV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZHVtbXkuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkoKSB7CiAgICAgICAgcmV0dXJuIGR1bW15XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkdW1teSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15KGludCB2YWx1ZSkgewoKICAgICAgICBkdW1teV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15ID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRHVtbXkoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGR1bW15XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMgb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlc09yQnVpbGRlcj4gb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTWlzc2luZyByZXF1aXJlZCBmaWVsZHMgbXVzdCBub3QgYWZmZWN0IHZlcmlmaWNhdGlvbiBvZiBjaGlsZCBtZXNzYWdlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbExhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNaXNzaW5nIHJlcXVpcmVkIGZpZWxkcyBtdXN0IG5vdCBhZmZlY3QgdmVyaWZpY2F0aW9uIG9mIGNoaWxkIG1lc3NhZ2VzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbExhenlNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTWlzc2luZyByZXF1aXJlZCBmaWVsZHMgbXVzdCBub3QgYWZmZWN0IHZlcmlmaWNhdGlvbiBvZiBjaGlsZCBtZXNzYWdlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTGF6eU1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE1pc3NpbmcgcmVxdWlyZWQgZmllbGRzIG11c3Qgbm90IGFmZmVjdCB2ZXJpZmljYXRpb24gb2YgY2hpbGQgbWVzc2FnZXMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2xhenlfbWVzc2FnZSA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbExhenlNZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNaXNzaW5nIHJlcXVpcmVkIGZpZWxkcyBtdXN0IG5vdCBhZmZlY3QgdmVyaWZpY2F0aW9uIG9mIGNoaWxkIG1lc3NhZ2VzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbExhenlNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTWlzc2luZyByZXF1aXJlZCBmaWVsZHMgbXVzdCBub3QgYWZmZWN0IHZlcmlmaWNhdGlvbiBvZiBjaGlsZCBtZXNzYWdlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXMgb3B0aW9uYWxfbGF6eV9tZXNzYWdlID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxMYXp5TWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNaXNzaW5nIHJlcXVpcmVkIGZpZWxkcyBtdXN0IG5vdCBhZmZlY3QgdmVyaWZpY2F0aW9uIG9mIGNoaWxkIG1lc3NhZ2VzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0T3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbExhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNaXNzaW5nIHJlcXVpcmVkIGZpZWxkcyBtdXN0IG5vdCBhZmZlY3QgdmVyaWZpY2F0aW9uIG9mIGNoaWxkIG1lc3NhZ2VzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxMYXp5TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTGF6eU1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxMYXp5TWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBNaXNzaW5nIHJlcXVpcmVkIGZpZWxkcyBtdXN0IG5vdCBhZmZlY3QgdmVyaWZpY2F0aW9uIG9mIGNoaWxkIG1lc3NhZ2VzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlcyBvcHRpb25hbF9sYXp5X21lc3NhZ2UgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTmVzdGVkVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk5lc3RlZFRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5OZXN0ZWRUZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbExhenlNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbExhenlNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbExhenlNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRm9yZWlnbikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRm9yZWlnbikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbiBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbiBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXF1aXJlZEZvcmVpZ24+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFJlcXVpcmVkRm9yZWlnbj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RSZXF1aXJlZEZvcmVpZ24gcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVxdWlyZWRGb3JlaWduPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXF1aXJlZEZvcmVpZ24+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RSZXF1aXJlZE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTWVzc2FnZS4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgZ2V0T3B0aW9uYWxNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4gCiAgICAgICAgZ2V0UmVwZWF0ZWRNZXNzYWdlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgZ2V0UmVwZWF0ZWRNZXNzYWdlKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRNZXNzYWdlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcXVpcmVkX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNSZXF1aXJlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXF1aXJlZF9tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZE1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldFJlcXVpcmVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcXVpcmVkX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXIgZ2V0UmVxdWlyZWRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0UmVxdWlyZWRNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2UpCiAgICAgIFRlc3RSZXF1aXJlZE1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RSZXF1aXJlZE1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFJlcXVpcmVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RSZXF1aXJlZE1lc3NhZ2UoKSB7CiAgICAgIHJlcGVhdGVkTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFJlcXVpcmVkTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgb3B0aW9uYWxNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldE9wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiByZXBlYXRlZE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkPiBnZXRSZXBlYXRlZE1lc3NhZ2VMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZE1lc3NhZ2VDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldFJlcGVhdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciBnZXRSZXBlYXRlZE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRVUlSRURfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCByZXF1aXJlZE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcXVpcmVkX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUmVxdWlyZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVxdWlyZWRfbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgZ2V0UmVxdWlyZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gcmVxdWlyZWRNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXF1aXJlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcXVpcmVkX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyIGdldFJlcXVpcmVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHJlcXVpcmVkTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcmVxdWlyZWRNZXNzYWdlXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWhhc1JlcXVpcmVkTWVzc2FnZSgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbE1lc3NhZ2UoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ2V0UmVwZWF0ZWRNZXNzYWdlQ291bnQoKTsgaSsrKSB7CiAgICAgICAgaWYgKCFnZXRSZXBlYXRlZE1lc3NhZ2UoaSkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoIWdldFJlcXVpcmVkTWVzc2FnZSgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRPcHRpb25hbE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyLCByZXBlYXRlZE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgzLCBnZXRSZXF1aXJlZE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRPcHRpb25hbE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIsIHJlcGVhdGVkTWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgZ2V0UmVxdWlyZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRNZXNzYWdlIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKGhhc09wdGlvbmFsTWVzc2FnZSgpICE9IG90aGVyLmhhc09wdGlvbmFsTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxNZXNzYWdlKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbE1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFJlcGVhdGVkTWVzc2FnZUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZE1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNSZXF1aXJlZE1lc3NhZ2UoKSAhPSBvdGhlci5oYXNSZXF1aXJlZE1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUmVxdWlyZWRNZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldFJlcXVpcmVkTWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVxdWlyZWRNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzT3B0aW9uYWxNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbE1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZE1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkTWVzc2FnZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNSZXF1aXJlZE1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUVVJUkVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcXVpcmVkTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRNZXNzYWdlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldFJlcXVpcmVkTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIHJlcXVpcmVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChyZXF1aXJlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXF1aXJlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICByZXF1aXJlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRNZXNzYWdlKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkTWVzc2FnZV8gPSByZXBlYXRlZE1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRNZXNzYWdlXyA9IHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxNZXNzYWdlXyA9IG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsTWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucmVxdWlyZWRNZXNzYWdlXyA9IHJlcXVpcmVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IHJlcXVpcmVkTWVzc2FnZV8KICAgICAgICAgICAgICA6IHJlcXVpcmVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsTWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkTWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkTWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZE1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIucmVwZWF0ZWRNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1JlcXVpcmVkTWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZVJlcXVpcmVkTWVzc2FnZShvdGhlci5nZXRSZXF1aXJlZE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWhhc1JlcXVpcmVkTWVzc2FnZSgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmIChoYXNPcHRpb25hbE1lc3NhZ2UoKSkgewogICAgICAgICAgaWYgKCFnZXRPcHRpb25hbE1lc3NhZ2UoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdldFJlcGVhdGVkTWVzc2FnZUNvdW50KCk7IGkrKykgewogICAgICAgICAgaWYgKCFnZXRSZXBlYXRlZE1lc3NhZ2UoaSkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRSZXF1aXJlZE1lc3NhZ2UoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldFJlcXVpcmVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCBvcHRpb25hbE1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+IG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgZ2V0T3B0aW9uYWxNZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbE1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxNZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbE1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxNZXNzYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvcHRpb25hbE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCBvcHRpb25hbF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIG9wdGlvbmFsX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgb3B0aW9uYWxfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbE1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ+IHJlcGVhdGVkTWVzc2FnZV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ+KHJlcGVhdGVkTWVzc2FnZV8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPiByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZD4gZ2V0UmVwZWF0ZWRNZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTWVzc2FnZV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZE1lc3NhZ2VDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZV8uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldFJlcGVhdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkTWVzc2FnZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQ+IHZhbHVlcykgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkTWVzc2FnZV8pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTWVzc2FnZV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXBlYXRlZF9tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciBhZGRSZXBlYXRlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVwZWF0ZWRfbWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgYWRkUmVwZWF0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcGVhdGVkX21lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQgcmVxdWlyZWRNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPiByZXF1aXJlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVxdWlyZWRfbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcXVpcmVkX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIGdldFJlcXVpcmVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAocmVxdWlyZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcXVpcmVkTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcmVxdWlyZWRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcXVpcmVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVxdWlyZWRfbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVxdWlyZWRNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgcmVxdWlyZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXF1aXJlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcXVpcmVkX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcXVpcmVkTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcXVpcmVkTWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVxdWlyZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXF1aXJlZF9tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVJlcXVpcmVkTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZCB2YWx1ZSkgewogICAgICAgIGlmIChyZXF1aXJlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkgJiYKICAgICAgICAgICAgcmVxdWlyZWRNZXNzYWdlXyAhPSBudWxsICYmCiAgICAgICAgICAgIHJlcXVpcmVkTWVzc2FnZV8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0UmVxdWlyZWRNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXF1aXJlZE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcXVpcmVkTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXF1aXJlZE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXF1aXJlZF9tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcXVpcmVkTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgcmVxdWlyZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKHJlcXVpcmVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJlcXVpcmVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHJlcXVpcmVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWQgcmVxdWlyZWRfbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIgZ2V0UmVxdWlyZWRNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldFJlcXVpcmVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZCByZXF1aXJlZF9tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPckJ1aWxkZXIgZ2V0UmVxdWlyZWRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXF1aXJlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVxdWlyZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVxdWlyZWRNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHJlcXVpcmVkTWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkIHJlcXVpcmVkX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXF1aXJlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcXVpcmVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0UmVxdWlyZWRNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXF1aXJlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcXVpcmVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE1lc3NhZ2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVxdWlyZWRNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RSZXF1aXJlZE1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UmVxdWlyZWRNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlcXVpcmVkTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVxdWlyZWRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24pCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBjaGlsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQ2hpbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gY2hpbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNoaWxkLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gZ2V0Q2hpbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gY2hpbGQgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduT3JCdWlsZGVyIGdldENoaWxkT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRm9yZWlnbiBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBheWxvYWQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1BheWxvYWQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEZvcmVpZ24gcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcGF5bG9hZC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIGdldFBheWxvYWQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEZvcmVpZ24gcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ25PckJ1aWxkZXIgZ2V0UGF5bG9hZE9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0R1bW15KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15ID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkdW1teS4KICAgICAqLwogICAgaW50IGdldER1bW15KCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogb3B0aW9uYWwgbWVzc2FnZSB0byB0ZXN0IHJlcXVpcmVkIGNsb3NlZCBlbnVtLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW0gcmVxdWlyZWRfZW51bSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXF1aXJlZEVudW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1JlcXVpcmVkRW51bSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogb3B0aW9uYWwgbWVzc2FnZSB0byB0ZXN0IHJlcXVpcmVkIGNsb3NlZCBlbnVtLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW0gcmVxdWlyZWRfZW51bSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRFbnVtLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0gZ2V0UmVxdWlyZWRFbnVtKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBvcHRpb25hbCBtZXNzYWdlIHRvIHRlc3QgcmVxdWlyZWQgY2xvc2VkIGVudW0uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bSByZXF1aXJlZF9lbnVtID0gNTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU9yQnVpbGRlciBnZXRSZXF1aXJlZEVudW1PckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIHJlcXVpcmVkX2VudW1fbm9fbWFzayA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXF1aXJlZEVudW1Ob01hc2sgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1JlcXVpcmVkRW51bU5vTWFzaygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU5vTWFzayByZXF1aXJlZF9lbnVtX25vX21hc2sgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRW51bU5vTWFzay4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIGdldFJlcXVpcmVkRW51bU5vTWFzaygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU5vTWFzayByZXF1aXJlZF9lbnVtX25vX21hc2sgPSA2OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrT3JCdWlsZGVyIGdldFJlcXVpcmVkRW51bU5vTWFza09yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aSByZXF1aXJlZF9lbnVtX211bHRpID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bU11bHRpIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW1NdWx0aSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpIHJlcXVpcmVkX2VudW1fbXVsdGkgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRW51bU11bHRpLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSBnZXRSZXF1aXJlZEVudW1NdWx0aSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpIHJlcXVpcmVkX2VudW1fbXVsdGkgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGlPckJ1aWxkZXIgZ2V0UmVxdWlyZWRFbnVtTXVsdGlPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSByZXF1aXJlZF9ub19tYXNrID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkTm9NYXNrIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNSZXF1aXJlZE5vTWFzaygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkgcmVxdWlyZWRfbm9fbWFzayA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVxdWlyZWROb01hc2suCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkgZ2V0UmVxdWlyZWROb01hc2soKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHJlcXVpcmVkX25vX21hc2sgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aU9yQnVpbGRlciBnZXRSZXF1aXJlZE5vTWFza09yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWdufQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduKQogICAgICBUZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24oY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDSElMRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gY2hpbGRfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBjaGlsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0NoaWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjaGlsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBnZXRDaGlsZCgpIHsKICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduLmdldERlZmF1bHRJbnN0YW5jZSgpIDogY2hpbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBjaGlsZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduT3JCdWlsZGVyIGdldENoaWxkT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gY2hpbGRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24uZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFZTE9BRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24gcGF5bG9hZF87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRGb3JlaWduIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcGF5bG9hZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1BheWxvYWQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEZvcmVpZ24gcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcGF5bG9hZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbiBnZXRQYXlsb2FkKCkgewogICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBheWxvYWRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRm9yZWlnbiBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ25PckJ1aWxkZXIgZ2V0UGF5bG9hZE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHBheWxvYWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24uZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBwYXlsb2FkXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEVU1NWV9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBpbnQgZHVtbXlfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHVtbXkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEdW1teSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkdW1teSA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZHVtbXkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkoKSB7CiAgICAgIHJldHVybiBkdW1teV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRVUlSRURfRU5VTV9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0gcmVxdWlyZWRFbnVtXzsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG9wdGlvbmFsIG1lc3NhZ2UgdG8gdGVzdCByZXF1aXJlZCBjbG9zZWQgZW51bS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtIHJlcXVpcmVkX2VudW0gPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRFbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUmVxdWlyZWRFbnVtKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBvcHRpb25hbCBtZXNzYWdlIHRvIHRlc3QgcmVxdWlyZWQgY2xvc2VkIGVudW0uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bSByZXF1aXJlZF9lbnVtID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0gZ2V0UmVxdWlyZWRFbnVtKCkgewogICAgICByZXR1cm4gcmVxdWlyZWRFbnVtXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcmVxdWlyZWRFbnVtXzsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIG9wdGlvbmFsIG1lc3NhZ2UgdG8gdGVzdCByZXF1aXJlZCBjbG9zZWQgZW51bS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtIHJlcXVpcmVkX2VudW0gPSA1OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU9yQnVpbGRlciBnZXRSZXF1aXJlZEVudW1PckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiByZXF1aXJlZEVudW1fID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0uZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXF1aXJlZEVudW1fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUVVJUkVEX0VOVU1fTk9fTUFTS19GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgcmVxdWlyZWRFbnVtTm9NYXNrXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgcmVxdWlyZWRfZW51bV9ub19tYXNrID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bU5vTWFzayBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1JlcXVpcmVkRW51bU5vTWFzaygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU5vTWFzayByZXF1aXJlZF9lbnVtX25vX21hc2sgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRW51bU5vTWFzay4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzayBnZXRSZXF1aXJlZEVudW1Ob01hc2soKSB7CiAgICAgIHJldHVybiByZXF1aXJlZEVudW1Ob01hc2tfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXF1aXJlZEVudW1Ob01hc2tfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU5vTWFzayByZXF1aXJlZF9lbnVtX25vX21hc2sgPSA2OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFza09yQnVpbGRlciBnZXRSZXF1aXJlZEVudW1Ob01hc2tPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiByZXF1aXJlZEVudW1Ob01hc2tfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXF1aXJlZEVudW1Ob01hc2tfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUVVJUkVEX0VOVU1fTVVMVElfRklFTERfTlVNQkVSID0gNzsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgcmVxdWlyZWRFbnVtTXVsdGlfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpIHJlcXVpcmVkX2VudW1fbXVsdGkgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRFbnVtTXVsdGkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW1NdWx0aSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpIHJlcXVpcmVkX2VudW1fbXVsdGkgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRW51bU11bHRpLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgZ2V0UmVxdWlyZWRFbnVtTXVsdGkoKSB7CiAgICAgIHJldHVybiByZXF1aXJlZEVudW1NdWx0aV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcmVxdWlyZWRFbnVtTXVsdGlfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpIHJlcXVpcmVkX2VudW1fbXVsdGkgPSA3OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpT3JCdWlsZGVyIGdldFJlcXVpcmVkRW51bU11bHRpT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gcmVxdWlyZWRFbnVtTXVsdGlfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHJlcXVpcmVkRW51bU11bHRpXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVFVSVJFRF9OT19NQVNLX0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkgcmVxdWlyZWROb01hc2tfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkgcmVxdWlyZWRfbm9fbWFzayA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXF1aXJlZE5vTWFzayBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1JlcXVpcmVkTm9NYXNrKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSByZXF1aXJlZF9ub19tYXNrID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZE5vTWFzay4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkgZ2V0UmVxdWlyZWROb01hc2soKSB7CiAgICAgIHJldHVybiByZXF1aXJlZE5vTWFza18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXF1aXJlZE5vTWFza187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSByZXF1aXJlZF9ub19tYXNrID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpT3JCdWlsZGVyIGdldFJlcXVpcmVkTm9NYXNrT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gcmVxdWlyZWROb01hc2tfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcmVxdWlyZWROb01hc2tfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmIChoYXNDaGlsZCgpKSB7CiAgICAgICAgaWYgKCFnZXRDaGlsZCgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGhhc1BheWxvYWQoKSkgewogICAgICAgIGlmICghZ2V0UGF5bG9hZCgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGhhc1JlcXVpcmVkRW51bSgpKSB7CiAgICAgICAgaWYgKCFnZXRSZXF1aXJlZEVudW0oKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChoYXNSZXF1aXJlZEVudW1Ob01hc2soKSkgewogICAgICAgIGlmICghZ2V0UmVxdWlyZWRFbnVtTm9NYXNrKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtTXVsdGkoKSkgewogICAgICAgIGlmICghZ2V0UmVxdWlyZWRFbnVtTXVsdGkoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChoYXNSZXF1aXJlZE5vTWFzaygpKSB7CiAgICAgICAgaWYgKCFnZXRSZXF1aXJlZE5vTWFzaygpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEsIGdldENoaWxkKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMiwgZ2V0UGF5bG9hZCgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigzLCBkdW1teV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNSwgZ2V0UmVxdWlyZWRFbnVtKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNiwgZ2V0UmVxdWlyZWRFbnVtTm9NYXNrKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNywgZ2V0UmVxdWlyZWRFbnVtTXVsdGkoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg5LCBnZXRSZXF1aXJlZE5vTWFzaygpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGdldENoaWxkKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBnZXRQYXlsb2FkKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMywgZHVtbXlfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNSwgZ2V0UmVxdWlyZWRFbnVtKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2LCBnZXRSZXF1aXJlZEVudW1Ob01hc2soKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcsIGdldFJlcXVpcmVkRW51bU11bHRpKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5LCBnZXRSZXF1aXJlZE5vTWFzaygpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24pKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24pIG9iajsKCiAgICAgIGlmIChoYXNDaGlsZCgpICE9IG90aGVyLmhhc0NoaWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0NoaWxkKCkpIHsKICAgICAgICBpZiAoIWdldENoaWxkKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRDaGlsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNQYXlsb2FkKCkgIT0gb3RoZXIuaGFzUGF5bG9hZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNQYXlsb2FkKCkpIHsKICAgICAgICBpZiAoIWdldFBheWxvYWQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBheWxvYWQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRHVtbXkoKSAhPSBvdGhlci5oYXNEdW1teSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEdW1teSgpKSB7CiAgICAgICAgaWYgKGdldER1bW15KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RHVtbXkoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNSZXF1aXJlZEVudW0oKSAhPSBvdGhlci5oYXNSZXF1aXJlZEVudW0oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtKCkpIHsKICAgICAgICBpZiAoIWdldFJlcXVpcmVkRW51bSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVxdWlyZWRFbnVtKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1JlcXVpcmVkRW51bU5vTWFzaygpICE9IG90aGVyLmhhc1JlcXVpcmVkRW51bU5vTWFzaygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNSZXF1aXJlZEVudW1Ob01hc2soKSkgewogICAgICAgIGlmICghZ2V0UmVxdWlyZWRFbnVtTm9NYXNrKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXF1aXJlZEVudW1Ob01hc2soKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtTXVsdGkoKSAhPSBvdGhlci5oYXNSZXF1aXJlZEVudW1NdWx0aSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNSZXF1aXJlZEVudW1NdWx0aSgpKSB7CiAgICAgICAgaWYgKCFnZXRSZXF1aXJlZEVudW1NdWx0aSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVxdWlyZWRFbnVtTXVsdGkoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWROb01hc2soKSAhPSBvdGhlci5oYXNSZXF1aXJlZE5vTWFzaygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNSZXF1aXJlZE5vTWFzaygpKSB7CiAgICAgICAgaWYgKCFnZXRSZXF1aXJlZE5vTWFzaygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVxdWlyZWROb01hc2soKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNDaGlsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ0hJTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldENoaWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzUGF5bG9hZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFZTE9BRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGF5bG9hZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0R1bW15KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEVU1NWV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RHVtbXkoKTsKICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVFVSVJFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXF1aXJlZEVudW0oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNSZXF1aXJlZEVudW1Ob01hc2soKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUVVJUkVEX0VOVU1fTk9fTUFTS19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVxdWlyZWRFbnVtTm9NYXNrKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtTXVsdGkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUVVJUkVEX0VOVU1fTVVMVElfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcXVpcmVkRW51bU11bHRpKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzUmVxdWlyZWROb01hc2soKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUVVJUkVEX05PX01BU0tfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcXVpcmVkTm9NYXNrKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24pCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ25fZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24uY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbi5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbi5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRDaGlsZEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVxdWlyZWRFbnVtRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXF1aXJlZEVudW1Ob01hc2tGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldFJlcXVpcmVkRW51bU11bHRpRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXF1aXJlZE5vTWFza0ZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgY2hpbGRfID0gbnVsbDsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBwYXlsb2FkXyA9IG51bGw7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZHVtbXlfID0gMDsKICAgICAgICByZXF1aXJlZEVudW1fID0gbnVsbDsKICAgICAgICBpZiAocmVxdWlyZWRFbnVtQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVxdWlyZWRFbnVtQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgcmVxdWlyZWRFbnVtQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXF1aXJlZEVudW1Ob01hc2tfID0gbnVsbDsKICAgICAgICBpZiAocmVxdWlyZWRFbnVtTm9NYXNrQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVxdWlyZWRFbnVtTm9NYXNrQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgcmVxdWlyZWRFbnVtTm9NYXNrQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXF1aXJlZEVudW1NdWx0aV8gPSBudWxsOwogICAgICAgIGlmIChyZXF1aXJlZEVudW1NdWx0aUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJlcXVpcmVkRW51bU11bHRpQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgcmVxdWlyZWRFbnVtTXVsdGlCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJlcXVpcmVkTm9NYXNrXyA9IG51bGw7CiAgICAgICAgaWYgKHJlcXVpcmVkTm9NYXNrQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVxdWlyZWROb01hc2tCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICByZXF1aXJlZE5vTWFza0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ25fZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24odGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNoaWxkXyA9IGNoaWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gY2hpbGRfCiAgICAgICAgICAgICAgOiBjaGlsZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucGF5bG9hZF8gPSBwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gcGF5bG9hZF8KICAgICAgICAgICAgICA6IHBheWxvYWRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmR1bW15XyA9IGR1bW15XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5yZXF1aXJlZEVudW1fID0gcmVxdWlyZWRFbnVtQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gcmVxdWlyZWRFbnVtXwogICAgICAgICAgICAgIDogcmVxdWlyZWRFbnVtQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5yZXF1aXJlZEVudW1Ob01hc2tfID0gcmVxdWlyZWRFbnVtTm9NYXNrQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gcmVxdWlyZWRFbnVtTm9NYXNrXwogICAgICAgICAgICAgIDogcmVxdWlyZWRFbnVtTm9NYXNrQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5yZXF1aXJlZEVudW1NdWx0aV8gPSByZXF1aXJlZEVudW1NdWx0aUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IHJlcXVpcmVkRW51bU11bHRpXwogICAgICAgICAgICAgIDogcmVxdWlyZWRFbnVtTXVsdGlCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnJlcXVpcmVkTm9NYXNrXyA9IHJlcXVpcmVkTm9NYXNrQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gcmVxdWlyZWROb01hc2tfCiAgICAgICAgICAgICAgOiByZXF1aXJlZE5vTWFza0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24pIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzQ2hpbGQoKSkgewogICAgICAgICAgbWVyZ2VDaGlsZChvdGhlci5nZXRDaGlsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1BheWxvYWQoKSkgewogICAgICAgICAgbWVyZ2VQYXlsb2FkKG90aGVyLmdldFBheWxvYWQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNEdW1teSgpKSB7CiAgICAgICAgICBzZXREdW1teShvdGhlci5nZXREdW1teSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1JlcXVpcmVkRW51bSgpKSB7CiAgICAgICAgICBtZXJnZVJlcXVpcmVkRW51bShvdGhlci5nZXRSZXF1aXJlZEVudW0oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNSZXF1aXJlZEVudW1Ob01hc2soKSkgewogICAgICAgICAgbWVyZ2VSZXF1aXJlZEVudW1Ob01hc2sob3RoZXIuZ2V0UmVxdWlyZWRFbnVtTm9NYXNrKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzUmVxdWlyZWRFbnVtTXVsdGkoKSkgewogICAgICAgICAgbWVyZ2VSZXF1aXJlZEVudW1NdWx0aShvdGhlci5nZXRSZXF1aXJlZEVudW1NdWx0aSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1JlcXVpcmVkTm9NYXNrKCkpIHsKICAgICAgICAgIG1lcmdlUmVxdWlyZWROb01hc2sob3RoZXIuZ2V0UmVxdWlyZWROb01hc2soKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoaGFzQ2hpbGQoKSkgewogICAgICAgICAgaWYgKCFnZXRDaGlsZCgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChoYXNQYXlsb2FkKCkpIHsKICAgICAgICAgIGlmICghZ2V0UGF5bG9hZCgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChoYXNSZXF1aXJlZEVudW0oKSkgewogICAgICAgICAgaWYgKCFnZXRSZXF1aXJlZEVudW0oKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoaGFzUmVxdWlyZWRFbnVtTm9NYXNrKCkpIHsKICAgICAgICAgIGlmICghZ2V0UmVxdWlyZWRFbnVtTm9NYXNrKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGhhc1JlcXVpcmVkRW51bU11bHRpKCkpIHsKICAgICAgICAgIGlmICghZ2V0UmVxdWlyZWRFbnVtTXVsdGkoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoaGFzUmVxdWlyZWROb01hc2soKSkgewogICAgICAgICAgaWYgKCFnZXRSZXF1aXJlZE5vTWFzaygpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0Q2hpbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBkdW1teV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldFJlcXVpcmVkRW51bUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRSZXF1aXJlZEVudW1Ob01hc2tGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA1ODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0UmVxdWlyZWRFbnVtTXVsdGlGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU4CiAgICAgICAgICAgICAgY2FzZSA3NDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0UmVxdWlyZWROb01hc2tGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIGNoaWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24uQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduT3JCdWlsZGVyPiBjaGlsZEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjaGlsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNDaGlsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNoaWxkLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBnZXRDaGlsZCgpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gY2hpbGRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24uZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDaGlsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gdmFsdWUpIHsKICAgICAgICBpZiAoY2hpbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGNoaWxkXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDaGlsZCgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbi5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGNoaWxkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUNoaWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiB2YWx1ZSkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBjaGlsZF8gIT0gbnVsbCAmJgogICAgICAgICAgICBjaGlsZF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldENoaWxkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjaGlsZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoY2hpbGRfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gY2hpbGQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ2hpbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGNoaWxkXyA9IG51bGw7CiAgICAgICAgaWYgKGNoaWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgY2hpbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBjaGlsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduLkJ1aWxkZXIgZ2V0Q2hpbGRCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0Q2hpbGRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIGNoaWxkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduT3JCdWlsZGVyIGdldENoaWxkT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjaGlsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGNoaWxkXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24uZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBjaGlsZF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbiBjaGlsZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24uQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduT3JCdWlsZGVyPiAKICAgICAgICAgIGdldENoaWxkRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChjaGlsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGNoaWxkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24sIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbi5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ25PckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRDaGlsZCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgY2hpbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNoaWxkQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIHBheWxvYWRfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24sIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbi5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ25PckJ1aWxkZXI+IHBheWxvYWRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRGb3JlaWduIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXlsb2FkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1BheWxvYWQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRm9yZWlnbiBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHBheWxvYWQuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIGdldFBheWxvYWQoKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBheWxvYWRfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcGF5bG9hZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRGb3JlaWduIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBheWxvYWQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduIHZhbHVlKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHBheWxvYWRfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHBheWxvYWRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRm9yZWlnbiBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYXlsb2FkKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBwYXlsb2FkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEZvcmVpZ24gcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VQYXlsb2FkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbiB2YWx1ZSkgewogICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApICYmCiAgICAgICAgICAgIHBheWxvYWRfICE9IG51bGwgJiYKICAgICAgICAgICAgcGF5bG9hZF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldFBheWxvYWRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHBheWxvYWRfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHBheWxvYWRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAocGF5bG9hZF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRm9yZWlnbiBwYXlsb2FkID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBheWxvYWQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIHBheWxvYWRfID0gbnVsbDsKICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHBheWxvYWRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBwYXlsb2FkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEZvcmVpZ24gcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbi5CdWlsZGVyIGdldFBheWxvYWRCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEZvcmVpZ24gcGF5bG9hZCA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbk9yQnVpbGRlciBnZXRQYXlsb2FkT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHBheWxvYWRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBwYXlsb2FkXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24uZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBwYXlsb2FkXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRGb3JlaWduIHBheWxvYWQgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbiwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRm9yZWlnbk9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRQYXlsb2FkRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEZvcmVpZ24uQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRGb3JlaWduT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0UGF5bG9hZCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcGF5bG9hZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcGF5bG9hZEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBkdW1teV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkdW1teSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0R1bW15KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZHVtbXkuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RHVtbXkoKSB7CiAgICAgICAgcmV0dXJuIGR1bW15XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHVtbXkgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkdW1teSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER1bW15KGludCB2YWx1ZSkgewoKICAgICAgICBkdW1teV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR1bW15ID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRHVtbXkoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGR1bW15XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtIHJlcXVpcmVkRW51bV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU9yQnVpbGRlcj4gcmVxdWlyZWRFbnVtQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBvcHRpb25hbCBtZXNzYWdlIHRvIHRlc3QgcmVxdWlyZWQgY2xvc2VkIGVudW0uCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bSByZXF1aXJlZF9lbnVtID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRFbnVtIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1JlcXVpcmVkRW51bSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIG9wdGlvbmFsIG1lc3NhZ2UgdG8gdGVzdCByZXF1aXJlZCBjbG9zZWQgZW51bS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtIHJlcXVpcmVkX2VudW0gPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bSBnZXRSZXF1aXJlZEVudW0oKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXF1aXJlZEVudW1fID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0uZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXF1aXJlZEVudW1fOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVxdWlyZWRFbnVtQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogb3B0aW9uYWwgbWVzc2FnZSB0byB0ZXN0IHJlcXVpcmVkIGNsb3NlZCBlbnVtLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW0gcmVxdWlyZWRfZW51bSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVxdWlyZWRFbnVtKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmIChyZXF1aXJlZEVudW1CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlcXVpcmVkRW51bV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVxdWlyZWRFbnVtQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogb3B0aW9uYWwgbWVzc2FnZSB0byB0ZXN0IHJlcXVpcmVkIGNsb3NlZCBlbnVtLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW0gcmVxdWlyZWRfZW51bSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVxdWlyZWRFbnVtKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcXVpcmVkRW51bV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVxdWlyZWRFbnVtQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogb3B0aW9uYWwgbWVzc2FnZSB0byB0ZXN0IHJlcXVpcmVkIGNsb3NlZCBlbnVtLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW0gcmVxdWlyZWRfZW51bSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VSZXF1aXJlZEVudW0ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSAmJgogICAgICAgICAgICByZXF1aXJlZEVudW1fICE9IG51bGwgJiYKICAgICAgICAgICAgcmVxdWlyZWRFbnVtXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0uZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0UmVxdWlyZWRFbnVtQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXF1aXJlZEVudW1fID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcXVpcmVkRW51bUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXF1aXJlZEVudW1fICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogb3B0aW9uYWwgbWVzc2FnZSB0byB0ZXN0IHJlcXVpcmVkIGNsb3NlZCBlbnVtLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW0gcmVxdWlyZWRfZW51bSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXF1aXJlZEVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIHJlcXVpcmVkRW51bV8gPSBudWxsOwogICAgICAgIGlmIChyZXF1aXJlZEVudW1CdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXF1aXJlZEVudW1CdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICByZXF1aXJlZEVudW1CdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBvcHRpb25hbCBtZXNzYWdlIHRvIHRlc3QgcmVxdWlyZWQgY2xvc2VkIGVudW0uCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bSByZXF1aXJlZF9lbnVtID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtLkJ1aWxkZXIgZ2V0UmVxdWlyZWRFbnVtQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldFJlcXVpcmVkRW51bUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogb3B0aW9uYWwgbWVzc2FnZSB0byB0ZXN0IHJlcXVpcmVkIGNsb3NlZCBlbnVtLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW0gcmVxdWlyZWRfZW51bSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU9yQnVpbGRlciBnZXRSZXF1aXJlZEVudW1PckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXF1aXJlZEVudW1CdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXF1aXJlZEVudW1fID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHJlcXVpcmVkRW51bV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBvcHRpb25hbCBtZXNzYWdlIHRvIHRlc3QgcmVxdWlyZWQgY2xvc2VkIGVudW0uCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bSByZXF1aXJlZF9lbnVtID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW0sIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1PckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVxdWlyZWRFbnVtRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXF1aXJlZEVudW1CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXF1aXJlZEVudW1CdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldFJlcXVpcmVkRW51bSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVxdWlyZWRFbnVtXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXF1aXJlZEVudW1CdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgcmVxdWlyZWRFbnVtTm9NYXNrXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrT3JCdWlsZGVyPiByZXF1aXJlZEVudW1Ob01hc2tCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIHJlcXVpcmVkX2VudW1fbm9fbWFzayA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRW51bU5vTWFzayBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZEVudW1Ob01hc2soKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU5vTWFzayByZXF1aXJlZF9lbnVtX25vX21hc2sgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRFbnVtTm9NYXNrLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzayBnZXRSZXF1aXJlZEVudW1Ob01hc2soKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bU5vTWFza0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXF1aXJlZEVudW1Ob01hc2tfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXF1aXJlZEVudW1Ob01hc2tfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVxdWlyZWRFbnVtTm9NYXNrQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgcmVxdWlyZWRfZW51bV9ub19tYXNrID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXF1aXJlZEVudW1Ob01hc2socHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bU5vTWFza0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgcmVxdWlyZWRFbnVtTm9NYXNrXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXF1aXJlZEVudW1Ob01hc2tCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU5vTWFzayByZXF1aXJlZF9lbnVtX25vX21hc2sgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcXVpcmVkRW51bU5vTWFzaygKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzay5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXF1aXJlZEVudW1Ob01hc2tCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXF1aXJlZEVudW1Ob01hc2tfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcXVpcmVkRW51bU5vTWFza0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIHJlcXVpcmVkX2VudW1fbm9fbWFzayA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VSZXF1aXJlZEVudW1Ob01hc2socHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bU5vTWFza0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSAmJgogICAgICAgICAgICByZXF1aXJlZEVudW1Ob01hc2tfICE9IG51bGwgJiYKICAgICAgICAgICAgcmVxdWlyZWRFbnVtTm9NYXNrXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0UmVxdWlyZWRFbnVtTm9NYXNrQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXF1aXJlZEVudW1Ob01hc2tfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcXVpcmVkRW51bU5vTWFza0J1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXF1aXJlZEVudW1Ob01hc2tfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1Ob01hc2sgcmVxdWlyZWRfZW51bV9ub19tYXNrID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcXVpcmVkRW51bU5vTWFzaygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgcmVxdWlyZWRFbnVtTm9NYXNrXyA9IG51bGw7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bU5vTWFza0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJlcXVpcmVkRW51bU5vTWFza0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHJlcXVpcmVkRW51bU5vTWFza0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIHJlcXVpcmVkX2VudW1fbm9fbWFzayA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzay5CdWlsZGVyIGdldFJlcXVpcmVkRW51bU5vTWFza0J1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRSZXF1aXJlZEVudW1Ob01hc2tGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrIHJlcXVpcmVkX2VudW1fbm9fbWFzayA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFza09yQnVpbGRlciBnZXRSZXF1aXJlZEVudW1Ob01hc2tPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bU5vTWFza0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXF1aXJlZEVudW1Ob01hc2tCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXF1aXJlZEVudW1Ob01hc2tfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzay5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHJlcXVpcmVkRW51bU5vTWFza187CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU5vTWFzayByZXF1aXJlZF9lbnVtX25vX21hc2sgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFzaywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU5vTWFza09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXF1aXJlZEVudW1Ob01hc2tGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bU5vTWFza0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcXVpcmVkRW51bU5vTWFza0J1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1Ob01hc2suQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTm9NYXNrT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0UmVxdWlyZWRFbnVtTm9NYXNrKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXF1aXJlZEVudW1Ob01hc2tfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcXVpcmVkRW51bU5vTWFza0J1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpIHJlcXVpcmVkRW51bU11bHRpXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGksIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpT3JCdWlsZGVyPiByZXF1aXJlZEVudW1NdWx0aUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aSByZXF1aXJlZF9lbnVtX211bHRpID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRFbnVtTXVsdGkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzUmVxdWlyZWRFbnVtTXVsdGkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpIHJlcXVpcmVkX2VudW1fbXVsdGkgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVxdWlyZWRFbnVtTXVsdGkuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgZ2V0UmVxdWlyZWRFbnVtTXVsdGkoKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bU11bHRpQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcXVpcmVkRW51bU11bHRpXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXF1aXJlZEVudW1NdWx0aV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXF1aXJlZEVudW1NdWx0aUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgcmVxdWlyZWRfZW51bV9tdWx0aSA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVxdWlyZWRFbnVtTXVsdGkocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgdmFsdWUpIHsKICAgICAgICBpZiAocmVxdWlyZWRFbnVtTXVsdGlCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlcXVpcmVkRW51bU11bHRpXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXF1aXJlZEVudW1NdWx0aUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgcmVxdWlyZWRfZW51bV9tdWx0aSA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVxdWlyZWRFbnVtTXVsdGkoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXF1aXJlZEVudW1NdWx0aUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcXVpcmVkRW51bU11bHRpXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXF1aXJlZEVudW1NdWx0aUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgcmVxdWlyZWRfZW51bV9tdWx0aSA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VSZXF1aXJlZEVudW1NdWx0aShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSB2YWx1ZSkgewogICAgICAgIGlmIChyZXF1aXJlZEVudW1NdWx0aUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSAmJgogICAgICAgICAgICByZXF1aXJlZEVudW1NdWx0aV8gIT0gbnVsbCAmJgogICAgICAgICAgICByZXF1aXJlZEVudW1NdWx0aV8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0UmVxdWlyZWRFbnVtTXVsdGlCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlcXVpcmVkRW51bU11bHRpXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXF1aXJlZEVudW1NdWx0aUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXF1aXJlZEVudW1NdWx0aV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bU11bHRpIHJlcXVpcmVkX2VudW1fbXVsdGkgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVxdWlyZWRFbnVtTXVsdGkoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIHJlcXVpcmVkRW51bU11bHRpXyA9IG51bGw7CiAgICAgICAgaWYgKHJlcXVpcmVkRW51bU11bHRpQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVxdWlyZWRFbnVtTXVsdGlCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICByZXF1aXJlZEVudW1NdWx0aUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgcmVxdWlyZWRfZW51bV9tdWx0aSA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpLkJ1aWxkZXIgZ2V0UmVxdWlyZWRFbnVtTXVsdGlCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0UmVxdWlyZWRFbnVtTXVsdGlGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgcmVxdWlyZWRfZW51bV9tdWx0aSA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpT3JCdWlsZGVyIGdldFJlcXVpcmVkRW51bU11bHRpT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXF1aXJlZEVudW1NdWx0aUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXF1aXJlZEVudW1NdWx0aUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcXVpcmVkRW51bU11bHRpXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHJlcXVpcmVkRW51bU11bHRpXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnVtTXVsdGkgcmVxdWlyZWRfZW51bV9tdWx0aSA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGksIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkRW51bU11bHRpT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcXVpcmVkRW51bU11bHRpRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXF1aXJlZEVudW1NdWx0aUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcXVpcmVkRW51bU11bHRpQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZEVudW1NdWx0aSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGkuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRFbnVtTXVsdGlPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRSZXF1aXJlZEVudW1NdWx0aSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVxdWlyZWRFbnVtTXVsdGlfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcXVpcmVkRW51bU11bHRpQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSByZXF1aXJlZE5vTWFza187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGksIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aU9yQnVpbGRlcj4gcmVxdWlyZWROb01hc2tCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSByZXF1aXJlZF9ub19tYXNrID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWROb01hc2sgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzUmVxdWlyZWROb01hc2soKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkgcmVxdWlyZWRfbm9fbWFzayA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZE5vTWFzay4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIGdldFJlcXVpcmVkTm9NYXNrKCkgewogICAgICAgIGlmIChyZXF1aXJlZE5vTWFza0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXF1aXJlZE5vTWFza18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXF1aXJlZE5vTWFza187CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXF1aXJlZE5vTWFza0J1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSByZXF1aXJlZF9ub19tYXNrID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXF1aXJlZE5vTWFzayhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkTm9NYXNrQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXF1aXJlZE5vTWFza18gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVxdWlyZWROb01hc2tCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkgcmVxdWlyZWRfbm9fbWFzayA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVxdWlyZWROb01hc2soCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcXVpcmVkTm9NYXNrQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVxdWlyZWROb01hc2tfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcXVpcmVkTm9NYXNrQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHJlcXVpcmVkX25vX21hc2sgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlUmVxdWlyZWROb01hc2socHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSB2YWx1ZSkgewogICAgICAgIGlmIChyZXF1aXJlZE5vTWFza0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSAmJgogICAgICAgICAgICByZXF1aXJlZE5vTWFza18gIT0gbnVsbCAmJgogICAgICAgICAgICByZXF1aXJlZE5vTWFza18gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRSZXF1aXJlZE5vTWFza0J1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVxdWlyZWROb01hc2tfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcXVpcmVkTm9NYXNrQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcXVpcmVkTm9NYXNrXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSByZXF1aXJlZF9ub19tYXNrID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcXVpcmVkTm9NYXNrKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICByZXF1aXJlZE5vTWFza18gPSBudWxsOwogICAgICAgIGlmIChyZXF1aXJlZE5vTWFza0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJlcXVpcmVkTm9NYXNrQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgcmVxdWlyZWROb01hc2tCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkgcmVxdWlyZWRfbm9fbWFzayA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuQnVpbGRlciBnZXRSZXF1aXJlZE5vTWFza0J1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRSZXF1aXJlZE5vTWFza0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHJlcXVpcmVkX25vX21hc2sgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpT3JCdWlsZGVyIGdldFJlcXVpcmVkTm9NYXNrT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXF1aXJlZE5vTWFza0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXF1aXJlZE5vTWFza0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcXVpcmVkTm9NYXNrXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcmVxdWlyZWROb01hc2tfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTWFza011bHRpIHJlcXVpcmVkX25vX21hc2sgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGksIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkTm9NYXNrTXVsdGkuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXF1aXJlZE5vTWFza0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVxdWlyZWROb01hc2tCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXF1aXJlZE5vTWFza0J1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWROb01hc2tNdWx0aS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE5vTWFza011bHRpT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0UmVxdWlyZWROb01hc2soKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcXVpcmVkTm9NYXNrXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXF1aXJlZE5vTWFza0J1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24pCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24pCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ24gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0Rm9yZWlnbk5lc3RlZE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0Rm9yZWlnbk5lc3RlZCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBmb3JlaWduX25lc3RlZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb3JlaWduTmVzdGVkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb3JlaWduTmVzdGVkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBmb3JlaWduX25lc3RlZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9yZWlnbk5lc3RlZC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRGb3JlaWduTmVzdGVkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBmb3JlaWduX25lc3RlZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldEZvcmVpZ25OZXN0ZWRPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUZXN0IHRoYXQgd2UgY2FuIHVzZSBOZXN0ZWRNZXNzYWdlIGZyb20gb3V0c2lkZSBUZXN0QWxsVHlwZXMuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0Rm9yZWlnbk5lc3RlZH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RGb3JlaWduTmVzdGVkIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGb3JlaWduTmVzdGVkKQogICAgICBUZXN0Rm9yZWlnbk5lc3RlZE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdEZvcmVpZ25OZXN0ZWQubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdEZvcmVpZ25OZXN0ZWQoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0Rm9yZWlnbk5lc3RlZCgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0Rm9yZWlnbk5lc3RlZCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RGb3JlaWduTmVzdGVkX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZvcmVpZ25OZXN0ZWRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT1JFSUdOX05FU1RFRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGZvcmVpZ25OZXN0ZWRfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZm9yZWlnbl9uZXN0ZWQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9yZWlnbk5lc3RlZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZvcmVpZ25OZXN0ZWQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGZvcmVpZ25fbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb3JlaWduTmVzdGVkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRGb3JlaWduTmVzdGVkKCkgewogICAgICByZXR1cm4gZm9yZWlnbk5lc3RlZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmb3JlaWduTmVzdGVkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGZvcmVpZ25fbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldEZvcmVpZ25OZXN0ZWRPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBmb3JlaWduTmVzdGVkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZvcmVpZ25OZXN0ZWRfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRGb3JlaWduTmVzdGVkKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0Rm9yZWlnbk5lc3RlZCgpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZvcmVpZ25OZXN0ZWQpIG9iajsKCiAgICAgIGlmIChoYXNGb3JlaWduTmVzdGVkKCkgIT0gb3RoZXIuaGFzRm9yZWlnbk5lc3RlZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGb3JlaWduTmVzdGVkKCkpIHsKICAgICAgICBpZiAoIWdldEZvcmVpZ25OZXN0ZWQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZvcmVpZ25OZXN0ZWQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNGb3JlaWduTmVzdGVkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGT1JFSUdOX05FU1RFRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Rm9yZWlnbk5lc3RlZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZvcmVpZ25OZXN0ZWQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Rm9yZWlnbk5lc3RlZCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Rm9yZWlnbk5lc3RlZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZvcmVpZ25OZXN0ZWQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Rm9yZWlnbk5lc3RlZCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZvcmVpZ25OZXN0ZWQgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Rm9yZWlnbk5lc3RlZCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Rm9yZWlnbk5lc3RlZCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Rm9yZWlnbk5lc3RlZCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Rm9yZWlnbk5lc3RlZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZvcmVpZ25OZXN0ZWQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Rm9yZWlnbk5lc3RlZCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdCB0aGF0IHdlIGNhbiB1c2UgTmVzdGVkTWVzc2FnZSBmcm9tIG91dHNpZGUgVGVzdEFsbFR5cGVzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEZvcmVpZ25OZXN0ZWR9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0Rm9yZWlnbk5lc3RlZCkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RGb3JlaWduTmVzdGVkX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RGb3JlaWduTmVzdGVkX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZvcmVpZ25OZXN0ZWQuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZvcmVpZ25OZXN0ZWQuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldEZvcmVpZ25OZXN0ZWRGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGZvcmVpZ25OZXN0ZWRfID0gbnVsbDsKICAgICAgICBpZiAoZm9yZWlnbk5lc3RlZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZvcmVpZ25OZXN0ZWRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmb3JlaWduTmVzdGVkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZvcmVpZ25OZXN0ZWRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Rm9yZWlnbk5lc3RlZCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZvcmVpZ25OZXN0ZWQgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZvcmVpZ25OZXN0ZWQgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZm9yZWlnbk5lc3RlZF8gPSBmb3JlaWduTmVzdGVkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gZm9yZWlnbk5lc3RlZF8KICAgICAgICAgICAgICA6IGZvcmVpZ25OZXN0ZWRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Rm9yZWlnbk5lc3RlZCkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Rm9yZWlnbk5lc3RlZClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZvcmVpZ25OZXN0ZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNGb3JlaWduTmVzdGVkKCkpIHsKICAgICAgICAgIG1lcmdlRm9yZWlnbk5lc3RlZChvdGhlci5nZXRGb3JlaWduTmVzdGVkKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRGb3JlaWduTmVzdGVkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZm9yZWlnbk5lc3RlZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gZm9yZWlnbk5lc3RlZEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGZvcmVpZ25fbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9yZWlnbk5lc3RlZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb3JlaWduTmVzdGVkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGZvcmVpZ25fbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZvcmVpZ25OZXN0ZWQuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBnZXRGb3JlaWduTmVzdGVkKCkgewogICAgICAgIGlmIChmb3JlaWduTmVzdGVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZvcmVpZ25OZXN0ZWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZm9yZWlnbk5lc3RlZF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmb3JlaWduTmVzdGVkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIGZvcmVpZ25fbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb3JlaWduTmVzdGVkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAoZm9yZWlnbk5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZm9yZWlnbk5lc3RlZF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZm9yZWlnbk5lc3RlZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBmb3JlaWduX25lc3RlZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9yZWlnbk5lc3RlZCgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZm9yZWlnbk5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZvcmVpZ25OZXN0ZWRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvcmVpZ25OZXN0ZWRCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZm9yZWlnbl9uZXN0ZWQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRm9yZWlnbk5lc3RlZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZvcmVpZ25OZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgZm9yZWlnbk5lc3RlZF8gIT0gbnVsbCAmJgogICAgICAgICAgICBmb3JlaWduTmVzdGVkXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEZvcmVpZ25OZXN0ZWRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvcmVpZ25OZXN0ZWRfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvcmVpZ25OZXN0ZWRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZm9yZWlnbk5lc3RlZF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZm9yZWlnbl9uZXN0ZWQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9yZWlnbk5lc3RlZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgZm9yZWlnbk5lc3RlZF8gPSBudWxsOwogICAgICAgIGlmIChmb3JlaWduTmVzdGVkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZm9yZWlnbk5lc3RlZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZvcmVpZ25OZXN0ZWRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZm9yZWlnbl9uZXN0ZWQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0Rm9yZWlnbk5lc3RlZEJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRGb3JlaWduTmVzdGVkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UgZm9yZWlnbl9uZXN0ZWQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldEZvcmVpZ25OZXN0ZWRPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZvcmVpZ25OZXN0ZWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZm9yZWlnbk5lc3RlZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZvcmVpZ25OZXN0ZWRfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmb3JlaWduTmVzdGVkXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSBmb3JlaWduX25lc3RlZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZvcmVpZ25OZXN0ZWRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZvcmVpZ25OZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmb3JlaWduTmVzdGVkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRGb3JlaWduTmVzdGVkKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmb3JlaWduTmVzdGVkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmb3JlaWduTmVzdGVkQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEZvcmVpZ25OZXN0ZWQpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGb3JlaWduTmVzdGVkKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Rm9yZWlnbk5lc3RlZCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEZvcmVpZ25OZXN0ZWQ+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEZvcmVpZ25OZXN0ZWQ+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0Rm9yZWlnbk5lc3RlZCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RGb3JlaWduTmVzdGVkPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RGb3JlaWduTmVzdGVkPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGb3JlaWduTmVzdGVkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEVtcHR5TWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0RW1wdHlNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRlc3RFbXB0eU1lc3NhZ2UgaXMgdXNlZCB0byB0ZXN0IHVua25vd24gZmllbGQgc3VwcG9ydC4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0RW1wdHlNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2UpCiAgICAgIFRlc3RFbXB0eU1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RFbXB0eU1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdEVtcHR5TWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RFbXB0eU1lc3NhZ2UoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdEVtcHR5TWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlKSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdEVtcHR5TWVzc2FnZSBpcyB1c2VkIHRvIHRlc3QgdW5rbm93biBmaWVsZCBzdXBwb3J0LgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2UpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2UodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RW1wdHlNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RW1wdHlNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEVtcHR5TWVzc2FnZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0RW1wdHlNZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdEVtcHR5TWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFbXB0eU1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEVtcHR5TWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxUZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnM+IHsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBMaWtlIGFib3ZlLCBidXQgZGVjbGFyZSBhbGwgZmllbGQgbnVtYmVycyBhcyBwb3RlbnRpYWwgZXh0ZW5zaW9ucy4gIE5vCiAgICogYWN0dWFsIGV4dGVuc2lvbnMgc2hvdWxkIGV2ZXIgYmUgZGVmaW5lZCBmb3IgdGhpcyB0eXBlLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZU1lc3NhZ2U8CiAgICAgICAgVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zKQogICAgICBUZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMsID8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucygpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuRXh0ZW5kYWJsZU1lc3NhZ2U8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnM+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDUzNjg3MDkxMiwgb3V0cHV0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplKCk7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucykgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBMaWtlIGFib3ZlLCBidXQgZGVjbGFyZSBhbGwgZmllbGQgbnVtYmVycyBhcyBwb3RlbnRpYWwgZXh0ZW5zaW9ucy4gIE5vCiAgICAgKiBhY3R1YWwgZXh0ZW5zaW9ucyBzaG91bGQgZXZlciBiZSBkZWZpbmVkIGZvciB0aGlzIHR5cGUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucywgQnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9uc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyh0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMsIFR5cGU+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBhZGRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFQ+IEJ1aWxkZXIgY2xlYXJFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zLCBUPiBleHRlbnNpb24pIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VFeHRlbnNpb25GaWVsZHMob3RoZXIpOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0UGlja2xlTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBOZWVkZWQgZm9yIGEgUHl0aG9uIHRlc3QuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlKQogICAgICBUZXN0UGlja2xlTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0UGlja2xlTmVzdGVkTWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0UGlja2xlTmVzdGVkTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJiIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzQmIoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJiLgogICAgICAgKi8KICAgICAgaW50IGdldEJiKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTmVzdGVkTWVzc2FnZSBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSkKICAgICAgICBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBOZXN0ZWRNZXNzYWdlKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHVibGljIGludGVyZmFjZSBOZXN0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UpCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBjYyA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2MgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIGJvb2xlYW4gaGFzQ2MoKTsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBjYyA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGNjLgogICAgICAgICAqLwogICAgICAgIGludCBnZXRDYygpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2V9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZE5lc3RlZE1lc3NhZ2UgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UpCiAgICAgICAgICBOZXN0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgICAgLy8gVXNlIE5lc3RlZE5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgICBwcml2YXRlIE5lc3RlZE5lc3RlZE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBOZXN0ZWROZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgICByZXR1cm4gbmV3IE5lc3RlZE5lc3RlZE1lc3NhZ2UoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9OZXN0ZWROZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX05lc3RlZE5lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0NfRklFTERfTlVNQkVSID0gMTsKICAgICAgICBwcml2YXRlIGludCBjY18gPSAwOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGNjID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjYyBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0NjKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBjYyA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGNjLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldENjKCkgewogICAgICAgICAgcmV0dXJuIGNjXzsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGNjXyk7CiAgICAgICAgICB9CiAgICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgICBzaXplID0gMDsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBjY18pOwogICAgICAgICAgfQogICAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgfQogICAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UpKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICAgIH0KICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICAgICAgaWYgKGhhc0NjKCkgIT0gb3RoZXIuaGFzQ2MoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgaWYgKGhhc0NjKCkpIHsKICAgICAgICAgICAgaWYgKGdldENjKCkKICAgICAgICAgICAgICAgICE9IG90aGVyLmdldENjKCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICAgIH0KICAgICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGlmIChoYXNDYygpKSB7CiAgICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIENDX0ZJRUxEX05VTUJFUjsKICAgICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Q2MoKTsKICAgICAgICAgIH0KICAgICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZX0KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UpCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfTmVzdGVkTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfTmVzdGVkTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgICAgfQoKICAgICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgICAgY2NfID0gMDsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9OZXN0ZWROZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlKHRoaXMpOwogICAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICB9CgogICAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgICAgcmVzdWx0LmNjXyA9IGNjXzsKICAgICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlKSB7CiAgICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2Upb3RoZXIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5OZXN0ZWROZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgICAgaWYgKG90aGVyLmhhc0NjKCkpIHsKICAgICAgICAgICAgICBzZXRDYyhvdGhlci5nZXRDYygpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgICAgICBjY18gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgICAgcHJpdmF0ZSBpbnQgY2NfIDsKICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgY2MgPSAxOzwvY29kZT4KICAgICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY2MgZmllbGQgaXMgc2V0LgogICAgICAgICAgICovCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNDYygpIHsKICAgICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgICAgfQogICAgICAgICAgLyoqCiAgICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBjYyA9IDE7PC9jb2RlPgogICAgICAgICAgICogQHJldHVybiBUaGUgY2MuCiAgICAgICAgICAgKi8KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBpbnQgZ2V0Q2MoKSB7CiAgICAgICAgICAgIHJldHVybiBjY187CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGNjID0gMTs8L2NvZGU+CiAgICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGNjIHRvIHNldC4KICAgICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Q2MoaW50IHZhbHVlKSB7CgogICAgICAgICAgICBjY18gPSB2YWx1ZTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGNjID0gMTs8L2NvZGU+CiAgICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ2MoKSB7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgICAgY2NfID0gMDsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgICB9CgoKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSkKICAgICAgICB9CgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UpCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgICBzdGF0aWMgewogICAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuTmVzdGVkTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE5lc3RlZE1lc3NhZ2U+CiAgICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE5lc3RlZE5lc3RlZE1lc3NhZ2U+KCkgewogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIE5lc3RlZE5lc3RlZE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWROZXN0ZWRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWROZXN0ZWRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLk5lc3RlZE5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICAgIH0KCiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJCX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgaW50IGJiXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJiIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQmIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBiYi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRCYigpIHsKICAgICAgICByZXR1cm4gYmJfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgYmJfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgYmJfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICAgIGlmIChoYXNCYigpICE9IG90aGVyLmhhc0JiKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzQmIoKSkgewogICAgICAgICAgaWYgKGdldEJiKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRCYigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzQmIoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkJfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QmIoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2V9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgYmJfID0gMDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5iYl8gPSBiYl87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzQmIoKSkgewogICAgICAgICAgICBzZXRCYihvdGhlci5nZXRCYigpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgICBiYl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCBiYl8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYiBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0JiKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGJiLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldEJiKCkgewogICAgICAgICAgcmV0dXJuIGJiXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJiIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmIoaW50IHZhbHVlKSB7CgogICAgICAgICAgYmJfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJiKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgYmJfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE5lc3RlZE1lc3NhZ2U+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTmVzdGVkTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBOZWVkZWQgZm9yIGEgUHl0aG9uIHRlc3QuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGlja2xlTmVzdGVkTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UGlja2xlTmVzdGVkTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxUZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXM+IHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZU1lc3NhZ2U8CiAgICAgICAgVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzKQogICAgICBUZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMsID8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcygpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuRXh0ZW5kYWJsZU1lc3NhZ2U8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXM+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDUzNjg3MDkxMiwgb3V0cHV0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplKCk7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcyBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcykgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzLCBCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcywgVHlwZT4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcywgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VD4gQnVpbGRlciBjbGVhckV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMsIFQ+IGV4dGVuc2lvbikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckV4dGVuc2lvbihleHRlbnNpb24pOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RSZWFsbHlMYXJnZVRhZ051bWJlck9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlIGxhcmdlc3QgcG9zc2libGUgdGFnIG51bWJlciBpcyAyXjI4IC0gMSwgc2luY2UgdGhlIHdpcmUgZm9ybWF0IHVzZXMKICAgICAqIHRocmVlIGJpdHMgdG8gY29tbXVuaWNhdGUgd2lyZSB0eXBlLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNBKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGUgbGFyZ2VzdCBwb3NzaWJsZSB0YWcgbnVtYmVyIGlzIDJeMjggLSAxLCBzaW5jZSB0aGUgd2lyZSBmb3JtYXQgdXNlcwogICAgICogdGhyZWUgYml0cyB0byBjb21tdW5pY2F0ZSB3aXJlIHR5cGUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICovCiAgICBpbnQgZ2V0QSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAyNjg0MzU0NTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQmIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAyNjg0MzU0NTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYmIuCiAgICAgKi8KICAgIGludCBnZXRCYigpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRlc3QgdGhhdCByZWFsbHkgbGFyZ2UgdGFnIG51bWJlcnMgZG9uJ3QgYnJlYWsgYW55dGhpbmcuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXJ9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyKQogICAgICBUZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXJPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RSZWFsbHlMYXJnZVRhZ051bWJlci5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBhXyA9IDA7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGUgbGFyZ2VzdCBwb3NzaWJsZSB0YWcgbnVtYmVyIGlzIDJeMjggLSAxLCBzaW5jZSB0aGUgd2lyZSBmb3JtYXQgdXNlcwogICAgICogdGhyZWUgYml0cyB0byBjb21tdW5pY2F0ZSB3aXJlIHR5cGUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGUgbGFyZ2VzdCBwb3NzaWJsZSB0YWcgbnVtYmVyIGlzIDJeMjggLSAxLCBzaW5jZSB0aGUgd2lyZSBmb3JtYXQgdXNlcwogICAgICogdGhyZWUgYml0cyB0byBjb21tdW5pY2F0ZSB3aXJlIHR5cGUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEEoKSB7CiAgICAgIHJldHVybiBhXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQl9GSUVMRF9OVU1CRVIgPSAyNjg0MzU0NTU7CiAgICBwcml2YXRlIGludCBiYl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYiA9IDI2ODQzNTQ1NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJiIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQmIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAyNjg0MzU0NTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYmIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0QmIoKSB7CiAgICAgIHJldHVybiBiYl87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBhXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMjY4NDM1NDU1LCBiYl8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIGFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDI2ODQzNTQ1NSwgYmJfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWFsbHlMYXJnZVRhZ051bWJlcikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIpIG9iajsKCiAgICAgIGlmIChoYXNBKCkgIT0gb3RoZXIuaGFzQSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBpZiAoZ2V0QSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEEoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNCYigpICE9IG90aGVyLmhhc0JiKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0JiKCkpIHsKICAgICAgICBpZiAoZ2V0QmIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRCYigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzQSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QSgpOwogICAgICB9CiAgICAgIGlmIChoYXNCYigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEJiKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWFsbHlMYXJnZVRhZ051bWJlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWFsbHlMYXJnZVRhZ051bWJlciBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRlc3QgdGhhdCByZWFsbHkgbGFyZ2UgdGFnIG51bWJlcnMgZG9uJ3QgYnJlYWsgYW55dGhpbmcuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZWFsbHlMYXJnZVRhZ051bWJlcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWFsbHlMYXJnZVRhZ051bWJlci5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWFsbHlMYXJnZVRhZ051bWJlci5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgYV8gPSAwOwogICAgICAgIGJiXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZWFsbHlMYXJnZVRhZ051bWJlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWFsbHlMYXJnZVRhZ051bWJlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWFsbHlMYXJnZVRhZ051bWJlci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWFsbHlMYXJnZVRhZ051bWJlciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmFfID0gYV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuYmJfID0gYmJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzQSgpKSB7CiAgICAgICAgICBzZXRBKG90aGVyLmdldEEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNCYigpKSB7CiAgICAgICAgICBzZXRCYihvdGhlci5nZXRCYigpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBhXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDIxNDc0ODM2NDA6IHsKICAgICAgICAgICAgICAgIGJiXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxNDc0ODM2NDAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgYV8gOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlIGxhcmdlc3QgcG9zc2libGUgdGFnIG51bWJlciBpcyAyXjI4IC0gMSwgc2luY2UgdGhlIHdpcmUgZm9ybWF0IHVzZXMKICAgICAgICogdGhyZWUgYml0cyB0byBjb21tdW5pY2F0ZSB3aXJlIHR5cGUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGUgbGFyZ2VzdCBwb3NzaWJsZSB0YWcgbnVtYmVyIGlzIDJeMjggLSAxLCBzaW5jZSB0aGUgd2lyZSBmb3JtYXQgdXNlcwogICAgICAgKiB0aHJlZSBiaXRzIHRvIGNvbW11bmljYXRlIHdpcmUgdHlwZS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgIHJldHVybiBhXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlIGxhcmdlc3QgcG9zc2libGUgdGFnIG51bWJlciBpcyAyXjI4IC0gMSwgc2luY2UgdGhlIHdpcmUgZm9ybWF0IHVzZXMKICAgICAgICogdGhyZWUgYml0cyB0byBjb21tdW5pY2F0ZSB3aXJlIHR5cGUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEEoaW50IHZhbHVlKSB7CgogICAgICAgIGFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGUgbGFyZ2VzdCBwb3NzaWJsZSB0YWcgbnVtYmVyIGlzIDJeMjggLSAxLCBzaW5jZSB0aGUgd2lyZSBmb3JtYXQgdXNlcwogICAgICAgKiB0aHJlZSBiaXRzIHRvIGNvbW11bmljYXRlIHdpcmUgdHlwZS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBhXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJiXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYiA9IDI2ODQzNTQ1NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNCYigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJiID0gMjY4NDM1NDU1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYmIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0QmIoKSB7CiAgICAgICAgcmV0dXJuIGJiXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAyNjg0MzU0NTU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJiIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmIoaW50IHZhbHVlKSB7CgogICAgICAgIGJiXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAyNjg0MzU0NTU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJiKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBiYl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWFsbHlMYXJnZVRhZ051bWJlcikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RSZWFsbHlMYXJnZVRhZ051bWJlcj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RSZWFsbHlMYXJnZVRhZ051bWJlciBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZWFsbHlMYXJnZVRhZ051bWJlcj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFJlY3Vyc2l2ZU1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNBKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVjdXJzaXZlTWVzc2FnZSBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlIGdldEEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNZXNzYWdlIGEgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZU9yQnVpbGRlciBnZXRBT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0koKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaS4KICAgICAqLwogICAgaW50IGdldEkoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0UmVjdXJzaXZlTWVzc2FnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVjdXJzaXZlTWVzc2FnZSkKICAgICAgVGVzdFJlY3Vyc2l2ZU1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RSZWN1cnNpdmVNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RSZWN1cnNpdmVNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVjdXJzaXZlTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZWN1cnNpdmVNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlIGFfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgZ2V0QSgpIHsKICAgICAgcmV0dXJuIGFfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogYV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVjdXJzaXZlTWVzc2FnZSBhID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlT3JCdWlsZGVyIGdldEFPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBhXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgaW50IGlfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzSSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEkoKSB7CiAgICAgIHJldHVybiBpXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgZ2V0QSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyLCBpXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRBKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMiwgaV8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKGhhc0EoKSAhPSBvdGhlci5oYXNBKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgIGlmICghZ2V0QSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0QSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNJKCkgIT0gb3RoZXIuaGFzSSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNJKCkpIHsKICAgICAgICBpZiAoZ2V0SSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEkoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNJKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRJKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVjdXJzaXZlTWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNZXNzYWdlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2VPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlY3Vyc2l2ZU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlY3Vyc2l2ZU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0QUZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgYV8gPSBudWxsOwogICAgICAgIGlmIChhQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgYUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGFCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlY3Vyc2l2ZU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuYV8gPSBhQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gYV8KICAgICAgICAgICAgICA6IGFCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmlfID0gaV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0EoKSkgewogICAgICAgICAgbWVyZ2VBKG90aGVyLmdldEEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNJKCkpIHsKICAgICAgICAgIHNldEkob3RoZXIuZ2V0SSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0QUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICBpXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBhXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlT3JCdWlsZGVyPiBhQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVjdXJzaXZlTWVzc2FnZSBhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBnZXRBKCkgewogICAgICAgIGlmIChhQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGFfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogYV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBhQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNZXNzYWdlIGEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEEocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChhQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNZXNzYWdlIGEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEEoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBhXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNZXNzYWdlIGEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlQShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKGFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgYV8gIT0gbnVsbCAmJgogICAgICAgICAgICBhXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEFCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGFfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGFCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoYV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgYSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBhXyA9IG51bGw7CiAgICAgICAgaWYgKGFCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBhQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgYUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVjdXJzaXZlTWVzc2FnZSBhID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZS5CdWlsZGVyIGdldEFCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0QUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNZXNzYWdlIGEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlT3JCdWlsZGVyIGdldEFPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGFCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gYUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGFfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBhXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVjdXJzaXZlTWVzc2FnZSBhID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZWN1cnNpdmVNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0QUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoYUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGFCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldEEoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGFfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgaV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNJKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgaSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBpLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEkoKSB7CiAgICAgICAgcmV0dXJuIGlfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgaSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEkoaW50IHZhbHVlKSB7CgogICAgICAgIGlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBpID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgaV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZWN1cnNpdmVNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVjdXJzaXZlTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZWN1cnNpdmVNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RSZWN1cnNpdmVNZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdFJlY3Vyc2l2ZU1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVjdXJzaXZlTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVjdXJzaXZlTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVjdXJzaXZlTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RNdXR1YWxSZWN1cnNpb25BT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CIGJiID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJiIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNCYigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkIgYmIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJiLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIGdldEJiKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQiBiYiA9IDE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CT3JCdWlsZGVyIGdldEJiT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBTdWJHcm91cCA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3ViZ3JvdXAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N1Ykdyb3VwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIFN1Ykdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3ViZ3JvdXAuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAgZ2V0U3ViR3JvdXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgU3ViR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBPckJ1aWxkZXIgZ2V0U3ViR3JvdXBPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFN1Ykdyb3VwUiA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFI+IAogICAgICAgIGdldFN1Ykdyb3VwUkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgU3ViR3JvdXBSID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiBnZXRTdWJHcm91cFIoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgU3ViR3JvdXBSID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0U3ViR3JvdXBSQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgU3ViR3JvdXBSID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFJPckJ1aWxkZXI+IAogICAgICAgIGdldFN1Ykdyb3VwUk9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgU3ViR3JvdXBSID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUk9yQnVpbGRlciBnZXRTdWJHcm91cFJPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUZXN0IHRoYXQgbXV0dWFsIHJlY3Vyc2lvbiB3b3Jrcy4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE11dHVhbFJlY3Vyc2lvbkEgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEpCiAgICAgIFRlc3RNdXR1YWxSZWN1cnNpb25BT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TXV0dWFsUmVjdXJzaW9uQS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TXV0dWFsUmVjdXJzaW9uQShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RNdXR1YWxSZWN1cnNpb25BKCkgewogICAgICBzdWJHcm91cFJfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNdXR1YWxSZWN1cnNpb25BKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBTdWJNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQiBiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc0IoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQiBiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGIuCiAgICAgICAqLwogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIGdldEIoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQiBiID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CT3JCdWlsZGVyIGdldEJPckJ1aWxkZXIoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBTdWJNZXNzYWdlIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlKQogICAgICAgIFN1Yk1lc3NhZ2VPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBTdWJNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgU3ViTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIFN1Yk1lc3NhZ2UoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgU3ViTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfU3ViTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQV9TdWJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiBiXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQiBiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0IoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkIgYiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiBnZXRCKCkgewogICAgICAgIHJldHVybiBiXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkIgYiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQk9yQnVpbGRlciBnZXRCT3JCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBiXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGJfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRCKCkpOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGdldEIoKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSkgb2JqOwoKICAgICAgICBpZiAoaGFzQigpICE9IG90aGVyLmhhc0IoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNCKCkpIHsKICAgICAgICAgIGlmICghZ2V0QigpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRCKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzQigpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEIoKS5oYXNoQ29kZSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSkKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQV9TdWJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQV9TdWJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgICAgZ2V0QkZpZWxkQnVpbGRlcigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBiXyA9IG51bGw7CiAgICAgICAgICBpZiAoYkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgYkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgYkJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfU3ViTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5iXyA9IGJCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgICA/IGJfCiAgICAgICAgICAgICAgICA6IGJCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSlvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc0IoKSkgewogICAgICAgICAgICBtZXJnZUIob3RoZXIuZ2V0QigpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICBnZXRCRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIgYl87CiAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkJPckJ1aWxkZXI+IGJCdWlsZGVyXzsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkIgYiA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYiBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzQigpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CIGIgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIGdldEIoKSB7CiAgICAgICAgICBpZiAoYkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGJfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CLmdldERlZmF1bHRJbnN0YW5jZSgpIDogYl87CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gYkJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CIGIgPSAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRCKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIgdmFsdWUpIHsKICAgICAgICAgIGlmIChiQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJfID0gdmFsdWU7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBiQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkIgYiA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEIoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChiQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBiXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYkJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgfQogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CIGIgPSAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiB2YWx1ZSkgewogICAgICAgICAgaWYgKGJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICAgIGJfICE9IG51bGwgJiYKICAgICAgICAgICAgICBiXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgICAgZ2V0QkJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGJfID0gdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGJCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJfICE9IG51bGwpIHsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkIgYiA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQigpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIGJfID0gbnVsbDsKICAgICAgICAgIGlmIChiQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICBiQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICBiQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CIGIgPSAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQi5CdWlsZGVyIGdldEJCdWlsZGVyKCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gZ2V0QkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CIGIgPSAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQk9yQnVpbGRlciBnZXRCT3JCdWlsZGVyKCkgewogICAgICAgICAgaWYgKGJCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBiQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGJfID09IG51bGwgPwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGJfOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkIgYiA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQi5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CT3JCdWlsZGVyPiAKICAgICAgICAgICAgZ2V0QkZpZWxkQnVpbGRlcigpIHsKICAgICAgICAgIGlmIChiQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBiQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQk9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgICAgZ2V0QigpLAogICAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgICAgYl8gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJCdWlsZGVyXzsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxTdWJNZXNzYWdlPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8U3ViTWVzc2FnZT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBTdWJNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8U3ViTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFN1Yk1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBTdWJHcm91cE9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTmVlZGVkIGJlY2F1c2Ugb2YgYnVnIGluIGphdmF0ZXN0CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSBzdWJfbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN1Yk1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNTdWJNZXNzYWdlKCk7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOZWVkZWQgYmVjYXVzZSBvZiBidWcgaW4gamF2YXRlc3QKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIHN1Yl9tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN1Yk1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UgZ2V0U3ViTWVzc2FnZSgpOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTmVlZGVkIGJlY2F1c2Ugb2YgYnVnIGluIGphdmF0ZXN0CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSBzdWJfbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlT3JCdWlsZGVyIGdldFN1Yk1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG5vdF9pbl90aGlzX3NjYyA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5vdEluVGhpc1NjYyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc05vdEluVGhpc1NjYygpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBub3RfaW5fdGhpc19zY2MgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbm90SW5UaGlzU2NjLgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0Tm90SW5UaGlzU2NjKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG5vdF9pbl90aGlzX3NjYyA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0Tm90SW5UaGlzU2NjT3JCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFN1Ykdyb3VwIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cCkKICAgICAgICBTdWJHcm91cE9yQnVpbGRlciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgLy8gVXNlIFN1Ykdyb3VwLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgU3ViR3JvdXAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBTdWJHcm91cCgpIHsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBTdWJHcm91cCgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfU3ViR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfU3ViR3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VCX01FU1NBR0VfRklFTERfTlVNQkVSID0gMzsKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2Ugc3ViTWVzc2FnZV87CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOZWVkZWQgYmVjYXVzZSBvZiBidWcgaW4gamF2YXRlc3QKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIHN1Yl9tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3ViTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1N1Yk1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOZWVkZWQgYmVjYXVzZSBvZiBidWcgaW4gamF2YXRlc3QKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIHN1Yl9tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN1Yk1lc3NhZ2UuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UgZ2V0U3ViTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gc3ViTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHN1Yk1lc3NhZ2VfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBOZWVkZWQgYmVjYXVzZSBvZiBidWcgaW4gamF2YXRlc3QKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIHN1Yl9tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2VPckJ1aWxkZXIgZ2V0U3ViTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gc3ViTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHN1Yk1lc3NhZ2VfOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOT1RfSU5fVEhJU19TQ0NfRklFTERfTlVNQkVSID0gNDsKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBub3RJblRoaXNTY2NfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBub3RfaW5fdGhpc19zY2MgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBub3RJblRoaXNTY2MgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOb3RJblRoaXNTY2MoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG5vdF9pbl90aGlzX3NjYyA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBub3RJblRoaXNTY2MuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXROb3RJblRoaXNTY2MoKSB7CiAgICAgICAgcmV0dXJuIG5vdEluVGhpc1NjY18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbm90SW5UaGlzU2NjXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBub3RfaW5fdGhpc19zY2MgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldE5vdEluVGhpc1NjY09yQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gbm90SW5UaGlzU2NjXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBub3RJblRoaXNTY2NfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgzLCBnZXRTdWJNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNCwgZ2V0Tm90SW5UaGlzU2NjKCkpOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIGdldFN1Yk1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgZ2V0Tm90SW5UaGlzU2NjKCkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXApIG9iajsKCiAgICAgICAgaWYgKGhhc1N1Yk1lc3NhZ2UoKSAhPSBvdGhlci5oYXNTdWJNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzU3ViTWVzc2FnZSgpKSB7CiAgICAgICAgICBpZiAoIWdldFN1Yk1lc3NhZ2UoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3ViTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzTm90SW5UaGlzU2NjKCkgIT0gb3RoZXIuaGFzTm90SW5UaGlzU2NjKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzTm90SW5UaGlzU2NjKCkpIHsKICAgICAgICAgIGlmICghZ2V0Tm90SW5UaGlzU2NjKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE5vdEluVGhpc1NjYygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaWYgKGhhc1N1Yk1lc3NhZ2UoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1VCX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3ViTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgICAgfQogICAgICAgIGlmIChoYXNOb3RJblRoaXNTY2MoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTk9UX0lOX1RISVNfU0NDX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE5vdEluVGhpc1NjYygpLmhhc2hDb2RlKCk7CiAgICAgICAgfQogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXB9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwKQogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cE9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQV9TdWJHcm91cF9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfU3ViR3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cC5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgICBnZXRTdWJNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICAgIGdldE5vdEluVGhpc1NjY0ZpZWxkQnVpbGRlcigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBzdWJNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgICBpZiAoc3ViTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgc3ViTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgc3ViTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIG5vdEluVGhpc1NjY18gPSBudWxsOwogICAgICAgICAgaWYgKG5vdEluVGhpc1NjY0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgbm90SW5UaGlzU2NjQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICBub3RJblRoaXNTY2NCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25BX1N1Ykdyb3VwX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwIGJ1aWxkKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQuc3ViTWVzc2FnZV8gPSBzdWJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgICAgPyBzdWJNZXNzYWdlXwogICAgICAgICAgICAgICAgOiBzdWJNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0Lm5vdEluVGhpc1NjY18gPSBub3RJblRoaXNTY2NCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgICA/IG5vdEluVGhpc1NjY18KICAgICAgICAgICAgICAgIDogbm90SW5UaGlzU2NjQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXApIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cClvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzU3ViTWVzc2FnZSgpKSB7CiAgICAgICAgICAgIG1lcmdlU3ViTWVzc2FnZShvdGhlci5nZXRTdWJNZXNzYWdlKCkpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKG90aGVyLmhhc05vdEluVGhpc1NjYygpKSB7CiAgICAgICAgICAgIG1lcmdlTm90SW5UaGlzU2NjKG90aGVyLmdldE5vdEluVGhpc1NjYygpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICBnZXRTdWJNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgZ2V0Tm90SW5UaGlzU2NjRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSBzdWJNZXNzYWdlXzsKICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZU9yQnVpbGRlcj4gc3ViTWVzc2FnZUJ1aWxkZXJfOwogICAgICAgIC8qKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogTmVlZGVkIGJlY2F1c2Ugb2YgYnVnIGluIGphdmF0ZXN0CiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICoKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSBzdWJfbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3ViTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3ViTWVzc2FnZSgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPHByZT4KICAgICAgICAgKiBOZWVkZWQgYmVjYXVzZSBvZiBidWcgaW4gamF2YXRlc3QKICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIHN1Yl9tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgc3ViTWVzc2FnZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIGdldFN1Yk1lc3NhZ2UoKSB7CiAgICAgICAgICBpZiAoc3ViTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIHN1Yk1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJNZXNzYWdlXzsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBzdWJNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIE5lZWRlZCBiZWNhdXNlIG9mIGJ1ZyBpbiBqYXZhdGVzdAogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2Ugc3ViX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdWJNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSB2YWx1ZSkgewogICAgICAgICAgaWYgKHN1Yk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3ViTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1Yk1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxwcmU+CiAgICAgICAgICogTmVlZGVkIGJlY2F1c2Ugb2YgYnVnIGluIGphdmF0ZXN0CiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICoKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZSBzdWJfbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN1Yk1lc3NhZ2UoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKHN1Yk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHN1Yk1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdWJNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIE5lZWRlZCBiZWNhdXNlIG9mIGJ1ZyBpbiBqYXZhdGVzdAogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2Ugc3ViX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVN1Yk1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgICBpZiAoc3ViTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICAgICAgc3ViTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICAgIHN1Yk1lc3NhZ2VfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICAgIGdldFN1Yk1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBzdWJNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdWJNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChzdWJNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPHByZT4KICAgICAgICAgKiBOZWVkZWQgYmVjYXVzZSBvZiBidWcgaW4gamF2YXRlc3QKICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIHN1Yl9tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdWJNZXNzYWdlKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgc3ViTWVzc2FnZV8gPSBudWxsOwogICAgICAgICAgaWYgKHN1Yk1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICAgIHN1Yk1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIHN1Yk1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIE5lZWRlZCBiZWNhdXNlIG9mIGJ1ZyBpbiBqYXZhdGVzdAogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2Ugc3ViX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlLkJ1aWxkZXIgZ2V0U3ViTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiBnZXRTdWJNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIE5lZWRlZCBiZWNhdXNlIG9mIGJ1ZyBpbiBqYXZhdGVzdAogICAgICAgICAqIDwvcHJlPgogICAgICAgICAqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2Ugc3ViX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlT3JCdWlsZGVyIGdldFN1Yk1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgICBpZiAoc3ViTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIHN1Yk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gc3ViTWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJNZXNzYWdlXzsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPHByZT4KICAgICAgICAgKiBOZWVkZWQgYmVjYXVzZSBvZiBidWcgaW4gamF2YXRlc3QKICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlIHN1Yl9tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgICBnZXRTdWJNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgICAgaWYgKHN1Yk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHN1Yk1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Yk1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgICBnZXRTdWJNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgICBzdWJNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gc3ViTWVzc2FnZUJ1aWxkZXJfOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBub3RJblRoaXNTY2NfOwogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBub3RJblRoaXNTY2NCdWlsZGVyXzsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG5vdF9pbl90aGlzX3NjYyA9IDQ7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbm90SW5UaGlzU2NjIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOb3RJblRoaXNTY2MoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbm90X2luX3RoaXNfc2NjID0gNDs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgbm90SW5UaGlzU2NjLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXROb3RJblRoaXNTY2MoKSB7CiAgICAgICAgICBpZiAobm90SW5UaGlzU2NjQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gbm90SW5UaGlzU2NjXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBub3RJblRoaXNTY2NfOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIG5vdEluVGhpc1NjY0J1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBub3RfaW5fdGhpc19zY2MgPSA0OzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXROb3RJblRoaXNTY2MocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICAgIGlmIChub3RJblRoaXNTY2NCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbm90SW5UaGlzU2NjXyA9IHZhbHVlOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbm90SW5UaGlzU2NjQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG5vdF9pbl90aGlzX3NjYyA9IDQ7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE5vdEluVGhpc1NjYygKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChub3RJblRoaXNTY2NCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIG5vdEluVGhpc1NjY18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG5vdEluVGhpc1NjY0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgfQogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBub3RfaW5fdGhpc19zY2MgPSA0OzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU5vdEluVGhpc1NjYyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgICAgaWYgKG5vdEluVGhpc1NjY0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApICYmCiAgICAgICAgICAgICAgbm90SW5UaGlzU2NjXyAhPSBudWxsICYmCiAgICAgICAgICAgICAgbm90SW5UaGlzU2NjXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICAgIGdldE5vdEluVGhpc1NjY0J1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIG5vdEluVGhpc1NjY18gPSB2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbm90SW5UaGlzU2NjQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChub3RJblRoaXNTY2NfICE9IG51bGwpIHsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG5vdF9pbl90aGlzX3NjYyA9IDQ7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTm90SW5UaGlzU2NjKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgbm90SW5UaGlzU2NjXyA9IG51bGw7CiAgICAgICAgICBpZiAobm90SW5UaGlzU2NjQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICBub3RJblRoaXNTY2NCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIG5vdEluVGhpc1NjY0J1aWxkZXJfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbm90X2luX3RoaXNfc2NjID0gNDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0Tm90SW5UaGlzU2NjQnVpbGRlcigpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIGdldE5vdEluVGhpc1NjY0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBub3RfaW5fdGhpc19zY2MgPSA0OzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0Tm90SW5UaGlzU2NjT3JCdWlsZGVyKCkgewogICAgICAgICAgaWYgKG5vdEluVGhpc1NjY0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIG5vdEluVGhpc1NjY0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBub3RJblRoaXNTY2NfID09IG51bGwgPwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBub3RJblRoaXNTY2NfOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG5vdF9pbl90aGlzX3NjYyA9IDQ7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICAgZ2V0Tm90SW5UaGlzU2NjRmllbGRCdWlsZGVyKCkgewogICAgICAgICAgaWYgKG5vdEluVGhpc1NjY0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgbm90SW5UaGlzU2NjQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgICAgZ2V0Tm90SW5UaGlzU2NjKCksCiAgICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgICBub3RJblRoaXNTY2NfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBub3RJblRoaXNTY2NCdWlsZGVyXzsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cCkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFN1Ykdyb3VwPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8U3ViR3JvdXA+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU3ViR3JvdXAgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxTdWJHcm91cD4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFN1Ykdyb3VwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIFN1Ykdyb3VwUk9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUikKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBheWxvYWQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNQYXlsb2FkKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcGF5bG9hZC4KICAgICAgICovCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFBheWxvYWQoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UGF5bG9hZE9yQnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU3ViR3JvdXBSIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIpCiAgICAgICAgU3ViR3JvdXBST3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgU3ViR3JvdXBSLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgU3ViR3JvdXBSKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgU3ViR3JvdXBSKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IFN1Ykdyb3VwUigpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfU3ViR3JvdXBSX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25BX1N1Ykdyb3VwUl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBWUxPQURfRklFTERfTlVNQkVSID0gNjsKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBwYXlsb2FkXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBheWxvYWQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNQYXlsb2FkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHBheWxvYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRQYXlsb2FkKCkgewogICAgICAgIHJldHVybiBwYXlsb2FkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBwYXlsb2FkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRQYXlsb2FkT3JCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBwYXlsb2FkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBwYXlsb2FkXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNiwgZ2V0UGF5bG9hZCgpKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2LCBnZXRQYXlsb2FkKCkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUikpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIpIG9iajsKCiAgICAgICAgaWYgKGhhc1BheWxvYWQoKSAhPSBvdGhlci5oYXNQYXlsb2FkKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzUGF5bG9hZCgpKSB7CiAgICAgICAgICBpZiAoIWdldFBheWxvYWQoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGF5bG9hZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaWYgKGhhc1BheWxvYWQoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFZTE9BRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYXlsb2FkKCkuaGFzaENvZGUoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIpCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUk9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQV9TdWJHcm91cFJfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25BX1N1Ykdyb3VwUl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICAgIGdldFBheWxvYWRGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgcGF5bG9hZF8gPSBudWxsOwogICAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICAgIHBheWxvYWRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIHBheWxvYWRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25BX1N1Ykdyb3VwUl9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiBidWlsZCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQucGF5bG9hZF8gPSBwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgICAgPyBwYXlsb2FkXwogICAgICAgICAgICAgICAgOiBwYXlsb2FkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc1BheWxvYWQoKSkgewogICAgICAgICAgICBtZXJnZVBheWxvYWQob3RoZXIuZ2V0UGF5bG9hZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICBnZXRQYXlsb2FkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHBheWxvYWRfOwogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBwYXlsb2FkQnVpbGRlcl87CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gNjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYXlsb2FkIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNQYXlsb2FkKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSA2OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBwYXlsb2FkLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRQYXlsb2FkKCkgewogICAgICAgICAgaWYgKHBheWxvYWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBwYXlsb2FkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBwYXlsb2FkXzsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBwYXlsb2FkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSA2OzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYXlsb2FkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwYXlsb2FkXyA9IHZhbHVlOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gNjs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGF5bG9hZCgKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChwYXlsb2FkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBwYXlsb2FkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgfQogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gNjs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VQYXlsb2FkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICAgICAgcGF5bG9hZF8gIT0gbnVsbCAmJgogICAgICAgICAgICAgIHBheWxvYWRfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgICAgZ2V0UGF5bG9hZEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHBheWxvYWRfID0gdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHBheWxvYWRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHBheWxvYWRfICE9IG51bGwpIHsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSA2OzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBheWxvYWQoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBwYXlsb2FkXyA9IG51bGw7CiAgICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcGF5bG9hZCA9IDY7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldFBheWxvYWRCdWlsZGVyKCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gZ2V0UGF5bG9hZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBwYXlsb2FkID0gNjs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFBheWxvYWRPckJ1aWxkZXIoKSB7CiAgICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIHBheWxvYWRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gcGF5bG9hZF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBheWxvYWRfOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHBheWxvYWQgPSA2OzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICAgIGdldFBheWxvYWRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgICBpZiAocGF5bG9hZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcGF5bG9hZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICAgIGdldFBheWxvYWQoKSwKICAgICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICAgIHBheWxvYWRfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwYXlsb2FkQnVpbGRlcl87CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFN1Ykdyb3VwUj4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFN1Ykdyb3VwUj4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBTdWJHcm91cFIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxTdWJHcm91cFI+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxTdWJHcm91cFI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkJfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiBiYl87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQiBiYiA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0JiKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQiBiYiA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYmIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIGdldEJiKCkgewogICAgICByZXR1cm4gYmJfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CLmdldERlZmF1bHRJbnN0YW5jZSgpIDogYmJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkIgYmIgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkJPckJ1aWxkZXIgZ2V0QmJPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBiYl8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBiYl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VCR1JPVVBfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cCBzdWJHcm91cF87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIFN1Ykdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdWJncm91cCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1N1Ykdyb3VwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIFN1Ykdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3ViZ3JvdXAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwIGdldFN1Ykdyb3VwKCkgewogICAgICByZXR1cm4gc3ViR3JvdXBfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViR3JvdXBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBTdWJHcm91cCA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBPckJ1aWxkZXIgZ2V0U3ViR3JvdXBPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBzdWJHcm91cF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJHcm91cF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VCR1JPVVBSX0ZJRUxEX05VTUJFUiA9IDU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFI+IHN1Ykdyb3VwUl87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFN1Ykdyb3VwUiA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSPiBnZXRTdWJHcm91cFJMaXN0KCkgewogICAgICByZXR1cm4gc3ViR3JvdXBSXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgU3ViR3JvdXBSID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBST3JCdWlsZGVyPiAKICAgICAgICBnZXRTdWJHcm91cFJPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gc3ViR3JvdXBSXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgU3ViR3JvdXBSID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFN1Ykdyb3VwUkNvdW50KCkgewogICAgICByZXR1cm4gc3ViR3JvdXBSXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFN1Ykdyb3VwUiA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSIGdldFN1Ykdyb3VwUihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHN1Ykdyb3VwUl8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgU3ViR3JvdXBSID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFJPckJ1aWxkZXIgZ2V0U3ViR3JvdXBST3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gc3ViR3JvdXBSXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRCYigpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVHcm91cCgyLCBnZXRTdWJHcm91cCgpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN1Ykdyb3VwUl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVHcm91cCg1LCBzdWJHcm91cFJfLmdldChpKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRCYigpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlR3JvdXBTaXplKDIsIGdldFN1Ykdyb3VwKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3ViR3JvdXBSXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVHcm91cFNpemUoNSwgc3ViR3JvdXBSXy5nZXQoaSkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQSkgb2JqOwoKICAgICAgaWYgKGhhc0JiKCkgIT0gb3RoZXIuaGFzQmIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQmIoKSkgewogICAgICAgIGlmICghZ2V0QmIoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEJiKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1N1Ykdyb3VwKCkgIT0gb3RoZXIuaGFzU3ViR3JvdXAoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzU3ViR3JvdXAoKSkgewogICAgICAgIGlmICghZ2V0U3ViR3JvdXAoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFN1Ykdyb3VwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRTdWJHcm91cFJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3ViR3JvdXBSTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNCYigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEJiKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3ViR3JvdXAoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNVQkdST1VQX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdWJHcm91cCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFN1Ykdyb3VwUkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1VCR1JPVVBSX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdWJHcm91cFJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0IHRoYXQgbXV0dWFsIHJlY3Vyc2lvbiB3b3Jrcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRCYkZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0U3ViR3JvdXBGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldFN1Ykdyb3VwUkZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgYmJfID0gbnVsbDsKICAgICAgICBpZiAoYmJCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBiYkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGJiQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBzdWJHcm91cF8gPSBudWxsOwogICAgICAgIGlmIChzdWJHcm91cEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHN1Ykdyb3VwQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgc3ViR3JvdXBCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChzdWJHcm91cFJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBzdWJHcm91cFJfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdWJHcm91cFJfID0gbnVsbDsKICAgICAgICAgIHN1Ykdyb3VwUkJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEgcmVzdWx0KSB7CiAgICAgICAgaWYgKHN1Ykdyb3VwUkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgICBzdWJHcm91cFJfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3Qoc3ViR3JvdXBSXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5zdWJHcm91cFJfID0gc3ViR3JvdXBSXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnN1Ykdyb3VwUl8gPSBzdWJHcm91cFJCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5iYl8gPSBiYkJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGJiXwogICAgICAgICAgICAgIDogYmJCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN1Ykdyb3VwXyA9IHN1Ykdyb3VwQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gc3ViR3JvdXBfCiAgICAgICAgICAgICAgOiBzdWJHcm91cEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0JiKCkpIHsKICAgICAgICAgIG1lcmdlQmIob3RoZXIuZ2V0QmIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdWJHcm91cCgpKSB7CiAgICAgICAgICBtZXJnZVN1Ykdyb3VwKG90aGVyLmdldFN1Ykdyb3VwKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoc3ViR3JvdXBSQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5zdWJHcm91cFJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAoc3ViR3JvdXBSXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBzdWJHcm91cFJfID0gb3RoZXIuc3ViR3JvdXBSXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlU3ViR3JvdXBSSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgc3ViR3JvdXBSXy5hZGRBbGwob3RoZXIuc3ViR3JvdXBSXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIuc3ViR3JvdXBSXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHN1Ykdyb3VwUkJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHN1Ykdyb3VwUkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICBzdWJHcm91cFJCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgc3ViR3JvdXBSXyA9IG90aGVyLnN1Ykdyb3VwUl87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgICAgICAgIHN1Ykdyb3VwUkJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFN1Ykdyb3VwUkZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBzdWJHcm91cFJCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5zdWJHcm91cFJfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRCYkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE5OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkR3JvdXAoMiwKICAgICAgICAgICAgICAgICAgICBnZXRTdWJHcm91cEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTkKICAgICAgICAgICAgICBjYXNlIDQzOiB7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkR3JvdXAoNSwKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAoc3ViR3JvdXBSQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVTdWJHcm91cFJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgc3ViR3JvdXBSXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBzdWJHcm91cFJCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQzCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiBiYl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQk9yQnVpbGRlcj4gYmJCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQiBiYiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJiIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0JiKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CIGJiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJiLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIgZ2V0QmIoKSB7CiAgICAgICAgaWYgKGJiQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGJiXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGJiXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGJiQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CIGJiID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRCYihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIHZhbHVlKSB7CiAgICAgICAgaWYgKGJiQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBiYl8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYmJCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkIgYmIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJiKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQi5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChiYkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGJiXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBiYkJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQiBiYiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VCYihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIHZhbHVlKSB7CiAgICAgICAgaWYgKGJiQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICAgIGJiXyAhPSBudWxsICYmCiAgICAgICAgICAgIGJiXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEJiQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBiYl8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgYmJCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoYmJfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CIGJiID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJiKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBiYl8gPSBudWxsOwogICAgICAgIGlmIChiYkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGJiQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgYmJCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkIgYmIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CLkJ1aWxkZXIgZ2V0QmJCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0QmJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQiBiYiA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkJPckJ1aWxkZXIgZ2V0QmJPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGJiQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGJiQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gYmJfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBiYl87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkIgYmIgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQk9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRCYkZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoYmJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBiYkJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQi5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0QmIoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGJiXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiYkJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAgc3ViR3JvdXBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBPckJ1aWxkZXI+IHN1Ykdyb3VwQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBTdWJHcm91cCA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdWJncm91cCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdWJHcm91cCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIFN1Ykdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzdWJncm91cC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwIGdldFN1Ykdyb3VwKCkgewogICAgICAgIGlmIChzdWJHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBzdWJHcm91cF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJHcm91cF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBzdWJHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIFN1Ykdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3ViR3JvdXAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cCB2YWx1ZSkgewogICAgICAgIGlmIChzdWJHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgc3ViR3JvdXBfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1Ykdyb3VwQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgU3ViR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdWJHcm91cCgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoc3ViR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBzdWJHcm91cF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3ViR3JvdXBCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBTdWJHcm91cCA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlU3ViR3JvdXAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cCB2YWx1ZSkgewogICAgICAgIGlmIChzdWJHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSAmJgogICAgICAgICAgICBzdWJHcm91cF8gIT0gbnVsbCAmJgogICAgICAgICAgICBzdWJHcm91cF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRTdWJHcm91cEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3ViR3JvdXBfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1Ykdyb3VwQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKHN1Ykdyb3VwXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIFN1Ykdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdWJHcm91cCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgc3ViR3JvdXBfID0gbnVsbDsKICAgICAgICBpZiAoc3ViR3JvdXBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBzdWJHcm91cEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHN1Ykdyb3VwQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgU3ViR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cC5CdWlsZGVyIGdldFN1Ykdyb3VwQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldFN1Ykdyb3VwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBTdWJHcm91cCA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwT3JCdWlsZGVyIGdldFN1Ykdyb3VwT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChzdWJHcm91cEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBzdWJHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHN1Ykdyb3VwXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViR3JvdXBfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgU3ViR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0U3ViR3JvdXBGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHN1Ykdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgc3ViR3JvdXBCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cE9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldFN1Ykdyb3VwKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBzdWJHcm91cF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3ViR3JvdXBCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUj4gc3ViR3JvdXBSXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlU3ViR3JvdXBSSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHN1Ykdyb3VwUl8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUj4oc3ViR3JvdXBSXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFJPckJ1aWxkZXI+IHN1Ykdyb3VwUkJ1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFN1Ykdyb3VwUiA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUj4gZ2V0U3ViR3JvdXBSTGlzdCgpIHsKICAgICAgICBpZiAoc3ViR3JvdXBSQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHN1Ykdyb3VwUl8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gc3ViR3JvdXBSQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFN1Ykdyb3VwUiA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0U3ViR3JvdXBSQ291bnQoKSB7CiAgICAgICAgaWYgKHN1Ykdyb3VwUkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBzdWJHcm91cFJfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHN1Ykdyb3VwUkJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBTdWJHcm91cFIgPSA1IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIgZ2V0U3ViR3JvdXBSKGludCBpbmRleCkgewogICAgICAgIGlmIChzdWJHcm91cFJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gc3ViR3JvdXBSXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gc3ViR3JvdXBSQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBTdWJHcm91cFIgPSA1IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdWJHcm91cFIoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSIHZhbHVlKSB7CiAgICAgICAgaWYgKHN1Ykdyb3VwUkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlU3ViR3JvdXBSSXNNdXRhYmxlKCk7CiAgICAgICAgICBzdWJHcm91cFJfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1Ykdyb3VwUkJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFN1Ykdyb3VwUiA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN1Ykdyb3VwUigKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoc3ViR3JvdXBSQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlU3ViR3JvdXBSSXNNdXRhYmxlKCk7CiAgICAgICAgICBzdWJHcm91cFJfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1Ykdyb3VwUkJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFN1Ykdyb3VwUiA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFN1Ykdyb3VwUihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiB2YWx1ZSkgewogICAgICAgIGlmIChzdWJHcm91cFJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVN1Ykdyb3VwUklzTXV0YWJsZSgpOwogICAgICAgICAgc3ViR3JvdXBSXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1Ykdyb3VwUkJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgU3ViR3JvdXBSID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkU3ViR3JvdXBSKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUiB2YWx1ZSkgewogICAgICAgIGlmIChzdWJHcm91cFJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVN1Ykdyb3VwUklzTXV0YWJsZSgpOwogICAgICAgICAgc3ViR3JvdXBSXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdWJHcm91cFJCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBTdWJHcm91cFIgPSA1IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRTdWJHcm91cFIoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUi5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChzdWJHcm91cFJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVTdWJHcm91cFJJc011dGFibGUoKTsKICAgICAgICAgIHN1Ykdyb3VwUl8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdWJHcm91cFJCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFN1Ykdyb3VwUiA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFN1Ykdyb3VwUigKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoc3ViR3JvdXBSQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlU3ViR3JvdXBSSXNNdXRhYmxlKCk7CiAgICAgICAgICBzdWJHcm91cFJfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1Ykdyb3VwUkJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFN1Ykdyb3VwUiA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFN1Ykdyb3VwUigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFI+IHZhbHVlcykgewogICAgICAgIGlmIChzdWJHcm91cFJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVTdWJHcm91cFJJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHN1Ykdyb3VwUl8pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1Ykdyb3VwUkJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBTdWJHcm91cFIgPSA1IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN1Ykdyb3VwUigpIHsKICAgICAgICBpZiAoc3ViR3JvdXBSQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgc3ViR3JvdXBSXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdWJHcm91cFJCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgU3ViR3JvdXBSID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlU3ViR3JvdXBSKGludCBpbmRleCkgewogICAgICAgIGlmIChzdWJHcm91cFJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVTdWJHcm91cFJJc011dGFibGUoKTsKICAgICAgICAgIHN1Ykdyb3VwUl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdWJHcm91cFJCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgU3ViR3JvdXBSID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSLkJ1aWxkZXIgZ2V0U3ViR3JvdXBSQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRTdWJHcm91cFJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgU3ViR3JvdXBSID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBST3JCdWlsZGVyIGdldFN1Ykdyb3VwUk9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChzdWJHcm91cFJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gc3ViR3JvdXBSXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBzdWJHcm91cFJCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFN1Ykdyb3VwUiA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFJPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFN1Ykdyb3VwUk9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHN1Ykdyb3VwUkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBzdWJHcm91cFJCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3Qoc3ViR3JvdXBSXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBTdWJHcm91cFIgPSA1IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIuQnVpbGRlciBhZGRTdWJHcm91cFJCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRTdWJHcm91cFJGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUi5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFN1Ykdyb3VwUiA9IDUgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUi5CdWlsZGVyIGFkZFN1Ykdyb3VwUkJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0U3ViR3JvdXBSRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgU3ViR3JvdXBSID0gNSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFN1Ykdyb3VwUkJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRTdWJHcm91cFJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBST3JCdWlsZGVyPiAKICAgICAgICAgIGdldFN1Ykdyb3VwUkZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoc3ViR3JvdXBSQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgc3ViR3JvdXBSQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuU3ViR3JvdXBSLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUi5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwUk9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHN1Ykdyb3VwUl8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgc3ViR3JvdXBSXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdWJHcm91cFJCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TXV0dWFsUmVjdXJzaW9uQT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0TXV0dWFsUmVjdXJzaW9uQT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RNdXR1YWxSZWN1cnNpb25BIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE11dHVhbFJlY3Vyc2lvbkE+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE11dHVhbFJlY3Vyc2lvbkE+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0TXV0dWFsUmVjdXJzaW9uQk9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQSBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0EoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEgZ2V0QSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEgYSA9IDE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BT3JCdWlsZGVyIGdldEFPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE11dHVhbFJlY3Vyc2lvbkIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkIpCiAgICAgIFRlc3RNdXR1YWxSZWN1cnNpb25CT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TXV0dWFsUmVjdXJzaW9uQi5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TXV0dWFsUmVjdXJzaW9uQihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RNdXR1YWxSZWN1cnNpb25CKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNdXR1YWxSZWN1cnNpb25CKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQSBhXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIGdldEEoKSB7CiAgICAgIHJldHVybiBhXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGFfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEgYSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQU9yQnVpbGRlciBnZXRBT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gYV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBhXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMl87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEsIGdldEEoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMiwgb3B0aW9uYWxJbnQzMl8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0QSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIsIG9wdGlvbmFsSW50MzJfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIpIG9iajsKCiAgICAgIGlmIChoYXNBKCkgIT0gb3RoZXIuaGFzQSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBpZiAoIWdldEEoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMigpICE9IG90aGVyLmhhc09wdGlvbmFsSW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMigpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50MzIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBBX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzIoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkIpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQi5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRBRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBhXyA9IG51bGw7CiAgICAgICAgaWYgKGFCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBhQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgYUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxJbnQzMl8gPSAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5hXyA9IGFCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBhXwogICAgICAgICAgICAgIDogYUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMl8gPSBvcHRpb25hbEludDMyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25CLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzQSgpKSB7CiAgICAgICAgICBtZXJnZUEob3RoZXIuZ2V0QSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50MzIoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQzMihvdGhlci5nZXRPcHRpb25hbEludDMyKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRBRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIGFfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkFPckJ1aWxkZXI+IGFCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQSBhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIGdldEEoKSB7CiAgICAgICAgaWYgKGFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gYV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBhXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGFCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEgYSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BIHZhbHVlKSB7CiAgICAgICAgaWYgKGFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGFfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGFCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEgYSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoYUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGFfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGFCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEgYSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VBKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEgdmFsdWUpIHsKICAgICAgICBpZiAoYUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBhXyAhPSBudWxsICYmCiAgICAgICAgICAgIGFfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0QUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgYUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChhXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQSBhID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGFfID0gbnVsbDsKICAgICAgICBpZiAoYUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGFCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBhQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BIGEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BLkJ1aWxkZXIgZ2V0QUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRBRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlY3Vyc2lvbkEgYSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkFPckJ1aWxkZXIgZ2V0QU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoYUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBhQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gYV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGFfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BIGEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkEuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRBRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChhQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgYUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNdXR1YWxSZWN1cnNpb25BT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0QSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgYV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYUJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb3B0aW9uYWxJbnQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25CKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVjdXJzaW9uQikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE11dHVhbFJlY3Vyc2lvbkIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNdXR1YWxSZWN1cnNpb25CPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RNdXR1YWxSZWN1cnNpb25CPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE11dHVhbFJlY3Vyc2lvbkIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TXV0dWFsUmVjdXJzaW9uQj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TXV0dWFsUmVjdXJzaW9uQj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TXV0dWFsUmVjdXJzaW9uQiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RJc0luaXRpYWxpemVkT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2Ugc3ViX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3ViTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3ViTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZSBzdWJfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3ViTWVzc2FnZS4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIGdldFN1Yk1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2Ugc3ViX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlT3JCdWlsZGVyIGdldFN1Yk1lc3NhZ2VPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdElzSW5pdGlhbGl6ZWR9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0SXNJbml0aWFsaXplZCBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0SXNJbml0aWFsaXplZCkKICAgICAgVGVzdElzSW5pdGlhbGl6ZWRPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RJc0luaXRpYWxpemVkLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RJc0luaXRpYWxpemVkKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdElzSW5pdGlhbGl6ZWQoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdElzSW5pdGlhbGl6ZWQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJc0luaXRpYWxpemVkX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIFN1Yk1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgU3ViR3JvdXAgPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3ViZ3JvdXAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNTdWJHcm91cCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgU3ViR3JvdXAgPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN1Ymdyb3VwLgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwIGdldFN1Ykdyb3VwKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBTdWJHcm91cCA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cE9yQnVpbGRlciBnZXRTdWJHcm91cE9yQnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFN1Yk1lc3NhZ2UgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UpCiAgICAgICAgU3ViTWVzc2FnZU9yQnVpbGRlciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgLy8gVXNlIFN1Yk1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBTdWJNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgU3ViTWVzc2FnZSgpIHsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBTdWJNZXNzYWdlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9TdWJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJc0luaXRpYWxpemVkX1N1Yk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBpbnRlcmZhY2UgU3ViR3JvdXBPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXApCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBpID0gMjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBib29sZWFuIGhhc0koKTsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBpID0gMjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgaS4KICAgICAgICAgKi8KICAgICAgICBpbnQgZ2V0SSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBTdWJHcm91cCBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXApCiAgICAgICAgICBTdWJHcm91cE9yQnVpbGRlciB7CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAgIC8vIFVzZSBTdWJHcm91cC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICAgIHByaXZhdGUgU3ViR3JvdXAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBTdWJHcm91cCgpIHsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgICAgcmV0dXJuIG5ldyBTdWJHcm91cCgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9TdWJNZXNzYWdlX1N1Ykdyb3VwX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9TdWJNZXNzYWdlX1N1Ykdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cC5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSV9GSUVMRF9OVU1CRVIgPSAyOwogICAgICAgIHByaXZhdGUgaW50IGlfID0gMDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBpID0gMjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzSSgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgaSA9IDI7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGkuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0SSgpIHsKICAgICAgICAgIHJldHVybiBpXzsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgIGlmICghaGFzSSgpKSB7CiAgICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIGlfKTsKICAgICAgICAgIH0KICAgICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICAgIHNpemUgPSAwOwogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIsIGlfKTsKICAgICAgICAgIH0KICAgICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCkpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgICAgfQogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCkgb2JqOwoKICAgICAgICAgIGlmIChoYXNJKCkgIT0gb3RoZXIuaGFzSSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBpZiAoaGFzSSgpKSB7CiAgICAgICAgICAgIGlmIChnZXRJKCkKICAgICAgICAgICAgICAgICE9IG90aGVyLmdldEkoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgICAgfQogICAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgICAgaWYgKGhhc0koKSkgewogICAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJX0ZJRUxEX05VTUJFUjsKICAgICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0SSgpOwogICAgICAgICAgfQogICAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICAgIHJldHVybiBoYXNoOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwIHByb3RvdHlwZSkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXB9CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCkKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwT3JCdWlsZGVyIHsKICAgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJc0luaXRpYWxpemVkX1N1Yk1lc3NhZ2VfU3ViR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9TdWJNZXNzYWdlX1N1Ykdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgICB9CgogICAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cC5uZXdCdWlsZGVyKCkKICAgICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgICB9CgogICAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgICBpXyA9IDA7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJc0luaXRpYWxpemVkX1N1Yk1lc3NhZ2VfU3ViR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCBidWlsZCgpIHsKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwKHRoaXMpOwogICAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICB9CgogICAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwIHJlc3VsdCkgewogICAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICAgIHJlc3VsdC5pXyA9IGlfOwogICAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwKSB7CiAgICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwKW90aGVyKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCBvdGhlcikgewogICAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgICAgaWYgKG90aGVyLmhhc0koKSkgewogICAgICAgICAgICAgIHNldEkob3RoZXIuZ2V0SSgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgICAgaWYgKCFoYXNJKCkpIHsKICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICAgICAgaV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICAgIHByaXZhdGUgaW50IGlfIDsKICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgaSA9IDI7PC9jb2RlPgogICAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpIGZpZWxkIGlzIHNldC4KICAgICAgICAgICAqLwogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzSSgpIHsKICAgICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgICAgfQogICAgICAgICAgLyoqCiAgICAgICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBpID0gMjs8L2NvZGU+CiAgICAgICAgICAgKiBAcmV0dXJuIFRoZSBpLgogICAgICAgICAgICovCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgaW50IGdldEkoKSB7CiAgICAgICAgICAgIHJldHVybiBpXzsKICAgICAgICAgIH0KICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+cmVxdWlyZWQgaW50MzIgaSA9IDI7PC9jb2RlPgogICAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBpIHRvIHNldC4KICAgICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SShpbnQgdmFsdWUpIHsKCiAgICAgICAgICAgIGlfID0gdmFsdWU7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgICAgLyoqCiAgICAgICAgICAgKiA8Y29kZT5yZXF1aXJlZCBpbnQzMiBpID0gMjs8L2NvZGU+CiAgICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySSgpIHsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgICBpXyA9IDA7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgICAgfQoKCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwKQogICAgICAgIH0KCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXApCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgICAgc3RhdGljIHsKICAgICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFN1Ykdyb3VwPgogICAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxTdWJHcm91cD4oKSB7CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgU3ViR3JvdXAgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICB9CiAgICAgICAgfTsKCiAgICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxTdWJHcm91cD4gcGFyc2VyKCkgewogICAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8U3ViR3JvdXA+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICAgIH0KCiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNVQkdST1VQX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwIHN1Ykdyb3VwXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIFN1Ykdyb3VwID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN1Ymdyb3VwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3ViR3JvdXAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBTdWJHcm91cCA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgc3ViZ3JvdXAuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAgZ2V0U3ViR3JvdXAoKSB7CiAgICAgICAgcmV0dXJuIHN1Ykdyb3VwXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViR3JvdXBfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBTdWJHcm91cCA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cE9yQnVpbGRlciBnZXRTdWJHcm91cE9yQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gc3ViR3JvdXBfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJHcm91cF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIGlmIChoYXNTdWJHcm91cCgpKSB7CiAgICAgICAgICBpZiAoIWdldFN1Ykdyb3VwKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZUdyb3VwKDEsIGdldFN1Ykdyb3VwKCkpOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUdyb3VwU2l6ZSgxLCBnZXRTdWJHcm91cCgpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlKSBvYmo7CgogICAgICAgIGlmIChoYXNTdWJHcm91cCgpICE9IG90aGVyLmhhc1N1Ykdyb3VwKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzU3ViR3JvdXAoKSkgewogICAgICAgICAgaWYgKCFnZXRTdWJHcm91cCgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdWJHcm91cCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaWYgKGhhc1N1Ykdyb3VwKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNVQkdST1VQX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN1Ykdyb3VwKCkuaGFzaENvZGUoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2V9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UpCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2VPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdElzSW5pdGlhbGl6ZWRfU3ViTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdElzSW5pdGlhbGl6ZWRfU3ViTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICAgIGdldFN1Ykdyb3VwRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIHN1Ykdyb3VwXyA9IG51bGw7CiAgICAgICAgICBpZiAoc3ViR3JvdXBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICAgIHN1Ykdyb3VwQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICBzdWJHcm91cEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdElzSW5pdGlhbGl6ZWRfU3ViTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5zdWJHcm91cF8gPSBzdWJHcm91cEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICAgID8gc3ViR3JvdXBfCiAgICAgICAgICAgICAgICA6IHN1Ykdyb3VwQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZSkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2Upb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5oYXNTdWJHcm91cCgpKSB7CiAgICAgICAgICAgIG1lcmdlU3ViR3JvdXAob3RoZXIuZ2V0U3ViR3JvdXAoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgaWYgKGhhc1N1Ykdyb3VwKCkpIHsKICAgICAgICAgICAgaWYgKCFnZXRTdWJHcm91cCgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDExOiB7CiAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRHcm91cCgxLAogICAgICAgICAgICAgICAgICAgICAgZ2V0U3ViR3JvdXBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgMTEKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwIHN1Ykdyb3VwXzsKICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cE9yQnVpbGRlcj4gc3ViR3JvdXBCdWlsZGVyXzsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBTdWJHcm91cCA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN1Ymdyb3VwIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdWJHcm91cCgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgU3ViR3JvdXAgPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgc3ViZ3JvdXAuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCBnZXRTdWJHcm91cCgpIHsKICAgICAgICAgIGlmIChzdWJHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIHN1Ykdyb3VwXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViR3JvdXBfOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHN1Ykdyb3VwQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBTdWJHcm91cCA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdWJHcm91cChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAgdmFsdWUpIHsKICAgICAgICAgIGlmIChzdWJHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdWJHcm91cF8gPSB2YWx1ZTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1Ykdyb3VwQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBTdWJHcm91cCA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdWJHcm91cCgKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgICBpZiAoc3ViR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHN1Ykdyb3VwXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3ViR3JvdXBCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIFN1Ykdyb3VwID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlU3ViR3JvdXAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwIHZhbHVlKSB7CiAgICAgICAgICBpZiAoc3ViR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICAgIHN1Ykdyb3VwXyAhPSBudWxsICYmCiAgICAgICAgICAgICAgc3ViR3JvdXBfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICAgIGdldFN1Ykdyb3VwQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgc3ViR3JvdXBfID0gdmFsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1Ykdyb3VwQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChzdWJHcm91cF8gIT0gbnVsbCkgewogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIFN1Ykdyb3VwID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3ViR3JvdXAoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBzdWJHcm91cF8gPSBudWxsOwogICAgICAgICAgaWYgKHN1Ykdyb3VwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICBzdWJHcm91cEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgc3ViR3JvdXBCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBTdWJHcm91cCA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwLkJ1aWxkZXIgZ2V0U3ViR3JvdXBCdWlsZGVyKCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gZ2V0U3ViR3JvdXBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIFN1Ykdyb3VwID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXBPckJ1aWxkZXIgZ2V0U3ViR3JvdXBPckJ1aWxkZXIoKSB7CiAgICAgICAgICBpZiAoc3ViR3JvdXBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBzdWJHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBzdWJHcm91cF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJHcm91cF87CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIFN1Ykdyb3VwID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuU3ViR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwT3JCdWlsZGVyPiAKICAgICAgICAgICAgZ2V0U3ViR3JvdXBGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgICBpZiAoc3ViR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHN1Ykdyb3VwQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLlN1Ykdyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5TdWJHcm91cE9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgICAgZ2V0U3ViR3JvdXAoKSwKICAgICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICAgIHN1Ykdyb3VwXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gc3ViR3JvdXBCdWlsZGVyXzsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxTdWJNZXNzYWdlPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8U3ViTWVzc2FnZT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBTdWJNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8U3ViTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFN1Yk1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNVQl9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZSBzdWJNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2Ugc3ViX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3ViTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1N1Yk1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2Ugc3ViX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN1Yk1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UgZ2V0U3ViTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIHN1Yk1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2Ugc3ViX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZU9yQnVpbGRlciBnZXRTdWJNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gc3ViTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHN1Yk1lc3NhZ2VfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmIChoYXNTdWJNZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldFN1Yk1lc3NhZ2UoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRTdWJNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0U3ViTWVzc2FnZSgpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQpIG9iajsKCiAgICAgIGlmIChoYXNTdWJNZXNzYWdlKCkgIT0gb3RoZXIuaGFzU3ViTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTdWJNZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldFN1Yk1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFN1Yk1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNTdWJNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVUJfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3ViTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0SXNJbml0aWFsaXplZH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWRPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdElzSW5pdGlhbGl6ZWRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdElzSW5pdGlhbGl6ZWRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0U3ViTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgc3ViTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChzdWJNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgc3ViTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHN1Yk1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdWJNZXNzYWdlXyA9IHN1Yk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBzdWJNZXNzYWdlXwogICAgICAgICAgICAgIDogc3ViTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc1N1Yk1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VTdWJNZXNzYWdlKG90aGVyLmdldFN1Yk1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoaGFzU3ViTWVzc2FnZSgpKSB7CiAgICAgICAgICBpZiAoIWdldFN1Yk1lc3NhZ2UoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldFN1Yk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIHN1Yk1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2VPckJ1aWxkZXI+IHN1Yk1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIHN1Yl9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3ViTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdWJNZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2Ugc3ViX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgc3ViTWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UgZ2V0U3ViTWVzc2FnZSgpIHsKICAgICAgICBpZiAoc3ViTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBzdWJNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBzdWJNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2Ugc3ViX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN1Yk1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHN1Yk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHN1Yk1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1Yk1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZSBzdWJfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3ViTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChzdWJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgc3ViTWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3ViTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIHN1Yl9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVN1Yk1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHN1Yk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgc3ViTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBzdWJNZXNzYWdlXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0U3ViTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3ViTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3ViTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChzdWJNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIHN1Yl9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN1Yk1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHN1Yk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAoc3ViTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHN1Yk1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBzdWJNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2Ugc3ViX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuQnVpbGRlciBnZXRTdWJNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldFN1Yk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlIHN1Yl9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlT3JCdWlsZGVyIGdldFN1Yk1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHN1Yk1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gc3ViTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHN1Yk1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHN1Yk1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2Ugc3ViX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQuU3ViTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRTdWJNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChzdWJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgc3ViTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RJc0luaXRpYWxpemVkLlN1Yk1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZC5TdWJNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0U3ViTWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgc3ViTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3ViTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpemVkKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0SXNJbml0aWFsaXplZCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdElzSW5pdGlhbGl6ZWQgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RJc0luaXRpYWxpemVkPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RJc0luaXRpYWxpemVkPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdElzSW5pdGlhbGl6ZWQgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0SXNJbml0aWFsaXplZD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0SXNJbml0aWFsaXplZD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SXNJbml0aWFsaXplZCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3REdXBGaWVsZE51bWJlck9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0RHVwRmllbGROdW1iZXIpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8xCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0EoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgaW50IGdldEEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZvbyA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb28oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRm9vID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28gZ2V0Rm9vKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZvbyA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vT3JCdWlsZGVyIGdldEZvb09yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQmFyID0gMyB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0JhcigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBCYXIgPSAzIHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXIuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciBnZXRCYXIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQmFyID0gMyB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXJPckJ1aWxkZXIgZ2V0QmFyT3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVGVzdCB0aGF0IGdyb3VwcyBoYXZlIGRpc2pvaW50IGZpZWxkIG51bWJlcnMgZnJvbSB0aGVpciBzaWJsaW5ncyBhbmQKICAgKiBwYXJlbnRzLiAgVGhpcyBpcyBOT1QgcG9zc2libGUgaW4gcHJvdG8xOyBvbmx5IGdvb2dsZS5wcm90b2J1Zi4gIFdoZW4gYXR0ZW1wdGluZwogICAqIHRvIGNvbXBpbGUgd2l0aCBwcm90bzEsIHRoaXMgd2lsbCBlbWl0IGFuIGVycm9yOyBzbyB3ZSBvbmx5IGluY2x1ZGUgaXQKICAgKiBpbiBwcm90b2J1Zl91bml0dGVzdF9wcm90by4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3REdXBGaWVsZE51bWJlcn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3REdXBGaWVsZE51bWJlciBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RHVwRmllbGROdW1iZXIpCiAgICAgIFRlc3REdXBGaWVsZE51bWJlck9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdER1cEZpZWxkTnVtYmVyLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3REdXBGaWVsZE51bWJlcihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3REdXBGaWVsZE51bWJlcigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0RHVwRmllbGROdW1iZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBGb29PckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0RHVwRmllbGROdW1iZXIuRm9vKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNBKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgICAqLwogICAgICBpbnQgZ2V0QSgpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RHVwRmllbGROdW1iZXIuRm9vfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEZvbyBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdER1cEZpZWxkTnVtYmVyLkZvbykKICAgICAgICBGb29PckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBGb28ubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBGb28oY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBGb28oKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgRm9vKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfRm9vX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REdXBGaWVsZE51bWJlcl9Gb29fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28uQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFfRklFTERfTlVNQkVSID0gMTsKICAgICAgcHJpdmF0ZSBpbnQgYV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEEoKSB7CiAgICAgICAgcmV0dXJuIGFfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgYV8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBhXyk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbykpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbykgb2JqOwoKICAgICAgICBpZiAoaGFzQSgpICE9IG90aGVyLmhhc0EoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICAgIGlmIChnZXRBKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRBKCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28gcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbyBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbyBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28gcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbyBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28gcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbyBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbyBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbyBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28gcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdER1cEZpZWxkTnVtYmVyLkZvb30KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdER1cEZpZWxkTnVtYmVyLkZvbykKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvb09yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfRm9vX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfRm9vX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28uY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvby5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28ubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBhXyA9IDA7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REdXBGaWVsZE51bWJlcl9Gb29fZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28gYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28gcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28gcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbyh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQuYV8gPSBhXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbykgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28pb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5oYXNBKCkpIHsKICAgICAgICAgICAgc2V0QShvdGhlci5nZXRBKCkpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICAgIGFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBpbnQgYV8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgICAgcmV0dXJuIGFfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBhIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QShpbnQgdmFsdWUpIHsKCiAgICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBhXyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REdXBGaWVsZE51bWJlci5Gb28pCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RHVwRmllbGROdW1iZXIuRm9vKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbygpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvbz4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZvbz4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBGb28gcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb28+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb28+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBCYXJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0RHVwRmllbGROdW1iZXIuQmFyKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNBKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgICAqLwogICAgICBpbnQgZ2V0QSgpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RHVwRmllbGROdW1iZXIuQmFyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJhciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdER1cEZpZWxkTnVtYmVyLkJhcikKICAgICAgICBCYXJPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBCYXIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBCYXIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBCYXIoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgQmFyKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfQmFyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REdXBGaWVsZE51bWJlcl9CYXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFfRklFTERfTlVNQkVSID0gMTsKICAgICAgcHJpdmF0ZSBpbnQgYV8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEEoKSB7CiAgICAgICAgcmV0dXJuIGFfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgYV8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBhXyk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhcikpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhcikgb2JqOwoKICAgICAgICBpZiAoaGFzQSgpICE9IG90aGVyLmhhc0EoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICAgIGlmIChnZXRBKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRBKCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdER1cEZpZWxkTnVtYmVyLkJhcn0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdER1cEZpZWxkTnVtYmVyLkJhcikKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhck9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfQmFyX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfQmFyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhci5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBhXyA9IDA7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REdXBGaWVsZE51bWJlcl9CYXJfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhcih0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQuYV8gPSBhXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhcikgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIpb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5oYXNBKCkpIHsKICAgICAgICAgICAgc2V0QShvdGhlci5nZXRBKCkpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICAgIGFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBpbnQgYV8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgICAgcmV0dXJuIGFfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBhIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QShpbnQgdmFsdWUpIHsKCiAgICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBhXyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REdXBGaWVsZE51bWJlci5CYXIpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RHVwRmllbGROdW1iZXIuQmFyKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhcigpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJhcj4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEJhcj4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCYXIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxCYXI+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxCYXI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IGFfID0gMDsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5PX1BST1RPMQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9fUFJPVE8xCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEEoKSB7CiAgICAgIHJldHVybiBhXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vIGZvb187CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZvbyA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZvbyA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvby4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbyBnZXRGb28oKSB7CiAgICAgIHJldHVybiBmb29fID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28uZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmb29fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGb28gPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb29PckJ1aWxkZXIgZ2V0Rm9vT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gZm9vXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZm9vXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVJfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyIGJhcl87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEJhciA9IDMgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmFyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQmFyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEJhciA9IDMgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJhci4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciBnZXRCYXIoKSB7CiAgICAgIHJldHVybiBiYXJfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBiYXJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBCYXIgPSAzIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXJPckJ1aWxkZXIgZ2V0QmFyT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gYmFyXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyLmdldERlZmF1bHRJbnN0YW5jZSgpIDogYmFyXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVHcm91cCgyLCBnZXRGb28oKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlR3JvdXAoMywgZ2V0QmFyKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIGFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlR3JvdXBTaXplKDIsIGdldEZvbygpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlR3JvdXBTaXplKDMsIGdldEJhcigpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlcikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIpIG9iajsKCiAgICAgIGlmIChoYXNBKCkgIT0gb3RoZXIuaGFzQSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBpZiAoZ2V0QSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEEoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGb28oKSAhPSBvdGhlci5oYXNGb28oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRm9vKCkpIHsKICAgICAgICBpZiAoIWdldEZvbygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Rm9vKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0JhcigpICE9IG90aGVyLmhhc0JhcigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNCYXIoKSkgewogICAgICAgIGlmICghZ2V0QmFyKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRCYXIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBBX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZvbygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGb28oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNCYXIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEJBUl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QmFyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlciBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlciBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlciBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlciBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdCB0aGF0IGdyb3VwcyBoYXZlIGRpc2pvaW50IGZpZWxkIG51bWJlcnMgZnJvbSB0aGVpciBzaWJsaW5ncyBhbmQKICAgICAqIHBhcmVudHMuICBUaGlzIGlzIE5PVCBwb3NzaWJsZSBpbiBwcm90bzE7IG9ubHkgZ29vZ2xlLnByb3RvYnVmLiAgV2hlbiBhdHRlbXB0aW5nCiAgICAgKiB0byBjb21waWxlIHdpdGggcHJvdG8xLCB0aGlzIHdpbGwgZW1pdCBhbiBlcnJvcjsgc28gd2Ugb25seSBpbmNsdWRlIGl0CiAgICAgKiBpbiBwcm90b2J1Zl91bml0dGVzdF9wcm90by4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3REdXBGaWVsZE51bWJlcn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REdXBGaWVsZE51bWJlcikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlck9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER1cEZpZWxkTnVtYmVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldEZvb0ZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0QmFyRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBhXyA9IDA7CiAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgaWYgKGZvb0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZvb0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZvb0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgYmFyXyA9IG51bGw7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGJhckJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGJhckJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REdXBGaWVsZE51bWJlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmFfID0gYV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZm9vXyA9IGZvb0J1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGZvb18KICAgICAgICAgICAgICA6IGZvb0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuYmFyXyA9IGJhckJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IGJhcl8KICAgICAgICAgICAgICA6IGJhckJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlcikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNBKCkpIHsKICAgICAgICAgIHNldEEob3RoZXIuZ2V0QSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZvbygpKSB7CiAgICAgICAgICBtZXJnZUZvbyhvdGhlci5nZXRGb28oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNCYXIoKSkgewogICAgICAgICAgbWVyZ2VCYXIob3RoZXIuZ2V0QmFyKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIGFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTk6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRHcm91cCgyLAogICAgICAgICAgICAgICAgICAgIGdldEZvb0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTkKICAgICAgICAgICAgICBjYXNlIDI3OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkR3JvdXAoMywKICAgICAgICAgICAgICAgICAgICBnZXRCYXJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI3CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGFfIDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8xCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0QSgpIHsKICAgICAgICByZXR1cm4gYV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIE5PX1BST1RPMQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRBKGludCB2YWx1ZSkgewoKICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogTk9fUFJPVE8xCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgYV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbyBmb29fOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28sIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvby5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb29PckJ1aWxkZXI+IGZvb0J1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRm9vID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvbyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb28oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGb28gPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZvby4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28gZ2V0Rm9vKCkgewogICAgICAgIGlmIChmb29CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZm9vXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZm9vXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZvb0J1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZvbyA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvbyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28gdmFsdWUpIHsKICAgICAgICBpZiAoZm9vQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvb0J1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZvbyA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvbygKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvby5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmb29CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmb29fID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvb0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZvbyA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRm9vKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvbyB2YWx1ZSkgewogICAgICAgIGlmIChmb29CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkgJiYKICAgICAgICAgICAgZm9vXyAhPSBudWxsICYmCiAgICAgICAgICAgIGZvb18gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEZvb0J1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9vXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb29CdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZm9vXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZvbyA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICBpZiAoZm9vQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZm9vQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgZm9vQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRm9vID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvby5CdWlsZGVyIGdldEZvb0J1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRGb29GaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZvbyA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb29PckJ1aWxkZXIgZ2V0Rm9vT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChmb29CdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZm9vQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZm9vXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28uZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmb29fOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRm9vID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28uQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuRm9vT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZvb0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoZm9vQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZm9vQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb28sIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkZvby5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5Gb29PckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRGb28oKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZm9vQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyIGJhcl87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhck9yQnVpbGRlcj4gYmFyQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBCYXIgPSAzIHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmFyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0JhcigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEJhciA9IDMgeyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYmFyLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciBnZXRCYXIoKSB7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBiYXJfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBiYXJfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gYmFyQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQmFyID0gMyB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmFyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciB2YWx1ZSkgewogICAgICAgIGlmIChiYXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGJhcl8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYmFyQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQmFyID0gMyB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmFyKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGJhcl8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYmFyQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQmFyID0gMyB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VCYXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyIHZhbHVlKSB7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSAmJgogICAgICAgICAgICBiYXJfICE9IG51bGwgJiYKICAgICAgICAgICAgYmFyXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0QmFyQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBiYXJfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJhckJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChiYXJfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQmFyID0gMyB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJCYXIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGJhcl8gPSBudWxsOwogICAgICAgIGlmIChiYXJCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBiYXJCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBiYXJCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBCYXIgPSAzIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyLkJ1aWxkZXIgZ2V0QmFyQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEJhckZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgQmFyID0gMyB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhck9yQnVpbGRlciBnZXRCYXJPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGJhckJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBiYXJCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBiYXJfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhci5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGJhcl87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBCYXIgPSAzIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhci5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlci5CYXJPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0QmFyRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChiYXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBiYXJCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHVwRmllbGROdW1iZXIuQmFyLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyLkJhck9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldEJhcigpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgYmFyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiYXJCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RHVwRmllbGROdW1iZXIpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REdXBGaWVsZE51bWJlcikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER1cEZpZWxkTnVtYmVyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlciBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3REdXBGaWVsZE51bWJlcj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0RHVwRmllbGROdW1iZXI+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0RHVwRmllbGROdW1iZXIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RHVwRmllbGROdW1iZXI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdER1cEZpZWxkTnVtYmVyPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REdXBGaWVsZE51bWJlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RFYWdlck1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3ViTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3ViTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHN1Yl9tZXNzYWdlID0gMSBbbGF6eSA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdWJNZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRTdWJNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gZmFsc2VdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0U3ViTWVzc2FnZU9yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIEFkZGl0aW9uYWwgbWVzc2FnZXMgZm9yIHRlc3RpbmcgbGF6eSBmaWVsZHMuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RWFnZXJNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEVhZ2VyTWVzc2FnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RWFnZXJNZXNzYWdlKQogICAgICBUZXN0RWFnZXJNZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0RWFnZXJNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RFYWdlck1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0RWFnZXJNZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RFYWdlck1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVhZ2VyTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVUJfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBzdWJNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBzdWJfbWVzc2FnZSA9IDEgW2xhenkgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdWJNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3ViTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHN1Yl9tZXNzYWdlID0gMSBbbGF6eSA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdWJNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0U3ViTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIHN1Yk1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHN1Yk1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHN1Yl9tZXNzYWdlID0gMSBbbGF6eSA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRTdWJNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gc3ViTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViTWVzc2FnZV87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEsIGdldFN1Yk1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRTdWJNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKGhhc1N1Yk1lc3NhZ2UoKSAhPSBvdGhlci5oYXNTdWJNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N1Yk1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0U3ViTWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3ViTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc1N1Yk1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNVQl9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdWJNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFkZGl0aW9uYWwgbWVzc2FnZXMgZm9yIHRlc3RpbmcgbGF6eSBmaWVsZHMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RWFnZXJNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWVzc2FnZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1lc3NhZ2VPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVhZ2VyTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldFN1Yk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHN1Yk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAoc3ViTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHN1Yk1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBzdWJNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVhZ2VyTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3ViTWVzc2FnZV8gPSBzdWJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gc3ViTWVzc2FnZV8KICAgICAgICAgICAgICA6IHN1Yk1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc1N1Yk1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VTdWJNZXNzYWdlKG90aGVyLmdldFN1Yk1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldFN1Yk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgc3ViTWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gc3ViTWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBzdWJfbWVzc2FnZSA9IDEgW2xhenkgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN1Yk1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3ViTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgc3ViTWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRTdWJNZXNzYWdlKCkgewogICAgICAgIGlmIChzdWJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHN1Yk1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHN1Yk1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gc3ViTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN1Yk1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAoc3ViTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgc3ViTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3ViTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN1Yk1lc3NhZ2UoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChzdWJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgc3ViTWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3ViTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlU3ViTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChzdWJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICAgIHN1Yk1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgc3ViTWVzc2FnZV8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0U3ViTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3ViTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3ViTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChzdWJNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3ViTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgc3ViTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChzdWJNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgc3ViTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHN1Yk1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHN1Yl9tZXNzYWdlID0gMSBbbGF6eSA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRTdWJNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldFN1Yk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gZmFsc2VdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRTdWJNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChzdWJNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHN1Yk1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBzdWJNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHN1Yk1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBzdWJfbWVzc2FnZSA9IDEgW2xhenkgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFN1Yk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHN1Yk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBzdWJNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRTdWJNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBzdWJNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdWJNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWVzc2FnZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFYWdlck1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEVhZ2VyTWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RFYWdlck1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RWFnZXJNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFYWdlck1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RMYXp5TWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TGF6eU1lc3NhZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHN1Yl9tZXNzYWdlID0gMSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3ViTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3ViTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHN1Yl9tZXNzYWdlID0gMSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN1Yk1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFN1Yk1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBzdWJfbWVzc2FnZSA9IDEgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFN1Yk1lc3NhZ2VPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdExhenlNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZSkKICAgICAgVGVzdExhenlNZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TGF6eU1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdExhenlNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdExhenlNZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RMYXp5TWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RMYXp5TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RMYXp5TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1VCX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgc3ViTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdWJNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3ViTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHN1Yl9tZXNzYWdlID0gMSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN1Yk1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRTdWJNZXNzYWdlKCkgewogICAgICByZXR1cm4gc3ViTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0U3ViTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHN1Yk1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHN1Yk1lc3NhZ2VfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRTdWJNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0U3ViTWVzc2FnZSgpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UpIG9iajsKCiAgICAgIGlmIChoYXNTdWJNZXNzYWdlKCkgIT0gb3RoZXIuaGFzU3ViTWVzc2FnZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTdWJNZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldFN1Yk1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFN1Yk1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNTdWJNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVUJfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3ViTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RMYXp5TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TGF6eU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0U3ViTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgc3ViTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChzdWJNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgc3ViTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHN1Yk1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TGF6eU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdWJNZXNzYWdlXyA9IHN1Yk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBzdWJNZXNzYWdlXwogICAgICAgICAgICAgIDogc3ViTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNTdWJNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlU3ViTWVzc2FnZShvdGhlci5nZXRTdWJNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRTdWJNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHN1Yk1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IHN1Yk1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN1Yk1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3ViTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzdWJNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFN1Yk1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKHN1Yk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gc3ViTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBzdWJNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBzdWJfbWVzc2FnZSA9IDEgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdWJNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHN1Yk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHN1Yk1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1Yk1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHN1Yl9tZXNzYWdlID0gMSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN1Yk1lc3NhZ2UoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChzdWJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgc3ViTWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3ViTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VTdWJNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHN1Yk1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgc3ViTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBzdWJNZXNzYWdlXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRTdWJNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdWJNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdWJNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKHN1Yk1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBzdWJfbWVzc2FnZSA9IDEgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN1Yk1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHN1Yk1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAoc3ViTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHN1Yk1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBzdWJNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBzdWJfbWVzc2FnZSA9IDEgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRTdWJNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldFN1Yk1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgc3ViX21lc3NhZ2UgPSAxIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFN1Yk1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHN1Yk1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gc3ViTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHN1Yk1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViTWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHN1Yl9tZXNzYWdlID0gMSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRTdWJNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChzdWJNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgc3ViTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0U3ViTWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgc3ViTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3ViTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdExhenlNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RMYXp5TWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RMYXp5TWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RMYXp5TWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TGF6eU1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdExhenlNZXNzYWdlUmVwZWF0ZWRPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlUmVwZWF0ZWQpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlIHJlcGVhdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2U+IAogICAgICAgIGdldFJlcGVhdGVkTWVzc2FnZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZSByZXBlYXRlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlIGdldFJlcGVhdGVkTWVzc2FnZShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlIHJlcGVhdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkTWVzc2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TGF6eU1lc3NhZ2UgcmVwZWF0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZSByZXBlYXRlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkKQogICAgICBUZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdExhenlNZXNzYWdlUmVwZWF0ZWQubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdExhenlNZXNzYWdlUmVwZWF0ZWQoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCgpIHsKICAgICAgcmVwZWF0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RMYXp5TWVzc2FnZVJlcGVhdGVkX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdExhenlNZXNzYWdlUmVwZWF0ZWRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZT4gcmVwZWF0ZWRNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZSByZXBlYXRlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZT4gZ2V0UmVwZWF0ZWRNZXNzYWdlTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TGF6eU1lc3NhZ2UgcmVwZWF0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZSByZXBlYXRlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRNZXNzYWdlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZSByZXBlYXRlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZSBnZXRSZXBlYXRlZE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TGF6eU1lc3NhZ2UgcmVwZWF0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCByZXBlYXRlZE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCByZXBlYXRlZE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkKSBvYmo7CgogICAgICBpZiAoIWdldFJlcGVhdGVkTWVzc2FnZUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZE1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGdldFJlcGVhdGVkTWVzc2FnZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRNZXNzYWdlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlUmVwZWF0ZWQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlUmVwZWF0ZWQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlUmVwZWF0ZWQgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlUmVwZWF0ZWQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlUmVwZWF0ZWRPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdExhenlNZXNzYWdlUmVwZWF0ZWRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdExhenlNZXNzYWdlUmVwZWF0ZWRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlUmVwZWF0ZWQubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdExhenlNZXNzYWdlUmVwZWF0ZWRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlUmVwZWF0ZWQgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlUmVwZWF0ZWQgcmVzdWx0KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRNZXNzYWdlXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZE1lc3NhZ2VfID0gcmVwZWF0ZWRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkTWVzc2FnZV8gPSByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlUmVwZWF0ZWQpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlUmVwZWF0ZWQpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZE1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRNZXNzYWdlXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkTWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZSBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2U+IHJlcGVhdGVkTWVzc2FnZV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2U+KHJlcGVhdGVkTWVzc2FnZV8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlT3JCdWlsZGVyPiByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlIHJlcGVhdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZT4gZ2V0UmVwZWF0ZWRNZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTWVzc2FnZV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TGF6eU1lc3NhZ2UgcmVwZWF0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZE1lc3NhZ2VDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZV8uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TGF6eU1lc3NhZ2UgcmVwZWF0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlIGdldFJlcGVhdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZSByZXBlYXRlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TGF6eU1lc3NhZ2UgcmVwZWF0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZSByZXBlYXRlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TGF6eU1lc3NhZ2UgcmVwZWF0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlIHJlcGVhdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZSByZXBlYXRlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlIHJlcGVhdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkTWVzc2FnZSgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2U+IHZhbHVlcykgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkTWVzc2FnZV8pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlIHJlcGVhdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlIHJlcGVhdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TGF6eU1lc3NhZ2UgcmVwZWF0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZSByZXBlYXRlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZSByZXBlYXRlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTWVzc2FnZV8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZSByZXBlYXRlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TGF6eU1lc3NhZ2UgcmVwZWF0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlLkJ1aWxkZXIgYWRkUmVwZWF0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlIHJlcGVhdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZS5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdExhenlNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdExhenlNZXNzYWdlUmVwZWF0ZWQpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdExhenlNZXNzYWdlUmVwZWF0ZWQ+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdExhenlNZXNzYWdlUmVwZWF0ZWQ+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TGF6eU1lc3NhZ2VSZXBlYXRlZCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RMYXp5TWVzc2FnZVJlcGVhdGVkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEVhZ2VyTWF5YmVMYXp5T3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFYWdlck1heWJlTGF6eSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZV9mb28gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZUZvbyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTWVzc2FnZUZvbygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfZm9vID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlRm9vLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRNZXNzYWdlRm9vKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZV9mb28gPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0TWVzc2FnZUZvb09yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBtZXNzYWdlX2JhciA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtZXNzYWdlQmFyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNNZXNzYWdlQmFyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZV9iYXIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VCYXIuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE1lc3NhZ2VCYXIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBtZXNzYWdlX2JhciA9IDI7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRNZXNzYWdlQmFyT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgbWVzc2FnZV9iYXogPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZUJheiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTWVzc2FnZUJheigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgbWVzc2FnZV9iYXogPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VCYXouCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgZ2V0TWVzc2FnZUJheigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgbWVzc2FnZV9iYXogPSAzOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRNZXNzYWdlQmF6T3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFYWdlck1heWJlTGF6eX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RFYWdlck1heWJlTGF6eSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RWFnZXJNYXliZUxhenkpCiAgICAgIFRlc3RFYWdlck1heWJlTGF6eU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdEVhZ2VyTWF5YmVMYXp5Lm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RFYWdlck1heWJlTGF6eShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RFYWdlck1heWJlTGF6eSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0RWFnZXJNYXliZUxhenkoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNYXliZUxhenlfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNYXliZUxhenlfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHBhY2tlZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHBhY2tlZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc1BhY2tlZCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcyBwYWNrZWQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkLgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMgZ2V0UGFja2VkKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHBhY2tlZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXNPckJ1aWxkZXIgZ2V0UGFja2VkT3JCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZE1lc3NhZ2UgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlKQogICAgICAgIE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBOZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgTmVzdGVkTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVhZ2VyTWF5YmVMYXp5X05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVhZ2VyTWF5YmVMYXp5X05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMgcGFja2VkXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcGFja2VkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcGFja2VkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUGFja2VkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcyBwYWNrZWQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMgZ2V0UGFja2VkKCkgewogICAgICAgIHJldHVybiBwYWNrZWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBhY2tlZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcGFja2VkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlc09yQnVpbGRlciBnZXRQYWNrZWRPckJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcGFja2VkXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgZ2V0UGFja2VkKCkpOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGdldFBhY2tlZCgpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICAgIGlmIChoYXNQYWNrZWQoKSAhPSBvdGhlci5oYXNQYWNrZWQoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNQYWNrZWQoKSkgewogICAgICAgICAgaWYgKCFnZXRQYWNrZWQoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzUGFja2VkKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWQoKS5oYXNoQ29kZSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSkKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVhZ2VyTWF5YmVMYXp5X05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFYWdlck1heWJlTGF6eV9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgICAgZ2V0UGFja2VkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIHBhY2tlZF8gPSBudWxsOwogICAgICAgICAgaWYgKHBhY2tlZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgcGFja2VkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICBwYWNrZWRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFYWdlck1heWJlTGF6eV9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQucGFja2VkXyA9IHBhY2tlZEJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICAgID8gcGFja2VkXwogICAgICAgICAgICAgICAgOiBwYWNrZWRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5oYXNQYWNrZWQoKSkgewogICAgICAgICAgICBtZXJnZVBhY2tlZChvdGhlci5nZXRQYWNrZWQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgZ2V0UGFja2VkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIHBhY2tlZF87CiAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXNPckJ1aWxkZXI+IHBhY2tlZEJ1aWxkZXJfOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcGFja2VkID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwYWNrZWQgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc1BhY2tlZCgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcyBwYWNrZWQgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIGdldFBhY2tlZCgpIHsKICAgICAgICAgIGlmIChwYWNrZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBwYWNrZWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBhY2tlZF87CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gcGFja2VkQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHBhY2tlZCA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyB2YWx1ZSkgewogICAgICAgICAgaWYgKHBhY2tlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwYWNrZWRfID0gdmFsdWU7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwYWNrZWRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcGFja2VkID0gMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKHBhY2tlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcGFja2VkXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGFja2VkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHBhY2tlZCA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlUGFja2VkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIHZhbHVlKSB7CiAgICAgICAgICBpZiAocGFja2VkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgICBwYWNrZWRfICE9IG51bGwgJiYKICAgICAgICAgICAgICBwYWNrZWRfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgICAgZ2V0UGFja2VkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcGFja2VkXyA9IHZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwYWNrZWRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHBhY2tlZF8gIT0gbnVsbCkgewogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcGFja2VkID0gMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWQoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBwYWNrZWRfID0gbnVsbDsKICAgICAgICAgIGlmIChwYWNrZWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICAgIHBhY2tlZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgcGFja2VkQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcyBwYWNrZWQgPSAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMuQnVpbGRlciBnZXRQYWNrZWRCdWlsZGVyKCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gZ2V0UGFja2VkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZFR5cGVzIHBhY2tlZCA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlc09yQnVpbGRlciBnZXRQYWNrZWRPckJ1aWxkZXIoKSB7CiAgICAgICAgICBpZiAocGFja2VkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gcGFja2VkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHBhY2tlZF8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHBhY2tlZF87CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMgcGFja2VkID0gMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgICBnZXRQYWNrZWRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgICBpZiAocGFja2VkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBwYWNrZWRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgICBnZXRQYWNrZWQoKSwKICAgICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICAgIHBhY2tlZF8gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHBhY2tlZEJ1aWxkZXJfOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE5lc3RlZE1lc3NhZ2U+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTmVzdGVkTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUVTU0FHRV9GT09fRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgbWVzc2FnZUZvb187CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZV9mb28gPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZUZvbyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc01lc3NhZ2VGb28oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBtZXNzYWdlX2ZvbyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbWVzc2FnZUZvby4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE1lc3NhZ2VGb28oKSB7CiAgICAgIHJldHVybiBtZXNzYWdlRm9vXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlRm9vXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBtZXNzYWdlX2ZvbyA9IDE7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0TWVzc2FnZUZvb09yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG1lc3NhZ2VGb29fID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1lc3NhZ2VGb29fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1FU1NBR0VfQkFSX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG1lc3NhZ2VCYXJfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfYmFyID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1lc3NhZ2VCYXIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNNZXNzYWdlQmFyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZV9iYXIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VCYXIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRNZXNzYWdlQmFyKCkgewogICAgICByZXR1cm4gbWVzc2FnZUJhcl8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZUJhcl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZV9iYXIgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldE1lc3NhZ2VCYXJPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBtZXNzYWdlQmFyXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlQmFyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX0JBWl9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIG1lc3NhZ2VCYXpfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgbWVzc2FnZV9iYXogPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZUJheiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc01lc3NhZ2VCYXooKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIG1lc3NhZ2VfYmF6ID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlQmF6LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSBnZXRNZXNzYWdlQmF6KCkgewogICAgICByZXR1cm4gbWVzc2FnZUJhel8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlQmF6XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIG1lc3NhZ2VfYmF6ID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE1lc3NhZ2VCYXpPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBtZXNzYWdlQmF6XyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1lc3NhZ2VCYXpfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRNZXNzYWdlRm9vKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMiwgZ2V0TWVzc2FnZUJhcigpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDMsIGdldE1lc3NhZ2VCYXooKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRNZXNzYWdlRm9vKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBnZXRNZXNzYWdlQmFyKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgzLCBnZXRNZXNzYWdlQmF6KCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5KSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSkgb2JqOwoKICAgICAgaWYgKGhhc01lc3NhZ2VGb28oKSAhPSBvdGhlci5oYXNNZXNzYWdlRm9vKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc01lc3NhZ2VGb28oKSkgewogICAgICAgIGlmICghZ2V0TWVzc2FnZUZvbygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TWVzc2FnZUZvbygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNNZXNzYWdlQmFyKCkgIT0gb3RoZXIuaGFzTWVzc2FnZUJhcigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNNZXNzYWdlQmFyKCkpIHsKICAgICAgICBpZiAoIWdldE1lc3NhZ2VCYXIoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE1lc3NhZ2VCYXIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzTWVzc2FnZUJheigpICE9IG90aGVyLmhhc01lc3NhZ2VCYXooKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTWVzc2FnZUJheigpKSB7CiAgICAgICAgaWYgKCFnZXRNZXNzYWdlQmF6KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRNZXNzYWdlQmF6KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzTWVzc2FnZUZvbygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUVTU0FHRV9GT09fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE1lc3NhZ2VGb28oKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNNZXNzYWdlQmFyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNRVNTQUdFX0JBUl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TWVzc2FnZUJhcigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc01lc3NhZ2VCYXooKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1FU1NBR0VfQkFaX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRNZXNzYWdlQmF6KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5IHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RWFnZXJNYXliZUxhenl9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RWFnZXJNYXliZUxhenkpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenlPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVhZ2VyTWF5YmVMYXp5X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFYWdlck1heWJlTGF6eV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRNZXNzYWdlRm9vRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRNZXNzYWdlQmFyRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRNZXNzYWdlQmF6RmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBtZXNzYWdlRm9vXyA9IG51bGw7CiAgICAgICAgaWYgKG1lc3NhZ2VGb29CdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBtZXNzYWdlRm9vQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgbWVzc2FnZUZvb0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgbWVzc2FnZUJhcl8gPSBudWxsOwogICAgICAgIGlmIChtZXNzYWdlQmFyQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZUJhckJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG1lc3NhZ2VCYXJCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG1lc3NhZ2VCYXpfID0gbnVsbDsKICAgICAgICBpZiAobWVzc2FnZUJhekJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VCYXpCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBtZXNzYWdlQmF6QnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVhZ2VyTWF5YmVMYXp5X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5IGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubWVzc2FnZUZvb18gPSBtZXNzYWdlRm9vQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gbWVzc2FnZUZvb18KICAgICAgICAgICAgICA6IG1lc3NhZ2VGb29CdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1lc3NhZ2VCYXJfID0gbWVzc2FnZUJhckJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG1lc3NhZ2VCYXJfCiAgICAgICAgICAgICAgOiBtZXNzYWdlQmFyQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5tZXNzYWdlQmF6XyA9IG1lc3NhZ2VCYXpCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBtZXNzYWdlQmF6XwogICAgICAgICAgICAgIDogbWVzc2FnZUJhekJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNNZXNzYWdlRm9vKCkpIHsKICAgICAgICAgIG1lcmdlTWVzc2FnZUZvbyhvdGhlci5nZXRNZXNzYWdlRm9vKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzTWVzc2FnZUJhcigpKSB7CiAgICAgICAgICBtZXJnZU1lc3NhZ2VCYXIob3RoZXIuZ2V0TWVzc2FnZUJhcigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc01lc3NhZ2VCYXooKSkgewogICAgICAgICAgbWVyZ2VNZXNzYWdlQmF6KG90aGVyLmdldE1lc3NhZ2VCYXooKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE1lc3NhZ2VGb29GaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZUJhckZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRNZXNzYWdlQmF6RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG1lc3NhZ2VGb29fOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IG1lc3NhZ2VGb29CdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZV9mb28gPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtZXNzYWdlRm9vIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc01lc3NhZ2VGb28oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfZm9vID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VGb28uCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0TWVzc2FnZUZvbygpIHsKICAgICAgICBpZiAobWVzc2FnZUZvb0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlRm9vXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlRm9vXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VGb29CdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfZm9vID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNZXNzYWdlRm9vKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGb29CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG1lc3NhZ2VGb29fID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VGb29CdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfZm9vID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNZXNzYWdlRm9vKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZUZvb0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VGb29fID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VGb29CdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfZm9vID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU1lc3NhZ2VGb28ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZUZvb0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBtZXNzYWdlRm9vXyAhPSBudWxsICYmCiAgICAgICAgICAgIG1lc3NhZ2VGb29fICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE1lc3NhZ2VGb29CdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1lc3NhZ2VGb29fID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VGb29CdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAobWVzc2FnZUZvb18gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfZm9vID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1lc3NhZ2VGb28oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG1lc3NhZ2VGb29fID0gbnVsbDsKICAgICAgICBpZiAobWVzc2FnZUZvb0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VGb29CdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBtZXNzYWdlRm9vQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBtZXNzYWdlX2ZvbyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0TWVzc2FnZUZvb0J1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRNZXNzYWdlRm9vRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfZm9vID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0TWVzc2FnZUZvb09yQnVpbGRlcigpIHsKICAgICAgICBpZiAobWVzc2FnZUZvb0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlRm9vQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZvb18gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlRm9vXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZV9mb28gPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRNZXNzYWdlRm9vRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChtZXNzYWdlRm9vQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZUZvb0J1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZUZvbygpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgbWVzc2FnZUZvb18gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWVzc2FnZUZvb0J1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG1lc3NhZ2VCYXJfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IG1lc3NhZ2VCYXJCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZV9iYXIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtZXNzYWdlQmFyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc01lc3NhZ2VCYXIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfYmFyID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VCYXIuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0TWVzc2FnZUJhcigpIHsKICAgICAgICBpZiAobWVzc2FnZUJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlQmFyXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlQmFyXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VCYXJCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfYmFyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNZXNzYWdlQmFyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VCYXJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG1lc3NhZ2VCYXJfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VCYXJCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfYmFyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNZXNzYWdlQmFyKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZUJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VCYXJfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VCYXJCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfYmFyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU1lc3NhZ2VCYXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZUJhckJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSAmJgogICAgICAgICAgICBtZXNzYWdlQmFyXyAhPSBudWxsICYmCiAgICAgICAgICAgIG1lc3NhZ2VCYXJfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE1lc3NhZ2VCYXJCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1lc3NhZ2VCYXJfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VCYXJCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAobWVzc2FnZUJhcl8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfYmFyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1lc3NhZ2VCYXIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG1lc3NhZ2VCYXJfID0gbnVsbDsKICAgICAgICBpZiAobWVzc2FnZUJhckJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VCYXJCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBtZXNzYWdlQmFyQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBtZXNzYWdlX2JhciA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0TWVzc2FnZUJhckJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRNZXNzYWdlQmFyRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG1lc3NhZ2VfYmFyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0TWVzc2FnZUJhck9yQnVpbGRlcigpIHsKICAgICAgICBpZiAobWVzc2FnZUJhckJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlQmFyQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUJhcl8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlQmFyXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgbWVzc2FnZV9iYXIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRNZXNzYWdlQmFyRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChtZXNzYWdlQmFyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZUJhckJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZUJhcigpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgbWVzc2FnZUJhcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWVzc2FnZUJhckJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgbWVzc2FnZUJhel87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gbWVzc2FnZUJhekJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIG1lc3NhZ2VfYmF6ID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZUJheiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNZXNzYWdlQmF6KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIG1lc3NhZ2VfYmF6ID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VCYXouCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSBnZXRNZXNzYWdlQmF6KCkgewogICAgICAgIGlmIChtZXNzYWdlQmF6QnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VCYXpfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZUJhel87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlQmF6QnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIG1lc3NhZ2VfYmF6ID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNZXNzYWdlQmF6KHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZUJhekJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgbWVzc2FnZUJhel8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUJhekJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSBtZXNzYWdlX2JheiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TWVzc2FnZUJheigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZUJhekJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VCYXpfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VCYXpCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgbWVzc2FnZV9iYXogPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlTWVzc2FnZUJheihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VCYXpCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkgJiYKICAgICAgICAgICAgbWVzc2FnZUJhel8gIT0gbnVsbCAmJgogICAgICAgICAgICBtZXNzYWdlQmF6XyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE1lc3NhZ2VCYXpCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1lc3NhZ2VCYXpfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG1lc3NhZ2VCYXpCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAobWVzc2FnZUJhel8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgbWVzc2FnZV9iYXogPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWVzc2FnZUJheigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgbWVzc2FnZUJhel8gPSBudWxsOwogICAgICAgIGlmIChtZXNzYWdlQmF6QnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZUJhekJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG1lc3NhZ2VCYXpCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgbWVzc2FnZV9iYXogPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgZ2V0TWVzc2FnZUJhekJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRNZXNzYWdlQmF6RmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UgbWVzc2FnZV9iYXogPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE1lc3NhZ2VCYXpPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VCYXpCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUJhekJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VCYXpfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlQmF6XzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSBtZXNzYWdlX2JheiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE1lc3NhZ2VCYXpGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VCYXpCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBtZXNzYWdlQmF6QnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eS5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRNZXNzYWdlQmF6KCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBtZXNzYWdlQmF6XyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtZXNzYWdlQmF6QnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEVhZ2VyTWF5YmVMYXp5KQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RWFnZXJNYXliZUxhenkpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFYWdlck1heWJlTGF6eSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RWFnZXJNYXliZUxhenk+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEVhZ2VyTWF5YmVMYXp5PigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdEVhZ2VyTWF5YmVMYXp5IHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEVhZ2VyTWF5YmVMYXp5PiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFYWdlck1heWJlTGF6eT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RWFnZXJNYXliZUxhenkgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBOZWVkZWQgZm9yIGEgUHl0aG9uIHRlc3QuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzKQogICAgICBUZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMi4KICAgICAgICovCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMkxpc3QoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgbmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzIuCiAgICAgICAqLwogICAgICBpbnQgZ2V0TmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzJDb3VudCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgbmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgaW50IGdldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyKGludCBpbmRleCk7CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfZm9yZWlnbm1lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IAogICAgICAgICAgZ2V0TmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VMaXN0KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9mb3JlaWdubWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZShpbnQgaW5kZXgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfZm9yZWlnbm1lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIGludCBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUNvdW50KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9mb3JlaWdubWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0TmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9mb3JlaWdubWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZE1lc3NhZ2UgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlKQogICAgICAgIE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBOZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRNZXNzYWdlSGFzQml0c19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRNZXNzYWdlSGFzQml0c19OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5FU1RFRE1FU1NBR0VfUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSID0gMTsKICAgICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyXyA9CiAgICAgICAgICBlbXB0eUludExpc3QoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgbmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkVTVEVETUVTU0FHRV9SRVBFQVRFRF9GT1JFSUdOTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAyOwogICAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9mb3JlaWdubWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gZ2V0TmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VMaXN0KCkgewogICAgICAgIHJldHVybiBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ZvcmVpZ25tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfZm9yZWlnbm1lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUNvdW50KCkgewogICAgICAgIHJldHVybiBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9mb3JlaWdubWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ZvcmVpZ25tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMiwgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIHsKICAgICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICAgIH0KICAgICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgICBzaXplICs9IDEgKiBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMkxpc3QoKS5zaXplKCk7CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICAgIGlmICghZ2V0TmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzJMaXN0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoIWdldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlTGlzdCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBORVNURURNRVNTQUdFX1JFUEVBVEVEX0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgICAgfQogICAgICAgIGlmIChnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUNvdW50KCkgPiAwKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBORVNURURNRVNTQUdFX1JFUEVBVEVEX0ZPUkVJR05NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgICAgfQogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2V9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlKQogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgICAgaWYgKG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8gPSBudWxsOwogICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgICB9CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRNZXNzYWdlSGFzQml0c19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlKHRoaXMpOwogICAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgICBpZiAobmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgICAgIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlXyk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3VsdC5uZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8gPSBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV87CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHQubmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfID0gbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgcmVzdWx0Lm5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyXyA9IG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyXzsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSlvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAoIW90aGVyLm5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMl8gPSBvdGhlci5uZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMl87CiAgICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlTmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMl8uYWRkQWxsKG90aGVyLm5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAobmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICghb3RoZXIubmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGlmIChuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8gPSBvdGhlci5uZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV87CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGVuc3VyZU5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8uYWRkQWxsKG90aGVyLm5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlXyk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoIW90aGVyLm5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBpZiAobmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8gPSBvdGhlci5uZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV87CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgICBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5uZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGVuc3VyZU5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgZW5zdXJlTmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICAgIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyXy5hZGRJbnQoaW5wdXQucmVhZEludDMyKCkpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBtID0KICAgICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgICAgaWYgKG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZU5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfLmFkZChtKTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVOZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICAgIGlmICghbmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICAgIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyXyA9IG1ha2VNdXRhYmxlQ29weShuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgbmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzIuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMkxpc3QoKSB7CiAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmV0dXJuIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBpbnQgZ2V0TmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzJDb3VudCgpIHsKICAgICAgICAgIHJldHVybiBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAgICogQHJldHVybiBUaGUgbmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBpbnQgZ2V0TmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgICByZXR1cm4gbmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMiB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyKAogICAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICAgIGVuc3VyZU5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ludDMyID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMiB0byBhZGQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICAgIGVuc3VyZU5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfaW50MzIgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMiB0byBhZGQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyKAogICAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICAgIGVuc3VyZU5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMl8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9pbnQzMiA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck5lc3RlZG1lc3NhZ2VSZXBlYXRlZEludDMyKCkgewogICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8gPQogICAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVOZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUlzTXV0YWJsZSgpIHsKICAgICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4obmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcl87CgogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ZvcmVpZ25tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IGdldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlTGlzdCgpIHsKICAgICAgICAgIGlmIChuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlXyk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9mb3JlaWdubWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBpbnQgZ2V0TmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VDb3VudCgpIHsKICAgICAgICAgIGlmIChuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlXy5zaXplKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9mb3JlaWdubWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIGdldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlKGludCBpbmRleCkgewogICAgICAgICAgaWYgKG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfLmdldChpbmRleCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfZm9yZWlnbm1lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZSgKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgICBpZiAobmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5zdXJlTmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ZvcmVpZ25tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2UoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVOZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfZm9yZWlnbm1lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgICBpZiAobmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5zdXJlTmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfLmFkZCh2YWx1ZSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9mb3JlaWdubWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlKAogICAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICAgIGlmIChuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVOZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfZm9yZWlnbm1lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZSgKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVOZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ZvcmVpZ25tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkTmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2UoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVOZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfZm9yZWlnbm1lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxOZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZSgKICAgICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiB2YWx1ZXMpIHsKICAgICAgICAgIGlmIChuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlTmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgICAgdmFsdWVzLCBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8pOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9mb3JlaWdubWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2UoKSB7CiAgICAgICAgICBpZiAobmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9mb3JlaWdubWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZU5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlKGludCBpbmRleCkgewogICAgICAgICAgaWYgKG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVOZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfZm9yZWlnbm1lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGdldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcigKICAgICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgICByZXR1cm4gZ2V0TmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfZm9yZWlnbm1lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZU9yQnVpbGRlcigKICAgICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgICBpZiAobmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZV8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9mb3JlaWdubWVzc2FnZSA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICAgICBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgICBpZiAobmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QobmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfZm9yZWlnbm1lc3NhZ2UgPSAyOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGFkZE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICAgIHJldHVybiBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ZvcmVpZ25tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBhZGROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgcmV0dXJuIGdldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ZvcmVpZ25tZXNzYWdlID0gMjs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlcj4gCiAgICAgICAgICAgICBnZXROZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJMaXN0KCkgewogICAgICAgICAgcmV0dXJuIGdldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICAgIGdldE5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgICAgaWYgKG5lc3RlZG1lc3NhZ2VSZXBlYXRlZEZvcmVpZ25tZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfLAogICAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApLAogICAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgICAgbmVzdGVkbWVzc2FnZVJlcGVhdGVkRm9yZWlnbm1lc3NhZ2VfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBuZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZUJ1aWxkZXJfOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE5lc3RlZE1lc3NhZ2U+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTmVzdGVkTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzKSBvYmo7CgogICAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIE5lZWRlZCBmb3IgYSBQeXRob24gdGVzdC4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0c30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0c09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRNZXNzYWdlSGFzQml0c19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBQcmltaXRpdmVGaWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcmltaXRpdmVGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUHJpbWl0aXZlRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgUHJpbWl0aXZlRmllbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHByaW1pdGl2ZUZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UHJpbWl0aXZlRmllbGQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBTdHJpbmdGaWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3RyaW5nRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIFN0cmluZ0ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmdGaWVsZC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHJpbmdGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgU3RyaW5nRmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHJpbmdGaWVsZC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyaW5nRmllbGRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIEVudW1GaWVsZCA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBlbnVtRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0VudW1GaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gRW51bUZpZWxkID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtRmllbGQuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0RW51bUZpZWxkKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1lc3NhZ2VGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTWVzc2FnZUZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBNZXNzYWdlRmllbGQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VGaWVsZC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRNZXNzYWdlRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDQ7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldE1lc3NhZ2VGaWVsZE9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIFN0cmluZ1BpZWNlRmllbGQgPSA1IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdQaWVjZUZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTdHJpbmdQaWVjZUZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBTdHJpbmdQaWVjZUZpZWxkID0gNSBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ1BpZWNlRmllbGQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nUGllY2VGaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgU3RyaW5nUGllY2VGaWVsZCA9IDUgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyaW5nUGllY2VGaWVsZC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyaW5nUGllY2VGaWVsZEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgQ29yZEZpZWxkID0gNiBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNvcmRGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQ29yZEZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBDb3JkRmllbGQgPSA2IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvcmRGaWVsZC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRDb3JkRmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIENvcmRGaWVsZCA9IDYgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGNvcmRGaWVsZC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0Q29yZEZpZWxkQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIFJlcGVhdGVkUHJpbWl0aXZlRmllbGQgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkUHJpbWl0aXZlRmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRSZXBlYXRlZFByaW1pdGl2ZUZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFByaW1pdGl2ZUZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRQcmltaXRpdmVGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIFJlcGVhdGVkUHJpbWl0aXZlRmllbGQgPSA3OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRQcmltaXRpdmVGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFByaW1pdGl2ZUZpZWxkKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRTdHJpbmdGaWVsZCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmdGaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0ZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRTdHJpbmdGaWVsZCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmdGaWVsZC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU3RyaW5nRmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRTdHJpbmdGaWVsZCA9IDg7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZ0ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZ0ZpZWxkKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ0ZpZWxkID0gODs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmdGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nRmllbGRCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIFJlcGVhdGVkRW51bUZpZWxkID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEVudW1GaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bT4gZ2V0UmVwZWF0ZWRFbnVtRmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBSZXBlYXRlZEVudW1GaWVsZCA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRFbnVtRmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEVudW1GaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBSZXBlYXRlZEVudW1GaWVsZCA9IDk7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEVudW1GaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0UmVwZWF0ZWRFbnVtRmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBSZXBlYXRlZE1lc3NhZ2VGaWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gCiAgICAgICAgZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBSZXBlYXRlZE1lc3NhZ2VGaWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZChpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgUmVwZWF0ZWRNZXNzYWdlRmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBSZXBlYXRlZE1lc3NhZ2VGaWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkTWVzc2FnZUZpZWxkT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgUmVwZWF0ZWRNZXNzYWdlRmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgPSAxMSBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgPSAxMSBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgPSAxMSBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZCA9IDExIFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZEJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRDb3JkRmllbGQgPSAxMiBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZENvcmRGaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZENvcmRGaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkQ29yZEZpZWxkID0gMTIgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRDb3JkRmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZENvcmRGaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZENvcmRGaWVsZCA9IDEyIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRDb3JkRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkQ29yZEZpZWxkKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZENvcmRGaWVsZCA9IDEyIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZENvcmRGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkQ29yZEZpZWxkQnl0ZXMoaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUZXN0IG1lc3NhZ2Ugd2l0aCBDYW1lbENhc2UgZmllbGQgbmFtZXMuICBUaGlzIHZpb2xhdGVzIFByb3RvY29sIEJ1ZmZlcgogICAqIHN0YW5kYXJkIHN0eWxlLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0Q2FtZWxDYXNlRmllbGROYW1lcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcykKICAgICAgVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RDYW1lbENhc2VGaWVsZE5hbWVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RDYW1lbENhc2VGaWVsZE5hbWVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXMoKSB7CiAgICAgIHN0cmluZ0ZpZWxkXyA9ICIiOwogICAgICBlbnVtRmllbGRfID0gNDsKICAgICAgc3RyaW5nUGllY2VGaWVsZF8gPSAiIjsKICAgICAgY29yZEZpZWxkXyA9ICIiOwogICAgICByZXBlYXRlZFByaW1pdGl2ZUZpZWxkXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZ0ZpZWxkXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkRW51bUZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRDb3JkRmllbGRfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0Q2FtZWxDYXNlRmllbGROYW1lcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDYW1lbENhc2VGaWVsZE5hbWVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQUklNSVRJVkVGSUVMRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgcHJpbWl0aXZlRmllbGRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgUHJpbWl0aXZlRmllbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcHJpbWl0aXZlRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNQcmltaXRpdmVGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBQcmltaXRpdmVGaWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcHJpbWl0aXZlRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UHJpbWl0aXZlRmllbGQoKSB7CiAgICAgIHJldHVybiBwcmltaXRpdmVGaWVsZF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HRklFTERfRklFTERfTlVNQkVSID0gMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cmluZ0ZpZWxkXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgU3RyaW5nRmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyaW5nRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHJpbmdGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgU3RyaW5nRmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ0ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHJpbmdGaWVsZCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJpbmdGaWVsZF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgc3RyaW5nRmllbGRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIFN0cmluZ0ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyaW5nRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHJpbmdGaWVsZEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cmluZ0ZpZWxkXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyaW5nRmllbGRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTUZJRUxEX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIGludCBlbnVtRmllbGRfID0gNDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIEVudW1GaWVsZCA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBlbnVtRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc0VudW1GaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gRW51bUZpZWxkID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0RW51bUZpZWxkKCkgewogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uZm9yTnVtYmVyKGVudW1GaWVsZF8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLkZPUkVJR05fRk9PIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1FU1NBR0VGSUVMRF9GSUVMRF9OVU1CRVIgPSA0OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIG1lc3NhZ2VGaWVsZF87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBNZXNzYWdlRmllbGQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZUZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTWVzc2FnZUZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBNZXNzYWdlRmllbGQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VGaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0TWVzc2FnZUZpZWxkKCkgewogICAgICByZXR1cm4gbWVzc2FnZUZpZWxkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1lc3NhZ2VGaWVsZF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBNZXNzYWdlRmllbGQgPSA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0TWVzc2FnZUZpZWxkT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gbWVzc2FnZUZpZWxkXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1lc3NhZ2VGaWVsZF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HUElFQ0VGSUVMRF9GSUVMRF9OVU1CRVIgPSA1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgc3RyaW5nUGllY2VGaWVsZF8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIFN0cmluZ1BpZWNlRmllbGQgPSA1IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdQaWVjZUZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyaW5nUGllY2VGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgU3RyaW5nUGllY2VGaWVsZCA9IDUgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmdQaWVjZUZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHJpbmdQaWVjZUZpZWxkKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cmluZ1BpZWNlRmllbGRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cmluZ1BpZWNlRmllbGRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIFN0cmluZ1BpZWNlRmllbGQgPSA1IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cmluZ1BpZWNlRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHJpbmdQaWVjZUZpZWxkQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nUGllY2VGaWVsZF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIHN0cmluZ1BpZWNlRmllbGRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09SREZJRUxEX0ZJRUxEX05VTUJFUiA9IDY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBjb3JkRmllbGRfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBDb3JkRmllbGQgPSA2IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY29yZEZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQ29yZEZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBDb3JkRmllbGQgPSA2IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvcmRGaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Q29yZEZpZWxkKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGNvcmRGaWVsZF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgY29yZEZpZWxkXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBDb3JkRmllbGQgPSA2IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBjb3JkRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRDb3JkRmllbGRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBjb3JkRmllbGRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBjb3JkRmllbGRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURQUklNSVRJVkVGSUVMRF9GSUVMRF9OVU1CRVIgPSA3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFByaW1pdGl2ZUZpZWxkXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIFJlcGVhdGVkUHJpbWl0aXZlRmllbGQgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkUHJpbWl0aXZlRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZFByaW1pdGl2ZUZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkUHJpbWl0aXZlRmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBSZXBlYXRlZFByaW1pdGl2ZUZpZWxkID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFByaW1pdGl2ZUZpZWxkLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkUHJpbWl0aXZlRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkUHJpbWl0aXZlRmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZCA9IDc7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFByaW1pdGl2ZUZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFByaW1pdGl2ZUZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRQcmltaXRpdmVGaWVsZF8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRFNUUklOR0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nRmllbGRfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ0ZpZWxkID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZ0ZpZWxkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0ZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nRmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRTdHJpbmdGaWVsZCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmdGaWVsZC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZ0ZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ0ZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ0ZpZWxkID0gODs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZ0ZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdGaWVsZF8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkU3RyaW5nRmllbGQgPSA4OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ0ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nRmllbGRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nRmllbGRfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVERU5VTUZJRUxEX0ZJRUxEX05VTUJFUiA9IDk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkRW51bUZpZWxkXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtPiByZXBlYXRlZEVudW1GaWVsZF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uRk9SRUlHTl9GT08gOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gUmVwZWF0ZWRFbnVtRmllbGQgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRW51bUZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bT4gZ2V0UmVwZWF0ZWRFbnVtRmllbGRMaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bT4ocmVwZWF0ZWRFbnVtRmllbGRfLCByZXBlYXRlZEVudW1GaWVsZF9jb252ZXJ0ZXJfKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIFJlcGVhdGVkRW51bUZpZWxkID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEVudW1GaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEVudW1GaWVsZENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRFbnVtRmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIFJlcGVhdGVkRW51bUZpZWxkID0gOTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRW51bUZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0UmVwZWF0ZWRFbnVtRmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEVudW1GaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRFbnVtRmllbGRfLmdldChpbmRleCkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVETUVTU0FHRUZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IHJlcGVhdGVkTWVzc2FnZUZpZWxkXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIFJlcGVhdGVkTWVzc2FnZUZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlRmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgUmVwZWF0ZWRNZXNzYWdlRmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlRmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgUmVwZWF0ZWRNZXNzYWdlRmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBSZXBlYXRlZE1lc3NhZ2VGaWVsZCA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VGaWVsZF8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIFJlcGVhdGVkTWVzc2FnZUZpZWxkID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZE9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUZpZWxkXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEU1RSSU5HUElFQ0VGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkXyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkID0gMTEgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkID0gMTEgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZCA9IDExIFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgPSAxMSBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEQ09SREZJRUxEX0ZJRUxEX05VTUJFUiA9IDEyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZENvcmRGaWVsZF8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkQ29yZEZpZWxkID0gMTIgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRDb3JkRmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkQ29yZEZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZEZpZWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkQ29yZEZpZWxkID0gMTIgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRDb3JkRmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRDb3JkRmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZEZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZENvcmRGaWVsZCA9IDEyIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRDb3JkRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZENvcmRGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZEZpZWxkXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRDb3JkRmllbGQgPSAxMiBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRDb3JkRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRDb3JkRmllbGRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZEZpZWxkXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIHByaW1pdGl2ZUZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyLCBzdHJpbmdGaWVsZF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMywgZW51bUZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg0LCBnZXRNZXNzYWdlRmllbGQoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA1LCBzdHJpbmdQaWVjZUZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA2LCBjb3JkRmllbGRfKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkUHJpbWl0aXZlRmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNywgcmVwZWF0ZWRQcmltaXRpdmVGaWVsZF8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nRmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA4LCByZXBlYXRlZFN0cmluZ0ZpZWxkXy5nZXRSYXcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRFbnVtRmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSg5LCByZXBlYXRlZEVudW1GaWVsZF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkTWVzc2FnZUZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTAsIHJlcGVhdGVkTWVzc2FnZUZpZWxkXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMTEsIHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZF8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQ29yZEZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMTIsIHJlcGVhdGVkQ29yZEZpZWxkXy5nZXRSYXcoaSkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIHByaW1pdGl2ZUZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyLCBzdHJpbmdGaWVsZF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSgzLCBlbnVtRmllbGRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoNCwgZ2V0TWVzc2FnZUZpZWxkKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoNSwgc3RyaW5nUGllY2VGaWVsZF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoNiwgY29yZEZpZWxkXyk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFByaW1pdGl2ZUZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKHJlcGVhdGVkUHJpbWl0aXZlRmllbGRfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRQcmltaXRpdmVGaWVsZExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZ0ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZ0ZpZWxkXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU3RyaW5nRmllbGRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRFbnVtRmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZEVudW1GaWVsZF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiByZXBlYXRlZEVudW1GaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRNZXNzYWdlRmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwLCByZXBlYXRlZE1lc3NhZ2VGaWVsZF8uZ2V0KGkpKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZENvcmRGaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRDb3JkRmllbGRfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRDb3JkRmllbGRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXMgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcykgb2JqOwoKICAgICAgaWYgKGhhc1ByaW1pdGl2ZUZpZWxkKCkgIT0gb3RoZXIuaGFzUHJpbWl0aXZlRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUHJpbWl0aXZlRmllbGQoKSkgewogICAgICAgIGlmIChnZXRQcmltaXRpdmVGaWVsZCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldFByaW1pdGl2ZUZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyaW5nRmllbGQoKSAhPSBvdGhlci5oYXNTdHJpbmdGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTdHJpbmdGaWVsZCgpKSB7CiAgICAgICAgaWYgKCFnZXRTdHJpbmdGaWVsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyaW5nRmllbGQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRW51bUZpZWxkKCkgIT0gb3RoZXIuaGFzRW51bUZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0VudW1GaWVsZCgpKSB7CiAgICAgICAgaWYgKGVudW1GaWVsZF8gIT0gb3RoZXIuZW51bUZpZWxkXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNNZXNzYWdlRmllbGQoKSAhPSBvdGhlci5oYXNNZXNzYWdlRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTWVzc2FnZUZpZWxkKCkpIHsKICAgICAgICBpZiAoIWdldE1lc3NhZ2VGaWVsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TWVzc2FnZUZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cmluZ1BpZWNlRmllbGQoKSAhPSBvdGhlci5oYXNTdHJpbmdQaWVjZUZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cmluZ1BpZWNlRmllbGQoKSkgewogICAgICAgIGlmICghZ2V0U3RyaW5nUGllY2VGaWVsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyaW5nUGllY2VGaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNDb3JkRmllbGQoKSAhPSBvdGhlci5oYXNDb3JkRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQ29yZEZpZWxkKCkpIHsKICAgICAgICBpZiAoIWdldENvcmRGaWVsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Q29yZEZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRSZXBlYXRlZFByaW1pdGl2ZUZpZWxkTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkUHJpbWl0aXZlRmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmdGaWVsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZ0ZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXJlcGVhdGVkRW51bUZpZWxkXy5lcXVhbHMob3RoZXIucmVwZWF0ZWRFbnVtRmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkTWVzc2FnZUZpZWxkTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkTWVzc2FnZUZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRDb3JkRmllbGRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRDb3JkRmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc1ByaW1pdGl2ZUZpZWxkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQUklNSVRJVkVGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UHJpbWl0aXZlRmllbGQoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyaW5nRmllbGQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHJpbmdGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0VudW1GaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRU5VTUZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBlbnVtRmllbGRfOwogICAgICB9CiAgICAgIGlmIChoYXNNZXNzYWdlRmllbGQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1FU1NBR0VGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TWVzc2FnZUZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyaW5nUGllY2VGaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSSU5HUElFQ0VGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyaW5nUGllY2VGaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0NvcmRGaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ09SREZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRDb3JkRmllbGQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFByaW1pdGl2ZUZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRFBSSU1JVElWRUZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFByaW1pdGl2ZUZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nRmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEU1RSSU5HRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nRmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRFbnVtRmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVERU5VTUZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXBlYXRlZEVudW1GaWVsZF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVETUVTU0FHRUZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEU1RSSU5HUElFQ0VGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQ29yZEZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRENPUkRGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRDb3JkRmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0IG1lc3NhZ2Ugd2l0aCBDYW1lbENhc2UgZmllbGQgbmFtZXMuICBUaGlzIHZpb2xhdGVzIFByb3RvY29sIEJ1ZmZlcgogICAgICogc3RhbmRhcmQgc3R5bGUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q2FtZWxDYXNlRmllbGROYW1lc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0TWVzc2FnZUZpZWxkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgcHJpbWl0aXZlRmllbGRfID0gMDsKICAgICAgICBzdHJpbmdGaWVsZF8gPSAiIjsKICAgICAgICBlbnVtRmllbGRfID0gNDsKICAgICAgICBtZXNzYWdlRmllbGRfID0gbnVsbDsKICAgICAgICBpZiAobWVzc2FnZUZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZUZpZWxkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgbWVzc2FnZUZpZWxkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBzdHJpbmdQaWVjZUZpZWxkXyA9ICIiOwogICAgICAgIGNvcmRGaWVsZF8gPSAiIjsKICAgICAgICByZXBlYXRlZFByaW1pdGl2ZUZpZWxkXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nRmllbGRfID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIHJlcGVhdGVkRW51bUZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VGaWVsZF8gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZENvcmRGaWVsZF8gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDYW1lbENhc2VGaWVsZE5hbWVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcyBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcyByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcyh0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIHJlc3VsdCkgewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRFbnVtRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRFbnVtRmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkRW51bUZpZWxkXyA9IHJlcGVhdGVkRW51bUZpZWxkXzsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRNZXNzYWdlRmllbGRfKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkTWVzc2FnZUZpZWxkXyA9IHJlcGVhdGVkTWVzc2FnZUZpZWxkXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkTWVzc2FnZUZpZWxkXyA9IHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucHJpbWl0aXZlRmllbGRfID0gcHJpbWl0aXZlRmllbGRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cmluZ0ZpZWxkXyA9IHN0cmluZ0ZpZWxkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5lbnVtRmllbGRfID0gZW51bUZpZWxkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5tZXNzYWdlRmllbGRfID0gbWVzc2FnZUZpZWxkQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gbWVzc2FnZUZpZWxkXwogICAgICAgICAgICAgIDogbWVzc2FnZUZpZWxkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHJpbmdQaWVjZUZpZWxkXyA9IHN0cmluZ1BpZWNlRmllbGRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNvcmRGaWVsZF8gPSBjb3JkRmllbGRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRQcmltaXRpdmVGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkUHJpbWl0aXZlRmllbGRfID0gcmVwZWF0ZWRQcmltaXRpdmVGaWVsZF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZ0ZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmdGaWVsZF8gPSByZXBlYXRlZFN0cmluZ0ZpZWxkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZF8gPSByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRDb3JkRmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZENvcmRGaWVsZF8gPSByZXBlYXRlZENvcmRGaWVsZF87CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc1ByaW1pdGl2ZUZpZWxkKCkpIHsKICAgICAgICAgIHNldFByaW1pdGl2ZUZpZWxkKG90aGVyLmdldFByaW1pdGl2ZUZpZWxkKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyaW5nRmllbGQoKSkgewogICAgICAgICAgc3RyaW5nRmllbGRfID0gb3RoZXIuc3RyaW5nRmllbGRfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNFbnVtRmllbGQoKSkgewogICAgICAgICAgc2V0RW51bUZpZWxkKG90aGVyLmdldEVudW1GaWVsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc01lc3NhZ2VGaWVsZCgpKSB7CiAgICAgICAgICBtZXJnZU1lc3NhZ2VGaWVsZChvdGhlci5nZXRNZXNzYWdlRmllbGQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdHJpbmdQaWVjZUZpZWxkKCkpIHsKICAgICAgICAgIHN0cmluZ1BpZWNlRmllbGRfID0gb3RoZXIuc3RyaW5nUGllY2VGaWVsZF87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0NvcmRGaWVsZCgpKSB7CiAgICAgICAgICBjb3JkRmllbGRfID0gb3RoZXIuY29yZEZpZWxkXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkUHJpbWl0aXZlRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkUHJpbWl0aXZlRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFByaW1pdGl2ZUZpZWxkXyA9IG90aGVyLnJlcGVhdGVkUHJpbWl0aXZlRmllbGRfOwogICAgICAgICAgICByZXBlYXRlZFByaW1pdGl2ZUZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUHJpbWl0aXZlRmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRQcmltaXRpdmVGaWVsZF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkUHJpbWl0aXZlRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU3RyaW5nRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFN0cmluZ0ZpZWxkXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nRmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nRmllbGRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZ0ZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEVudW1GaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRFbnVtRmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEVudW1GaWVsZF8gPSBvdGhlci5yZXBlYXRlZEVudW1GaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRW51bUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRW51bUZpZWxkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRFbnVtRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTWVzc2FnZUZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VGaWVsZF8gPSBvdGhlci5yZXBlYXRlZE1lc3NhZ2VGaWVsZF87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRfLmFkZEFsbChvdGhlci5yZXBlYXRlZE1lc3NhZ2VGaWVsZF8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkTWVzc2FnZUZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRfID0gb3RoZXIucmVwZWF0ZWRNZXNzYWdlRmllbGRfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkTWVzc2FnZUZpZWxkRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIucmVwZWF0ZWRNZXNzYWdlRmllbGRfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQ29yZEZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZENvcmRGaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQ29yZEZpZWxkXyA9IG90aGVyLnJlcGVhdGVkQ29yZEZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRDb3JkRmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRDb3JkRmllbGRfLmFkZEFsbChvdGhlci5yZXBlYXRlZENvcmRGaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgcHJpbWl0aXZlRmllbGRfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIHN0cmluZ0ZpZWxkXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMywgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVudW1GaWVsZF8gPSB0bXBSYXc7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE1lc3NhZ2VGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgICBjYXNlIDQyOiB7CiAgICAgICAgICAgICAgICBzdHJpbmdQaWVjZUZpZWxkXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgY29yZEZpZWxkXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA1NjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUHJpbWl0aXZlRmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkUHJpbWl0aXZlRmllbGRfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NgogICAgICAgICAgICAgIGNhc2UgNTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRQcmltaXRpdmVGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFByaW1pdGl2ZUZpZWxkXy5hZGRJbnQoaW5wdXQucmVhZEludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU4CiAgICAgICAgICAgICAgY2FzZSA2NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZ0ZpZWxkXy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY2CiAgICAgICAgICAgICAgY2FzZSA3MjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoOSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRW51bUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRW51bUZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MgogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoOSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEVudW1GaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRW51bUZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlRmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTAKICAgICAgICAgICAgICBjYXNlIDk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQ29yZEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZENvcmRGaWVsZF8uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5OAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBwcmltaXRpdmVGaWVsZF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgUHJpbWl0aXZlRmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwcmltaXRpdmVGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1ByaW1pdGl2ZUZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgUHJpbWl0aXZlRmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcHJpbWl0aXZlRmllbGQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0UHJpbWl0aXZlRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIHByaW1pdGl2ZUZpZWxkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgUHJpbWl0aXZlRmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwcmltaXRpdmVGaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFByaW1pdGl2ZUZpZWxkKGludCB2YWx1ZSkgewoKICAgICAgICBwcmltaXRpdmVGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIFByaW1pdGl2ZUZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUHJpbWl0aXZlRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHByaW1pdGl2ZUZpZWxkXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBzdHJpbmdGaWVsZF8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBTdHJpbmdGaWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cmluZ0ZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cmluZ0ZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIFN0cmluZ0ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ0ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nRmllbGQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJpbmdGaWVsZF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHJpbmdGaWVsZF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIFN0cmluZ0ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHJpbmdGaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFN0cmluZ0ZpZWxkQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJpbmdGaWVsZF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIHN0cmluZ0ZpZWxkXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBTdHJpbmdGaWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cmluZ0ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyaW5nRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHJpbmdGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBTdHJpbmdGaWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cmluZ0ZpZWxkKCkgewogICAgICAgIHN0cmluZ0ZpZWxkXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cmluZ0ZpZWxkKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgU3RyaW5nRmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igc3RyaW5nRmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHJpbmdGaWVsZEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHJpbmdGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGVudW1GaWVsZF8gPSA0OwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIEVudW1GaWVsZCA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGVudW1GaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc0VudW1GaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBFbnVtRmllbGQgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZW51bUZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBnZXRFbnVtRmllbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLmZvck51bWJlcihlbnVtRmllbGRfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLkZPUkVJR05fRk9PIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gRW51bUZpZWxkID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZW51bUZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RW51bUZpZWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBlbnVtRmllbGRfID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBFbnVtRmllbGQgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJFbnVtRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGVudW1GaWVsZF8gPSA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgbWVzc2FnZUZpZWxkXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiBtZXNzYWdlRmllbGRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBNZXNzYWdlRmllbGQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtZXNzYWdlRmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTWVzc2FnZUZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRNZXNzYWdlRmllbGQoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlRmllbGRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZUZpZWxkXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBNZXNzYWdlRmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE1lc3NhZ2VGaWVsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgbWVzc2FnZUZpZWxkXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNZXNzYWdlRmllbGQoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUZpZWxkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VNZXNzYWdlRmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChtZXNzYWdlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkgJiYKICAgICAgICAgICAgbWVzc2FnZUZpZWxkXyAhPSBudWxsICYmCiAgICAgICAgICAgIG1lc3NhZ2VGaWVsZF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRNZXNzYWdlRmllbGRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1lc3NhZ2VGaWVsZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUZpZWxkQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgTWVzc2FnZUZpZWxkID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgbWVzc2FnZUZpZWxkXyA9IG51bGw7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG1lc3NhZ2VGaWVsZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBNZXNzYWdlRmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgZ2V0TWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE1lc3NhZ2VGaWVsZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIE1lc3NhZ2VGaWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0TWVzc2FnZUZpZWxkT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChtZXNzYWdlRmllbGRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUZpZWxkXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbWVzc2FnZUZpZWxkXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBNZXNzYWdlRmllbGQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRNZXNzYWdlRmllbGRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZUZpZWxkKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBtZXNzYWdlRmllbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1lc3NhZ2VGaWVsZEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyaW5nUGllY2VGaWVsZF8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBTdHJpbmdQaWVjZUZpZWxkID0gNSBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdQaWVjZUZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cmluZ1BpZWNlRmllbGQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgU3RyaW5nUGllY2VGaWVsZCA9IDUgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ1BpZWNlRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHJpbmdQaWVjZUZpZWxkKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nUGllY2VGaWVsZF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHJpbmdQaWVjZUZpZWxkXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgU3RyaW5nUGllY2VGaWVsZCA9IDUgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHJpbmdQaWVjZUZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0U3RyaW5nUGllY2VGaWVsZEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nUGllY2VGaWVsZF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIHN0cmluZ1BpZWNlRmllbGRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIFN0cmluZ1BpZWNlRmllbGQgPSA1IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cmluZ1BpZWNlRmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHJpbmdQaWVjZUZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyaW5nUGllY2VGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBTdHJpbmdQaWVjZUZpZWxkID0gNSBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdHJpbmdQaWVjZUZpZWxkKCkgewogICAgICAgIHN0cmluZ1BpZWNlRmllbGRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0U3RyaW5nUGllY2VGaWVsZCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIFN0cmluZ1BpZWNlRmllbGQgPSA1IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBzdHJpbmdQaWVjZUZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyaW5nUGllY2VGaWVsZEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHJpbmdQaWVjZUZpZWxkXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGNvcmRGaWVsZF8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBDb3JkRmllbGQgPSA2IFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjb3JkRmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzQ29yZEZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIENvcmRGaWVsZCA9IDYgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3JkRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRDb3JkRmllbGQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBjb3JkRmllbGRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgY29yZEZpZWxkXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgQ29yZEZpZWxkID0gNiBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBjb3JkRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRDb3JkRmllbGRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGNvcmRGaWVsZF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGNvcmRGaWVsZF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgQ29yZEZpZWxkID0gNiBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgY29yZEZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Q29yZEZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY29yZEZpZWxkXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIENvcmRGaWVsZCA9IDYgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNvcmRGaWVsZCgpIHsKICAgICAgICBjb3JkRmllbGRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0Q29yZEZpZWxkKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgQ29yZEZpZWxkID0gNiBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGNvcmRGaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENvcmRGaWVsZEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjb3JkRmllbGRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZFByaW1pdGl2ZUZpZWxkXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRQcmltaXRpdmVGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkUHJpbWl0aXZlRmllbGRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFByaW1pdGl2ZUZpZWxkXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZFByaW1pdGl2ZUZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZCA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFByaW1pdGl2ZUZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRQcmltaXRpdmVGaWVsZExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRQcmltaXRpdmVGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFByaW1pdGl2ZUZpZWxkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZCA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFByaW1pdGl2ZUZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFByaW1pdGl2ZUZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkUHJpbWl0aXZlRmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZCA9IDc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRQcmltaXRpdmVGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkUHJpbWl0aXZlRmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkUHJpbWl0aXZlRmllbGRfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIFJlcGVhdGVkUHJpbWl0aXZlRmllbGQgPSA3OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkUHJpbWl0aXZlRmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFByaW1pdGl2ZUZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRQcmltaXRpdmVGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkUHJpbWl0aXZlRmllbGRfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgUmVwZWF0ZWRQcmltaXRpdmVGaWVsZCA9IDc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkUHJpbWl0aXZlRmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFByaW1pdGl2ZUZpZWxkKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFByaW1pdGl2ZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRQcmltaXRpdmVGaWVsZF8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIFJlcGVhdGVkUHJpbWl0aXZlRmllbGQgPSA3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRQcmltaXRpdmVGaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkUHJpbWl0aXZlRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFByaW1pdGl2ZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkUHJpbWl0aXZlRmllbGRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIFJlcGVhdGVkUHJpbWl0aXZlRmllbGQgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFByaW1pdGl2ZUZpZWxkKCkgewogICAgICAgIHJlcGVhdGVkUHJpbWl0aXZlRmllbGRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZ0ZpZWxkXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFN0cmluZ0ZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTdHJpbmdGaWVsZF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nRmllbGRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFN0cmluZ0ZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkU3RyaW5nRmllbGQgPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmdGaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdGaWVsZExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ0ZpZWxkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkU3RyaW5nRmllbGQgPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmdGaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdGaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ0ZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ0ZpZWxkID0gODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZ0ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nRmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nRmllbGRfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ0ZpZWxkID0gODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdGaWVsZEJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ0ZpZWxkXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkU3RyaW5nRmllbGQgPSA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nRmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFN0cmluZ0ZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdGaWVsZF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRTdHJpbmdGaWVsZCA9IDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nRmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZ0ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nRmllbGRfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRTdHJpbmdGaWVsZCA9IDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFN0cmluZ0ZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTdHJpbmdGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU3RyaW5nRmllbGRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ0ZpZWxkID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmdGaWVsZCgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ0ZpZWxkXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkU3RyaW5nRmllbGQgPSA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmdGaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nRmllbGRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nRmllbGRfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZEVudW1GaWVsZF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRW51bUZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRW51bUZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZEVudW1GaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIFJlcGVhdGVkRW51bUZpZWxkID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkRW51bUZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+IGdldFJlcGVhdGVkRW51bUZpZWxkTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtPihyZXBlYXRlZEVudW1GaWVsZF8sIHJlcGVhdGVkRW51bUZpZWxkX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gUmVwZWF0ZWRFbnVtRmllbGQgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRFbnVtRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRW51bUZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRW51bUZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBSZXBlYXRlZEVudW1GaWVsZCA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRFbnVtRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0UmVwZWF0ZWRFbnVtRmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRW51bUZpZWxkX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZEVudW1GaWVsZF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBSZXBlYXRlZEVudW1GaWVsZCA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRFbnVtRmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEVudW1GaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRFbnVtRmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEVudW1GaWVsZF8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBSZXBlYXRlZEVudW1GaWVsZCA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRW51bUZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRFbnVtRmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRFbnVtRmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEVudW1GaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIFJlcGVhdGVkRW51bUZpZWxkID0gOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRW51bUZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRFbnVtRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRW51bUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZEVudW1GaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBSZXBlYXRlZEVudW1GaWVsZCA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRW51bUZpZWxkKCkgewogICAgICAgIHJlcGVhdGVkRW51bUZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gcmVwZWF0ZWRNZXNzYWdlRmllbGRfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VGaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPihyZXBlYXRlZE1lc3NhZ2VGaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiByZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBSZXBlYXRlZE1lc3NhZ2VGaWVsZCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPiBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZExpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTWVzc2FnZUZpZWxkXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgUmVwZWF0ZWRNZXNzYWdlRmllbGQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTWVzc2FnZUZpZWxkQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUZpZWxkXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgUmVwZWF0ZWRNZXNzYWdlRmllbGQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRNZXNzYWdlRmllbGRfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIFJlcGVhdGVkTWVzc2FnZUZpZWxkID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRNZXNzYWdlRmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VGaWVsZF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgUmVwZWF0ZWRNZXNzYWdlRmllbGQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VGaWVsZF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgUmVwZWF0ZWRNZXNzYWdlRmllbGQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE1lc3NhZ2VGaWVsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBSZXBlYXRlZE1lc3NhZ2VGaWVsZCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTWVzc2FnZUZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZE1lc3NhZ2VGaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIFJlcGVhdGVkTWVzc2FnZUZpZWxkID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRNZXNzYWdlRmllbGQoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlRmllbGRJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUZpZWxkXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgUmVwZWF0ZWRNZXNzYWdlRmllbGQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE1lc3NhZ2VGaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTWVzc2FnZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VGaWVsZF8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgUmVwZWF0ZWRNZXNzYWdlRmllbGQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZE1lc3NhZ2VGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZT4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlRmllbGRJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkTWVzc2FnZUZpZWxkXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIFJlcGVhdGVkTWVzc2FnZUZpZWxkID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZE1lc3NhZ2VGaWVsZCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VGaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIFJlcGVhdGVkTWVzc2FnZUZpZWxkID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRNZXNzYWdlRmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRNZXNzYWdlRmllbGRJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUZpZWxkXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBSZXBlYXRlZE1lc3NhZ2VGaWVsZCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTWVzc2FnZUZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBSZXBlYXRlZE1lc3NhZ2VGaWVsZCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldFJlcGVhdGVkTWVzc2FnZUZpZWxkT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUZpZWxkXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIFJlcGVhdGVkTWVzc2FnZUZpZWxkID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZE9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTWVzc2FnZUZpZWxkXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgUmVwZWF0ZWRNZXNzYWdlRmllbGQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGFkZFJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIFJlcGVhdGVkTWVzc2FnZUZpZWxkID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBhZGRSZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRNZXNzYWdlRmllbGRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBSZXBlYXRlZE1lc3NhZ2VGaWVsZCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTWVzc2FnZUZpZWxkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZE1lc3NhZ2VGaWVsZEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRNZXNzYWdlRmllbGRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VGaWVsZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZE1lc3NhZ2VGaWVsZF8sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRNZXNzYWdlRmllbGRfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTWVzc2FnZUZpZWxkQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZCA9IDExIFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgPSAxMSBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgPSAxMSBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZF8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZCA9IDExIFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgPSAxMSBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgPSAxMSBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkID0gMTEgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTxqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkID0gMTEgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkKCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZFN0cmluZ1BpZWNlRmllbGQgPSAxMSBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nUGllY2VGaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkQ29yZEZpZWxkXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZENvcmRGaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQ29yZEZpZWxkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRDb3JkRmllbGRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZENvcmRGaWVsZF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZENvcmRGaWVsZCA9IDEyIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRDb3JkRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkQ29yZEZpZWxkTGlzdCgpIHsKICAgICAgICByZXBlYXRlZENvcmRGaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZENvcmRGaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZENvcmRGaWVsZCA9IDEyIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRDb3JkRmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQ29yZEZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQ29yZEZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZENvcmRGaWVsZCA9IDEyIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQ29yZEZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkQ29yZEZpZWxkKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZENvcmRGaWVsZF8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkQ29yZEZpZWxkID0gMTIgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZENvcmRGaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRSZXBlYXRlZENvcmRGaWVsZEJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZENvcmRGaWVsZF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBSZXBlYXRlZENvcmRGaWVsZCA9IDEyIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQ29yZEZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRDb3JkRmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQ29yZEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRDb3JkRmllbGRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkQ29yZEZpZWxkID0gMTIgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQ29yZEZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRDb3JkRmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZENvcmRGaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkQ29yZEZpZWxkXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIFJlcGVhdGVkQ29yZEZpZWxkID0gMTIgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZENvcmRGaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkQ29yZEZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkQ29yZEZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkQ29yZEZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRDb3JkRmllbGQgPSAxMiBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRDb3JkRmllbGQoKSB7CiAgICAgICAgcmVwZWF0ZWRDb3JkRmllbGRfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgUmVwZWF0ZWRDb3JkRmllbGQgPSAxMiBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkQ29yZEZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRDb3JkRmllbGRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRDb3JkRmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZENvcmRGaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdENhbWVsQ2FzZUZpZWxkTmFtZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q2FtZWxDYXNlRmllbGROYW1lcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdENhbWVsQ2FzZUZpZWxkTmFtZXM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdENhbWVsQ2FzZUZpZWxkTmFtZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0Q2FtZWxDYXNlRmllbGROYW1lcyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RDYW1lbENhc2VGaWVsZE5hbWVzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RDYW1lbENhc2VGaWVsZE5hbWVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDYW1lbENhc2VGaWVsZE5hbWVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEZpZWxkT3JkZXJpbmdzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxUZXN0RmllbGRPcmRlcmluZ3M+IHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG15U3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNNeVN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbXlTdHJpbmcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TXlTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBteVN0cmluZy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TXlTdHJpbmdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgbXlfaW50ID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG15SW50IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNNeUludCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBteV9pbnQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG15SW50LgogICAgICovCiAgICBsb25nIGdldE15SW50KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBteV9mbG9hdCA9IDEwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG15RmxvYXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc015RmxvYXQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbXlfZmxvYXQgPSAxMDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbXlGbG9hdC4KICAgICAqLwogICAgZmxvYXQgZ2V0TXlGbG9hdCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMjAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMjAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZS4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMjAwOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBXZSBsaXN0IGZpZWxkcyBvdXQgb2Ygb3JkZXIsIHRvIGVuc3VyZSB0aGF0IHdlJ3JlIHVzaW5nIGZpZWxkIG51bWJlciBhbmQgbm90CiAgICogZmllbGQgaW5kZXggdG8gZGV0ZXJtaW5lIHNlcmlhbGl6YXRpb24gb3JkZXIuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3N9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0RmllbGRPcmRlcmluZ3MgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgICBUZXN0RmllbGRPcmRlcmluZ3M+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MpCiAgICAgIFRlc3RGaWVsZE9yZGVyaW5nc09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdEZpZWxkT3JkZXJpbmdzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RGaWVsZE9yZGVyaW5ncyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncywgPz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdEZpZWxkT3JkZXJpbmdzKCkgewogICAgICBteVN0cmluZ18gPSAiIjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0RmllbGRPcmRlcmluZ3MoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RmllbGRPcmRlcmluZ3NfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RmllbGRPcmRlcmluZ3NfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvbyA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9vIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzT28oKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9vID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9vLgogICAgICAgKi8KICAgICAgbG9uZyBnZXRPbygpOwoKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAqIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCiAgICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc0JiKCk7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJiLgogICAgICAgKi8KICAgICAgaW50IGdldEJiKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZE1lc3NhZ2UgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlKQogICAgICAgIE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBOZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgTmVzdGVkTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgTmVzdGVkTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZpZWxkT3JkZXJpbmdzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZpZWxkT3JkZXJpbmdzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT09fRklFTERfTlVNQkVSID0gMjsKICAgICAgcHJpdmF0ZSBsb25nIG9vXyA9IDBMOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb28gPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09vKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb28gPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb28uCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9vKCkgewogICAgICAgIHJldHVybiBvb187CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJCX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgaW50IGJiXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICAgKiBhIGxvY2FsIHZhcmlhYmxlIG5hbWVkICJiIiBpbiBvbmUgb2YgdGhlIGdlbmVyYXRlZCBtZXRob2RzLiAgRG9oLgogICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNCYigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAqIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCiAgICAgICAqIFRoaXMgZmlsZSBuZWVkcyB0byBjb21waWxlIGluIHByb3RvMSB0byB0ZXN0IGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5LgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmIgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYmIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0QmIoKSB7CiAgICAgICAgcmV0dXJuIGJiXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGJiXyk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMiwgb29fKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgYmJfKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemUoMiwgb29fKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICAgIGlmIChoYXNPbygpICE9IG90aGVyLmhhc09vKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzT28oKSkgewogICAgICAgICAgaWYgKGdldE9vKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRPbygpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmIChoYXNCYigpICE9IG90aGVyLmhhc0JiKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzQmIoKSkgewogICAgICAgICAgaWYgKGdldEJiKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRCYigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzT28oKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT09fRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgICBnZXRPbygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc0JiKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEJCX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEJiKCk7CiAgICAgICAgfQogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2V9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlKQogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RmllbGRPcmRlcmluZ3NfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZpZWxkT3JkZXJpbmdzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIG9vXyA9IDBMOwogICAgICAgICAgYmJfID0gMDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZpZWxkT3JkZXJpbmdzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5vb18gPSBvb187CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5iYl8gPSBiYl87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2Upb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc09vKCkpIHsKICAgICAgICAgICAgc2V0T28ob3RoZXIuZ2V0T28oKSk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAob3RoZXIuaGFzQmIoKSkgewogICAgICAgICAgICBzZXRCYihvdGhlci5nZXRCYigpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgICBiYl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICAgIG9vXyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGxvbmcgb29fIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvbyA9IDI7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb28gZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbygpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb28gPSAyOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBvby4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGxvbmcgZ2V0T28oKSB7CiAgICAgICAgICByZXR1cm4gb29fOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvbyA9IDI7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb28gdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbyhsb25nIHZhbHVlKSB7CgogICAgICAgICAgb29fID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvbyA9IDI7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9vKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgb29fID0gMEw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBpbnQgYmJfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYiBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0JiKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgYmIuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0QmIoKSB7CiAgICAgICAgICByZXR1cm4gYmJfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8cHJlPgogICAgICAgICAqIFRoZSBmaWVsZCBuYW1lICJiIiBmYWlscyB0byBjb21waWxlIGluIHByb3RvMSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoCiAgICAgICAgICogYSBsb2NhbCB2YXJpYWJsZSBuYW1lZCAiYiIgaW4gb25lIG9mIHRoZSBnZW5lcmF0ZWQgbWV0aG9kcy4gIERvaC4KICAgICAgICAgKiBUaGlzIGZpbGUgbmVlZHMgdG8gY29tcGlsZSBpbiBwcm90bzEgdG8gdGVzdCBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICAgICAgICAgKiA8L3ByZT4KICAgICAgICAgKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJiID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBiYiB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJiKGludCB2YWx1ZSkgewoKICAgICAgICAgIGJiXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPHByZT4KICAgICAgICAgKiBUaGUgZmllbGQgbmFtZSAiYiIgZmFpbHMgdG8gY29tcGlsZSBpbiBwcm90bzEgYmVjYXVzZSBpdCBjb25mbGljdHMgd2l0aAogICAgICAgICAqIGEgbG9jYWwgdmFyaWFibGUgbmFtZWQgImIiIGluIG9uZSBvZiB0aGUgZ2VuZXJhdGVkIG1ldGhvZHMuICBEb2guCiAgICAgICAgICogVGhpcyBmaWxlIG5lZWRzIHRvIGNvbXBpbGUgaW4gcHJvdG8xIHRvIHRlc3QgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkuCiAgICAgICAgICogPC9wcmU+CiAgICAgICAgICoKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYiA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJiKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgYmJfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkTWVzc2FnZT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBOZXN0ZWRNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNWV9TVFJJTkdfRklFTERfTlVNQkVSID0gMTE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBteVN0cmluZ18gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbXlTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNNeVN0cmluZygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbXlTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE15U3RyaW5nKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG15U3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBteVN0cmluZ18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG15U3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TXlTdHJpbmdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBteVN0cmluZ187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIG15U3RyaW5nXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1ZX0lOVF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBsb25nIG15SW50XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBteV9pbnQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbXlJbnQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNNeUludCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBteV9pbnQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG15SW50LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRNeUludCgpIHsKICAgICAgcmV0dXJuIG15SW50XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNWV9GTE9BVF9GSUVMRF9OVU1CRVIgPSAxMDE7CiAgICBwcml2YXRlIGZsb2F0IG15RmxvYXRfID0gMEY7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG15X2Zsb2F0ID0gMTAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbXlGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc015RmxvYXQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbXlfZmxvYXQgPSAxMDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbXlGbG9hdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldE15RmxvYXQoKSB7CiAgICAgIHJldHVybiBteUZsb2F0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9ORVNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAyMDA7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMjAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDIwMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAyMDA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5FeHRlbmRhYmxlTWVzc2FnZTxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncz4uRXh0ZW5zaW9uV3JpdGVyCiAgICAgICAgICBleHRlbnNpb25Xcml0ZXIgPSBuZXdFeHRlbnNpb25Xcml0ZXIoKTsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMSwgbXlJbnRfKTsKICAgICAgfQogICAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCgxMSwgb3V0cHV0KTsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMSwgbXlTdHJpbmdfKTsKICAgICAgfQogICAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCgxMDEsIG91dHB1dCk7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0KDEwMSwgbXlGbG9hdF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMjAwLCBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemUoMSwgbXlJbnRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDExLCBteVN0cmluZ18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGbG9hdFNpemUoMTAxLCBteUZsb2F0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwMCwgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplKCk7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncyBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncykgb2JqOwoKICAgICAgaWYgKGhhc015U3RyaW5nKCkgIT0gb3RoZXIuaGFzTXlTdHJpbmcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTXlTdHJpbmcoKSkgewogICAgICAgIGlmICghZ2V0TXlTdHJpbmcoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE15U3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc015SW50KCkgIT0gb3RoZXIuaGFzTXlJbnQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTXlJbnQoKSkgewogICAgICAgIGlmIChnZXRNeUludCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE15SW50KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzTXlGbG9hdCgpICE9IG90aGVyLmhhc015RmxvYXQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTXlGbG9hdCgpKSB7CiAgICAgICAgaWYgKGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhnZXRNeUZsb2F0KCkpCiAgICAgICAgICAgICE9IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgICAgIG90aGVyLmdldE15RmxvYXQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RXh0ZW5zaW9uRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldEV4dGVuc2lvbkZpZWxkcygpKSkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc015U3RyaW5nKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNWV9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE15U3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzTXlJbnQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1ZX0lOVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0TXlJbnQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc015RmxvYXQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1ZX0ZMT0FUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgIGdldE15RmxvYXQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfTkVTVEVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9IGhhc2hGaWVsZHMoaGFzaCwgZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogV2UgbGlzdCBmaWVsZHMgb3V0IG9mIG9yZGVyLCB0byBlbnN1cmUgdGhhdCB3ZSdyZSB1c2luZyBmaWVsZCBudW1iZXIgYW5kIG5vdAogICAgICogZmllbGQgaW5kZXggdG8gZGV0ZXJtaW5lIHNlcmlhbGl6YXRpb24gb3JkZXIuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3N9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncywgQnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEZpZWxkT3JkZXJpbmdzKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RGaWVsZE9yZGVyaW5nc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RmllbGRPcmRlcmluZ3NfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBteVN0cmluZ18gPSAiIjsKICAgICAgICBteUludF8gPSAwTDsKICAgICAgICBteUZsb2F0XyA9IDBGOwogICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RmllbGRPcmRlcmluZ3NfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5teVN0cmluZ18gPSBteVN0cmluZ187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubXlJbnRfID0gbXlJbnRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm15RmxvYXRfID0gbXlGbG9hdF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLCBUeXBlPiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgaW50IGluZGV4LCBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgYWRkRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncywgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncywgVD4gZXh0ZW5zaW9uKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRXh0ZW5zaW9uKGV4dGVuc2lvbik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzTXlTdHJpbmcoKSkgewogICAgICAgICAgbXlTdHJpbmdfID0gb3RoZXIubXlTdHJpbmdfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNNeUludCgpKSB7CiAgICAgICAgICBzZXRNeUludChvdGhlci5nZXRNeUludCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc015RmxvYXQoKSkgewogICAgICAgICAgc2V0TXlGbG9hdChvdGhlci5nZXRNeUZsb2F0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxOZXN0ZWRNZXNzYWdlKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIG15SW50XyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDkwOiB7CiAgICAgICAgICAgICAgICBteVN0cmluZ18gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICAgIGNhc2UgODEzOiB7CiAgICAgICAgICAgICAgICBteUZsb2F0XyA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxMwogICAgICAgICAgICAgIGNhc2UgMTYwMjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjAyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBteVN0cmluZ18gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbXlTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTXlTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBteVN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE15U3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbXlTdHJpbmdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbXlTdHJpbmdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBteVN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE15U3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBteVN0cmluZ187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIG15U3RyaW5nXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbXlTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNeVN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG15U3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNeVN0cmluZygpIHsKICAgICAgICBteVN0cmluZ18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRNeVN0cmluZygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDExOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbXlTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNeVN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBteVN0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBteUludF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgbXlfaW50ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbXlJbnQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNeUludCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG15X2ludCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBteUludC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0TXlJbnQoKSB7CiAgICAgICAgcmV0dXJuIG15SW50XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgbXlfaW50ID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbXlJbnQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNeUludChsb25nIHZhbHVlKSB7CgogICAgICAgIG15SW50XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgbXlfaW50ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTXlJbnQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG15SW50XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IG15RmxvYXRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG15X2Zsb2F0ID0gMTAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBteUZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzTXlGbG9hdCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG15X2Zsb2F0ID0gMTAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbXlGbG9hdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldE15RmxvYXQoKSB7CiAgICAgICAgcmV0dXJuIG15RmxvYXRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBteV9mbG9hdCA9IDEwMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbXlGbG9hdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE15RmxvYXQoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgbXlGbG9hdF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG15X2Zsb2F0ID0gMTAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNeUZsb2F0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBteUZsb2F0XyA9IDBGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDIwMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDIwMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkTWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2Ugb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UgPSAyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTmVzdGVkTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSBvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZSA9IDIwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlIG9wdGlvbmFsX25lc3RlZF9tZXNzYWdlID0gMjAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncy5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRNZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEZpZWxkT3JkZXJpbmdzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEZpZWxkT3JkZXJpbmdzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RGaWVsZE9yZGVyaW5ncz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RGaWVsZE9yZGVyaW5ncyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RGaWVsZE9yZGVyaW5ncz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RmllbGRPcmRlcmluZ3M+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEV4dGVuc2lvbk9yZGVyaW5nczFPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG15U3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNNeVN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBteVN0cmluZy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRNeVN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbXlTdHJpbmcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE15U3RyaW5nQnl0ZXMoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczF9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMSkKICAgICAgVGVzdEV4dGVuc2lvbk9yZGVyaW5nczFPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RFeHRlbnNpb25PcmRlcmluZ3MxLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RFeHRlbnNpb25PcmRlcmluZ3MxKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEoKSB7CiAgICAgIG15U3RyaW5nXyA9ICIiOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RFeHRlbnNpb25PcmRlcmluZ3MxKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczFfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1ZX1NUUklOR19GSUVMRF9OVU1CRVIgPSAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbXlTdHJpbmdfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbXlTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNNeVN0cmluZygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBteVN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TXlTdHJpbmcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbXlTdHJpbmdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIG15U3RyaW5nXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBteVN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE15U3RyaW5nQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbXlTdHJpbmdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBteVN0cmluZ18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMSwgbXlTdHJpbmdfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxLCBteVN0cmluZ18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMSkgb2JqOwoKICAgICAgaWYgKGhhc015U3RyaW5nKCkgIT0gb3RoZXIuaGFzTXlTdHJpbmcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTXlTdHJpbmcoKSkgewogICAgICAgIGlmICghZ2V0TXlTdHJpbmcoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE15U3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzTXlTdHJpbmcoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1ZX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TXlTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczF9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25PcmRlcmluZ3MxX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25PcmRlcmluZ3MxX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBteVN0cmluZ18gPSAiIjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczFfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubXlTdHJpbmdfID0gbXlTdHJpbmdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNNeVN0cmluZygpKSB7CiAgICAgICAgICBteVN0cmluZ18gPSBvdGhlci5teVN0cmluZ187CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgbXlTdHJpbmdfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG15U3RyaW5nXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG15U3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc015U3RyaW5nKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBteVN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE15U3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbXlTdHJpbmdfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgbXlTdHJpbmdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG15U3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TXlTdHJpbmdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG15U3RyaW5nXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbXlTdHJpbmdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG15U3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TXlTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBteVN0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNeVN0cmluZygpIHsKICAgICAgICBteVN0cmluZ18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRNeVN0cmluZygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBteVN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE15U3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG15U3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RFeHRlbnNpb25PcmRlcmluZ3MxIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEV4dGVuc2lvbk9yZGVyaW5nczE+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEV4dGVuc2lvbk9yZGVyaW5nczE+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczEgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEVTVF9FWFRfT1JERVJJTkdTMV9GSUVMRF9OVU1CRVIgPSAxMzsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEZpZWxkT3JkZXJpbmdzLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczE+IHRlc3RFeHRPcmRlcmluZ3MxID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMS5nZXREZWZhdWx0SW5zdGFuY2UoKSwKICAgICAgICAgIDAsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MxLmNsYXNzLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RFeHRlbnNpb25PcmRlcmluZ3MyT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBteVN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTXlTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbXlTdHJpbmcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0TXlTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG15U3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRNeVN0cmluZ0J5dGVzKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIpCiAgICAgIFRlc3RFeHRlbnNpb25PcmRlcmluZ3MyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RFeHRlbnNpb25PcmRlcmluZ3MyKCkgewogICAgICBteVN0cmluZ18gPSAiIjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25PcmRlcmluZ3MyX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEV4dGVuc2lvbk9yZGVyaW5nczNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMykKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBteVN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc015U3RyaW5nKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG15U3RyaW5nLgogICAgICAgKi8KICAgICAgamF2YS5sYW5nLlN0cmluZyBnZXRNeVN0cmluZygpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbXlTdHJpbmcuCiAgICAgICAqLwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE15U3RyaW5nQnl0ZXMoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzKQogICAgICAgIFRlc3RFeHRlbnNpb25PcmRlcmluZ3MzT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBUZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIFRlc3RFeHRlbnNpb25PcmRlcmluZ3MzKCkgewogICAgICAgIG15U3RyaW5nXyA9ICIiOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IFRlc3RFeHRlbnNpb25PcmRlcmluZ3MzKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMl9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzM19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMl9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzM19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNWV9TVFJJTkdfRklFTERfTlVNQkVSID0gMTsKICAgICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBteVN0cmluZ18gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBteVN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc015U3RyaW5nKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBteVN0cmluZy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TXlTdHJpbmcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBteVN0cmluZ187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIG15U3RyaW5nXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG15U3RyaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRNeVN0cmluZ0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbXlTdHJpbmdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbXlTdHJpbmdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMSwgbXlTdHJpbmdfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDEsIG15U3RyaW5nXyk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMpKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMykgb2JqOwoKICAgICAgICBpZiAoaGFzTXlTdHJpbmcoKSAhPSBvdGhlci5oYXNNeVN0cmluZygpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc015U3RyaW5nKCkpIHsKICAgICAgICAgIGlmICghZ2V0TXlTdHJpbmcoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TXlTdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNNeVN0cmluZygpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNWV9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TXlTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMyBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMyBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMykKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczNPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczJfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczNfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25PcmRlcmluZ3MyX1Rlc3RFeHRlbnNpb25PcmRlcmluZ3MzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBteVN0cmluZ18gPSAiIjsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczJfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczNfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczModGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5teVN0cmluZ18gPSBteVN0cmluZ187CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMpb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMyBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc015U3RyaW5nKCkpIHsKICAgICAgICAgICAgbXlTdHJpbmdfID0gb3RoZXIubXlTdHJpbmdfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgICBteVN0cmluZ18gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG15U3RyaW5nXyA9ICIiOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG15U3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNeVN0cmluZygpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIG15U3RyaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE15U3RyaW5nKCkgewogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBteVN0cmluZ187CiAgICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgICBteVN0cmluZ18gPSBzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbXlTdHJpbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgICBnZXRNeVN0cmluZ0J5dGVzKCkgewogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBteVN0cmluZ187CiAgICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgICBteVN0cmluZ18gPSBiOwogICAgICAgICAgICByZXR1cm4gYjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG15U3RyaW5nIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TXlTdHJpbmcoCiAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgICBteVN0cmluZ18gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNeVN0cmluZygpIHsKICAgICAgICAgIG15U3RyaW5nXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldE15U3RyaW5nKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbXlTdHJpbmcgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRNeVN0cmluZ0J5dGVzKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgICBteVN0cmluZ18gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMykKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMyBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMygpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMz4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RFeHRlbnNpb25PcmRlcmluZ3MzPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIFRlc3RFeHRlbnNpb25PcmRlcmluZ3MzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEV4dGVuc2lvbk9yZGVyaW5nczM+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRFU1RfRVhUX09SREVSSU5HUzNfRklFTERfTlVNQkVSID0gMTQ7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncyB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncywKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczM+IHRlc3RFeHRPcmRlcmluZ3MzID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAgIDAsCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMuY2xhc3MsCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNWV9TVFJJTkdfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IG15U3RyaW5nXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG15U3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTXlTdHJpbmcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG15X3N0cmluZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbXlTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE15U3RyaW5nKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG15U3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBteVN0cmluZ18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgbXlTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRNeVN0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG15U3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgbXlTdHJpbmdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEsIG15U3RyaW5nXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMSwgbXlTdHJpbmdfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIpIG9iajsKCiAgICAgIGlmIChoYXNNeVN0cmluZygpICE9IG90aGVyLmhhc015U3RyaW5nKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc015U3RyaW5nKCkpIHsKICAgICAgICBpZiAoIWdldE15U3RyaW5nKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRNeVN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc015U3RyaW5nKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNWV9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE15U3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMiBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgbXlTdHJpbmdfID0gIiI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25PcmRlcmluZ3MyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMiBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMiBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm15U3RyaW5nXyA9IG15U3RyaW5nXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMiBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzTXlTdHJpbmcoKSkgewogICAgICAgICAgbXlTdHJpbmdfID0gb3RoZXIubXlTdHJpbmdfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIG15U3RyaW5nXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBteVN0cmluZ18gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBteVN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNeVN0cmluZygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbXlTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRNeVN0cmluZygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG15U3RyaW5nXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIG15U3RyaW5nXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBteVN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE15U3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBteVN0cmluZ187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIG15U3RyaW5nXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBteVN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE15U3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgbXlTdHJpbmdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbXlfc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTXlTdHJpbmcoKSB7CiAgICAgICAgbXlTdHJpbmdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TXlTdHJpbmcoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBteV9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgbXlTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNeVN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBteVN0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMiBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEV4dGVuc2lvbk9yZGVyaW5nczI+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEV4dGVuc2lvbk9yZGVyaW5nczI+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFeHRlbnNpb25PcmRlcmluZ3MyPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFeHRlbnNpb25PcmRlcmluZ3MyPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFRFU1RfRVhUX09SREVSSU5HUzJfRklFTERfTlVNQkVSID0gMTI7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEZpZWxkT3JkZXJpbmdzIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25PcmRlcmluZ3MyPiB0ZXN0RXh0T3JkZXJpbmdzMiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAwLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5jbGFzcywKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbk9yZGVyaW5nczIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZXNjYXBlZF9ieXRlcyA9IDEgW2RlZmF1bHQgPSAiJiM5MjswMDAmIzkyOzAwMSYjOTI7MDA3JiM5MjswMTAmIzkyOzAxNCYjOTI7biYjOTI7ciYjOTI7dCYjOTI7MDEzJiM5MjsmIzkyOyYjOTI7JyYjOTI7IiYjOTI7Mzc2Il07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBlc2NhcGVkQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0VzY2FwZWRCeXRlcygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBlc2NhcGVkX2J5dGVzID0gMSBbZGVmYXVsdCA9ICImIzkyOzAwMCYjOTI7MDAxJiM5MjswMDcmIzkyOzAxMCYjOTI7MDE0JiM5MjtuJiM5MjtyJiM5Mjt0JiM5MjswMTMmIzkyOyYjOTI7JiM5MjsnJiM5MjsiJiM5MjszNzYiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlc2NhcGVkQnl0ZXMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRFc2NhcGVkQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBsYXJnZV91aW50MzIgPSAyIFtkZWZhdWx0ID0gNDI5NDk2NzI5NV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsYXJnZVVpbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTGFyZ2VVaW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIGxhcmdlX3VpbnQzMiA9IDIgW2RlZmF1bHQgPSA0Mjk0OTY3Mjk1XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsYXJnZVVpbnQzMi4KICAgICAqLwogICAgaW50IGdldExhcmdlVWludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgbGFyZ2VfdWludDY0ID0gMyBbZGVmYXVsdCA9IDE4NDQ2NzQ0MDczNzA5NTUxNjE1XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxhcmdlVWludDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNMYXJnZVVpbnQ2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgbGFyZ2VfdWludDY0ID0gMyBbZGVmYXVsdCA9IDE4NDQ2NzQ0MDczNzA5NTUxNjE1XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsYXJnZVVpbnQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRMYXJnZVVpbnQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgc21hbGxfaW50MzIgPSA0IFtkZWZhdWx0ID0gLTIxNDc0ODM2NDddOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc21hbGxJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU21hbGxJbnQzMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBzbWFsbF9pbnQzMiA9IDQgW2RlZmF1bHQgPSAtMjE0NzQ4MzY0N107PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc21hbGxJbnQzMi4KICAgICAqLwogICAgaW50IGdldFNtYWxsSW50MzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IHNtYWxsX2ludDY0ID0gNSBbZGVmYXVsdCA9IC05MjIzMzcyMDM2ODU0Nzc1ODA3XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNtYWxsSW50NjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1NtYWxsSW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgc21hbGxfaW50NjQgPSA1IFtkZWZhdWx0ID0gLTkyMjMzNzIwMzY4NTQ3NzU4MDddOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHNtYWxsSW50NjQuCiAgICAgKi8KICAgIGxvbmcgZ2V0U21hbGxJbnQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgcmVhbGx5X3NtYWxsX2ludDMyID0gMjEgW2RlZmF1bHQgPSAtMjE0NzQ4MzY0OF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZWFsbHlTbWFsbEludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNSZWFsbHlTbWFsbEludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHJlYWxseV9zbWFsbF9pbnQzMiA9IDIxIFtkZWZhdWx0ID0gLTIxNDc0ODM2NDhdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlYWxseVNtYWxsSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRSZWFsbHlTbWFsbEludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCByZWFsbHlfc21hbGxfaW50NjQgPSAyMiBbZGVmYXVsdCA9IC05MjIzMzcyMDM2ODU0Nzc1ODA4XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlYWxseVNtYWxsSW50NjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1JlYWxseVNtYWxsSW50NjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgcmVhbGx5X3NtYWxsX2ludDY0ID0gMjIgW2RlZmF1bHQgPSAtOTIyMzM3MjAzNjg1NDc3NTgwOF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVhbGx5U21hbGxJbnQ2NC4KICAgICAqLwogICAgbG9uZyBnZXRSZWFsbHlTbWFsbEludDY0KCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlIGRlZmF1bHQgdmFsdWUgaGVyZSBpcyBVVEYtOCBmb3IgIiYjOTI7dTEyMzQiLiAgKFdlIGNvdWxkIGFsc28ganVzdCB0eXBlCiAgICAgKiB0aGUgVVRGLTggdGV4dCBkaXJlY3RseSBpbnRvIHRoaXMgdGV4dCBmaWxlIHJhdGhlciB0aGFuIGVzY2FwZSBpdCwgYnV0CiAgICAgKiBsb3RzIG9mIHBlb3BsZSB1c2UgZWRpdG9ycyB0aGF0IHdvdWxkIGJlIGNvbmZ1c2VkIGJ5IHRoaXMuKQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHV0Zjhfc3RyaW5nID0gNiBbZGVmYXVsdCA9ICImIzkyOzM0MSYjOTI7MjEwJiM5MjsyNjQiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHV0ZjhTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1V0ZjhTdHJpbmcoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlIGhlcmUgaXMgVVRGLTggZm9yICImIzkyO3UxMjM0Ii4gIChXZSBjb3VsZCBhbHNvIGp1c3QgdHlwZQogICAgICogdGhlIFVURi04IHRleHQgZGlyZWN0bHkgaW50byB0aGlzIHRleHQgZmlsZSByYXRoZXIgdGhhbiBlc2NhcGUgaXQsIGJ1dAogICAgICogbG90cyBvZiBwZW9wbGUgdXNlIGVkaXRvcnMgdGhhdCB3b3VsZCBiZSBjb25mdXNlZCBieSB0aGlzLikKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyB1dGY4X3N0cmluZyA9IDYgW2RlZmF1bHQgPSAiJiM5MjszNDEmIzkyOzIxMCYjOTI7MjY0Il07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdXRmOFN0cmluZy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRVdGY4U3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBoZXJlIGlzIFVURi04IGZvciAiJiM5Mjt1MTIzNCIuICAoV2UgY291bGQgYWxzbyBqdXN0IHR5cGUKICAgICAqIHRoZSBVVEYtOCB0ZXh0IGRpcmVjdGx5IGludG8gdGhpcyB0ZXh0IGZpbGUgcmF0aGVyIHRoYW4gZXNjYXBlIGl0LCBidXQKICAgICAqIGxvdHMgb2YgcGVvcGxlIHVzZSBlZGl0b3JzIHRoYXQgd291bGQgYmUgY29uZnVzZWQgYnkgdGhpcy4pCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgdXRmOF9zdHJpbmcgPSA2IFtkZWZhdWx0ID0gIiYjOTI7MzQxJiM5MjsyMTAmIzkyOzI2NCJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciB1dGY4U3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRVdGY4U3RyaW5nQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0cyBmb3Igc2luZ2xlLXByZWNpc2lvbiBmbG9hdGluZy1wb2ludCB2YWx1ZXMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCB6ZXJvX2Zsb2F0ID0gNyBbZGVmYXVsdCA9IDBdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgemVyb0Zsb2F0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNaZXJvRmxvYXQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRlc3RzIGZvciBzaW5nbGUtcHJlY2lzaW9uIGZsb2F0aW5nLXBvaW50IHZhbHVlcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHplcm9fZmxvYXQgPSA3IFtkZWZhdWx0ID0gMF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgemVyb0Zsb2F0LgogICAgICovCiAgICBmbG9hdCBnZXRaZXJvRmxvYXQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG9uZV9mbG9hdCA9IDggW2RlZmF1bHQgPSAxXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZUZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPbmVGbG9hdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBvbmVfZmxvYXQgPSA4IFtkZWZhdWx0ID0gMV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lRmxvYXQuCiAgICAgKi8KICAgIGZsb2F0IGdldE9uZUZsb2F0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBzbWFsbF9mbG9hdCA9IDkgW2RlZmF1bHQgPSAxLjVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc21hbGxGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU21hbGxGbG9hdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBzbWFsbF9mbG9hdCA9IDkgW2RlZmF1bHQgPSAxLjVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHNtYWxsRmxvYXQuCiAgICAgKi8KICAgIGZsb2F0IGdldFNtYWxsRmxvYXQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG5lZ2F0aXZlX29uZV9mbG9hdCA9IDEwIFtkZWZhdWx0ID0gLTFdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmVnYXRpdmVPbmVGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTmVnYXRpdmVPbmVGbG9hdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBuZWdhdGl2ZV9vbmVfZmxvYXQgPSAxMCBbZGVmYXVsdCA9IC0xXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBuZWdhdGl2ZU9uZUZsb2F0LgogICAgICovCiAgICBmbG9hdCBnZXROZWdhdGl2ZU9uZUZsb2F0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBuZWdhdGl2ZV9mbG9hdCA9IDExIFtkZWZhdWx0ID0gLTEuNV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuZWdhdGl2ZUZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNOZWdhdGl2ZUZsb2F0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG5lZ2F0aXZlX2Zsb2F0ID0gMTEgW2RlZmF1bHQgPSAtMS41XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBuZWdhdGl2ZUZsb2F0LgogICAgICovCiAgICBmbG9hdCBnZXROZWdhdGl2ZUZsb2F0KCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVXNpbmcgZXhwb25lbnRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBsYXJnZV9mbG9hdCA9IDEyIFtkZWZhdWx0ID0gMmUrMDhdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbGFyZ2VGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTGFyZ2VGbG9hdCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVXNpbmcgZXhwb25lbnRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBsYXJnZV9mbG9hdCA9IDEyIFtkZWZhdWx0ID0gMmUrMDhdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxhcmdlRmxvYXQuCiAgICAgKi8KICAgIGZsb2F0IGdldExhcmdlRmxvYXQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHNtYWxsX25lZ2F0aXZlX2Zsb2F0ID0gMTMgW2RlZmF1bHQgPSAtOGUtMjhdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc21hbGxOZWdhdGl2ZUZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTbWFsbE5lZ2F0aXZlRmxvYXQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgc21hbGxfbmVnYXRpdmVfZmxvYXQgPSAxMyBbZGVmYXVsdCA9IC04ZS0yOF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc21hbGxOZWdhdGl2ZUZsb2F0LgogICAgICovCiAgICBmbG9hdCBnZXRTbWFsbE5lZ2F0aXZlRmxvYXQoKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXh0IGZvciBub25maW5pdGUgZmxvYXRpbmctcG9pbnQgdmFsdWVzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGluZl9kb3VibGUgPSAxNCBbZGVmYXVsdCA9IGluZl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbmZEb3VibGUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0luZkRvdWJsZSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGV4dCBmb3Igbm9uZmluaXRlIGZsb2F0aW5nLXBvaW50IHZhbHVlcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBpbmZfZG91YmxlID0gMTQgW2RlZmF1bHQgPSBpbmZdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGluZkRvdWJsZS4KICAgICAqLwogICAgZG91YmxlIGdldEluZkRvdWJsZSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIG5lZ19pbmZfZG91YmxlID0gMTUgW2RlZmF1bHQgPSAtaW5mXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lZ0luZkRvdWJsZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTmVnSW5mRG91YmxlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBuZWdfaW5mX2RvdWJsZSA9IDE1IFtkZWZhdWx0ID0gLWluZl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbmVnSW5mRG91YmxlLgogICAgICovCiAgICBkb3VibGUgZ2V0TmVnSW5mRG91YmxlKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgbmFuX2RvdWJsZSA9IDE2IFtkZWZhdWx0ID0gbmFuXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5hbkRvdWJsZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTmFuRG91YmxlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBuYW5fZG91YmxlID0gMTYgW2RlZmF1bHQgPSBuYW5dOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG5hbkRvdWJsZS4KICAgICAqLwogICAgZG91YmxlIGdldE5hbkRvdWJsZSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgaW5mX2Zsb2F0ID0gMTcgW2RlZmF1bHQgPSBpbmZdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW5mRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0luZkZsb2F0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGluZl9mbG9hdCA9IDE3IFtkZWZhdWx0ID0gaW5mXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbmZGbG9hdC4KICAgICAqLwogICAgZmxvYXQgZ2V0SW5mRmxvYXQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG5lZ19pbmZfZmxvYXQgPSAxOCBbZGVmYXVsdCA9IC1pbmZdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmVnSW5mRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc05lZ0luZkZsb2F0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG5lZ19pbmZfZmxvYXQgPSAxOCBbZGVmYXVsdCA9IC1pbmZdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG5lZ0luZkZsb2F0LgogICAgICovCiAgICBmbG9hdCBnZXROZWdJbmZGbG9hdCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbmFuX2Zsb2F0ID0gMTkgW2RlZmF1bHQgPSBuYW5dOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmFuRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc05hbkZsb2F0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG5hbl9mbG9hdCA9IDE5IFtkZWZhdWx0ID0gbmFuXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBuYW5GbG9hdC4KICAgICAqLwogICAgZmxvYXQgZ2V0TmFuRmxvYXQoKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0cyBmb3IgQysrIHRyaWdyYXBocy4KICAgICAqIFRyaWdyYXBocyBzaG91bGQgYmUgZXNjYXBlZCBpbiBDKysgZ2VuZXJhdGVkIGZpbGVzLCBidXQgdGhleSBzaG91bGQgbm90IGJlCiAgICAgKiBlc2NhcGVkIGZvciBvdGhlciBsYW5ndWFnZXMuCiAgICAgKiBOb3RlIHRoYXQgaW4gLnByb3RvIGZpbGUsICImIzkyOz8iIGlzIGEgdmFsaWQgd2F5IHRvIGVzY2FwZSA/IGluIHN0cmluZwogICAgICogbGl0ZXJhbHMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgY3BwX3RyaWdyYXBoID0gMjAgW2RlZmF1bHQgPSAiPyA/ID8/ID8/ID8/PyA/Py8gPz8tIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjcHBUcmlncmFwaCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQ3BwVHJpZ3JhcGgoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRlc3RzIGZvciBDKysgdHJpZ3JhcGhzLgogICAgICogVHJpZ3JhcGhzIHNob3VsZCBiZSBlc2NhcGVkIGluIEMrKyBnZW5lcmF0ZWQgZmlsZXMsIGJ1dCB0aGV5IHNob3VsZCBub3QgYmUKICAgICAqIGVzY2FwZWQgZm9yIG90aGVyIGxhbmd1YWdlcy4KICAgICAqIE5vdGUgdGhhdCBpbiAucHJvdG8gZmlsZSwgIiYjOTI7PyIgaXMgYSB2YWxpZCB3YXkgdG8gZXNjYXBlID8gaW4gc3RyaW5nCiAgICAgKiBsaXRlcmFscy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjcHBfdHJpZ3JhcGggPSAyMCBbZGVmYXVsdCA9ICI/ID8gPz8gPz8gPz8/ID8/LyA/Py0iXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjcHBUcmlncmFwaC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRDcHBUcmlncmFwaCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdHMgZm9yIEMrKyB0cmlncmFwaHMuCiAgICAgKiBUcmlncmFwaHMgc2hvdWxkIGJlIGVzY2FwZWQgaW4gQysrIGdlbmVyYXRlZCBmaWxlcywgYnV0IHRoZXkgc2hvdWxkIG5vdCBiZQogICAgICogZXNjYXBlZCBmb3Igb3RoZXIgbGFuZ3VhZ2VzLgogICAgICogTm90ZSB0aGF0IGluIC5wcm90byBmaWxlLCAiJiM5Mjs/IiBpcyBhIHZhbGlkIHdheSB0byBlc2NhcGUgPyBpbiBzdHJpbmcKICAgICAqIGxpdGVyYWxzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGNwcF90cmlncmFwaCA9IDIwIFtkZWZhdWx0ID0gIj8gPyA/PyA/PyA/Pz8gPz8vID8/LSJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBjcHBUcmlncmFwaC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0Q3BwVHJpZ3JhcGhCeXRlcygpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFN0cmluZyBkZWZhdWx0cyBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXIgJyYjOTI7MDAwJwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ193aXRoX3plcm8gPSAyMyBbZGVmYXVsdCA9ICJoZWwmIzkyOzAwMGxvIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdXaXRoWmVybyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3RyaW5nV2l0aFplcm8oKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFN0cmluZyBkZWZhdWx0cyBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXIgJyYjOTI7MDAwJwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ193aXRoX3plcm8gPSAyMyBbZGVmYXVsdCA9ICJoZWwmIzkyOzAwMGxvIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyaW5nV2l0aFplcm8uCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nV2l0aFplcm8oKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFN0cmluZyBkZWZhdWx0cyBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXIgJyYjOTI7MDAwJwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ193aXRoX3plcm8gPSAyMyBbZGVmYXVsdCA9ICJoZWwmIzkyOzAwMGxvIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cmluZ1dpdGhaZXJvLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHJpbmdXaXRoWmVyb0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBieXRlc193aXRoX3plcm8gPSAyNCBbZGVmYXVsdCA9ICJ3b3ImIzkyOzAwMGxkIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBieXRlc1dpdGhaZXJvIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNCeXRlc1dpdGhaZXJvKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGJ5dGVzX3dpdGhfemVybyA9IDI0IFtkZWZhdWx0ID0gIndvciYjOTI7MDAwbGQiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlc1dpdGhaZXJvLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0Qnl0ZXNXaXRoWmVybygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19waWVjZV93aXRoX3plcm8gPSAyNSBbZGVmYXVsdCA9ICJhYiYjOTI7MDAwYyIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cmluZ1BpZWNlV2l0aFplcm8gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cmluZ1BpZWNlV2l0aFplcm8oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19waWVjZV93aXRoX3plcm8gPSAyNSBbZGVmYXVsdCA9ICJhYiYjOTI7MDAwYyIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmdQaWVjZVdpdGhaZXJvLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ1BpZWNlV2l0aFplcm8oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19waWVjZV93aXRoX3plcm8gPSAyNSBbZGVmYXVsdCA9ICJhYiYjOTI7MDAwYyIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyaW5nUGllY2VXaXRoWmVyby4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyaW5nUGllY2VXaXRoWmVyb0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgY29yZF93aXRoX3plcm8gPSAyNiBbZGVmYXVsdCA9ICIxMiYjOTI7MDAwMyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBjb3JkV2l0aFplcm8gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0NvcmRXaXRoWmVybygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgY29yZF93aXRoX3plcm8gPSAyNiBbZGVmYXVsdCA9ICIxMiYjOTI7MDAwMyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY29yZFdpdGhaZXJvLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldENvcmRXaXRoWmVybygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgY29yZF93aXRoX3plcm8gPSAyNiBbZGVmYXVsdCA9ICIxMiYjOTI7MDAwMyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGNvcmRXaXRoWmVyby4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0Q29yZFdpdGhaZXJvQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyByZXBsYWNlbWVudF9zdHJpbmcgPSAyNyBbZGVmYXVsdCA9ICIke3Vua25vd259Il07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXBsYWNlbWVudFN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzUmVwbGFjZW1lbnRTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHJlcGxhY2VtZW50X3N0cmluZyA9IDI3IFtkZWZhdWx0ID0gIiR7dW5rbm93bn0iXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXBsYWNlbWVudFN0cmluZy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBsYWNlbWVudFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcmVwbGFjZW1lbnRfc3RyaW5nID0gMjcgW2RlZmF1bHQgPSAiJHt1bmtub3dufSJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciByZXBsYWNlbWVudFN0cmluZy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwbGFjZW1lbnRTdHJpbmdCeXRlcygpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzKQogICAgICBUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMoKSB7CiAgICAgIGVzY2FwZWRCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmJ5dGVzRGVmYXVsdFZhbHVlKCJcMDAwXDAwMVwwMDdcMDEwXDAxNFxuXHJcdFwwMTNcXFwnXCJcMzc2Iik7CiAgICAgIGxhcmdlVWludDMyXyA9IC0xOwogICAgICBsYXJnZVVpbnQ2NF8gPSAtMUw7CiAgICAgIHNtYWxsSW50MzJfID0gLTIxNDc0ODM2NDc7CiAgICAgIHNtYWxsSW50NjRfID0gLTkyMjMzNzIwMzY4NTQ3NzU4MDdMOwogICAgICByZWFsbHlTbWFsbEludDMyXyA9IC0yMTQ3NDgzNjQ4OwogICAgICByZWFsbHlTbWFsbEludDY0XyA9IC05MjIzMzcyMDM2ODU0Nzc1ODA4TDsKICAgICAgdXRmOFN0cmluZ18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLnN0cmluZ0RlZmF1bHRWYWx1ZSgiXDM0MVwyMTBcMjY0Iik7CiAgICAgIG9uZUZsb2F0XyA9IDFGOwogICAgICBzbWFsbEZsb2F0XyA9IDEuNUY7CiAgICAgIG5lZ2F0aXZlT25lRmxvYXRfID0gLTFGOwogICAgICBuZWdhdGl2ZUZsb2F0XyA9IC0xLjVGOwogICAgICBsYXJnZUZsb2F0XyA9IDJlKzA4RjsKICAgICAgc21hbGxOZWdhdGl2ZUZsb2F0XyA9IC04ZS0yOEY7CiAgICAgIGluZkRvdWJsZV8gPSBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFk7CiAgICAgIG5lZ0luZkRvdWJsZV8gPSBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFk7CiAgICAgIG5hbkRvdWJsZV8gPSBEb3VibGUuTmFOOwogICAgICBpbmZGbG9hdF8gPSBGbG9hdC5QT1NJVElWRV9JTkZJTklUWTsKICAgICAgbmVnSW5mRmxvYXRfID0gRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFk7CiAgICAgIG5hbkZsb2F0XyA9IEZsb2F0Lk5hTjsKICAgICAgY3BwVHJpZ3JhcGhfID0gIj8gPyA/PyA/PyA/Pz8gPz8vID8/LSI7CiAgICAgIHN0cmluZ1dpdGhaZXJvXyA9ICJoZWxcMDAwbG8iOwogICAgICBieXRlc1dpdGhaZXJvXyA9IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuYnl0ZXNEZWZhdWx0VmFsdWUoIndvclwwMDBsZCIpOwogICAgICBzdHJpbmdQaWVjZVdpdGhaZXJvXyA9ICJhYlwwMDBjIjsKICAgICAgY29yZFdpdGhaZXJvXyA9ICIxMlwwMDAzIjsKICAgICAgcmVwbGFjZW1lbnRTdHJpbmdfID0gIiR7dW5rbm93bn0iOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRyZW1lRGVmYXVsdFZhbHVlc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRyZW1lRGVmYXVsdFZhbHVlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVNDQVBFRF9CWVRFU19GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZXNjYXBlZEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuYnl0ZXNEZWZhdWx0VmFsdWUoIlwwMDBcMDAxXDAwN1wwMTBcMDE0XG5cclx0XDAxM1xcXCdcIlwzNzYiKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZXNjYXBlZF9ieXRlcyA9IDEgW2RlZmF1bHQgPSAiJiM5MjswMDAmIzkyOzAwMSYjOTI7MDA3JiM5MjswMTAmIzkyOzAxNCYjOTI7biYjOTI7ciYjOTI7dCYjOTI7MDEzJiM5MjsmIzkyOyYjOTI7JyYjOTI7IiYjOTI7Mzc2Il07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBlc2NhcGVkQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNFc2NhcGVkQnl0ZXMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZXNjYXBlZF9ieXRlcyA9IDEgW2RlZmF1bHQgPSAiJiM5MjswMDAmIzkyOzAwMSYjOTI7MDA3JiM5MjswMTAmIzkyOzAxNCYjOTI7biYjOTI7ciYjOTI7dCYjOTI7MDEzJiM5MjsmIzkyOyYjOTI7JyYjOTI7IiYjOTI7Mzc2Il07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZXNjYXBlZEJ5dGVzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEVzY2FwZWRCeXRlcygpIHsKICAgICAgcmV0dXJuIGVzY2FwZWRCeXRlc187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTEFSR0VfVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGludCBsYXJnZVVpbnQzMl8gPSAtMTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIGxhcmdlX3VpbnQzMiA9IDIgW2RlZmF1bHQgPSA0Mjk0OTY3Mjk1XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxhcmdlVWludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTGFyZ2VVaW50MzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIGxhcmdlX3VpbnQzMiA9IDIgW2RlZmF1bHQgPSA0Mjk0OTY3Mjk1XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsYXJnZVVpbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRMYXJnZVVpbnQzMigpIHsKICAgICAgcmV0dXJuIGxhcmdlVWludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMQVJHRV9VSU5UNjRfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgbG9uZyBsYXJnZVVpbnQ2NF8gPSAtMUw7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBsYXJnZV91aW50NjQgPSAzIFtkZWZhdWx0ID0gMTg0NDY3NDQwNzM3MDk1NTE2MTVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbGFyZ2VVaW50NjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNMYXJnZVVpbnQ2NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgbGFyZ2VfdWludDY0ID0gMyBbZGVmYXVsdCA9IDE4NDQ2NzQ0MDczNzA5NTUxNjE1XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBsYXJnZVVpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0TGFyZ2VVaW50NjQoKSB7CiAgICAgIHJldHVybiBsYXJnZVVpbnQ2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU01BTExfSU5UMzJfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgaW50IHNtYWxsSW50MzJfID0gLTIxNDc0ODM2NDc7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHNtYWxsX2ludDMyID0gNCBbZGVmYXVsdCA9IC0yMTQ3NDgzNjQ3XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNtYWxsSW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTbWFsbEludDMyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHNtYWxsX2ludDMyID0gNCBbZGVmYXVsdCA9IC0yMTQ3NDgzNjQ3XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzbWFsbEludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNtYWxsSW50MzIoKSB7CiAgICAgIHJldHVybiBzbWFsbEludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTTUFMTF9JTlQ2NF9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBsb25nIHNtYWxsSW50NjRfID0gLTkyMjMzNzIwMzY4NTQ3NzU4MDdMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBzbWFsbF9pbnQ2NCA9IDUgW2RlZmF1bHQgPSAtOTIyMzM3MjAzNjg1NDc3NTgwN107PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzbWFsbEludDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU21hbGxJbnQ2NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBzbWFsbF9pbnQ2NCA9IDUgW2RlZmF1bHQgPSAtOTIyMzM3MjAzNjg1NDc3NTgwN107PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc21hbGxJbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0U21hbGxJbnQ2NCgpIHsKICAgICAgcmV0dXJuIHNtYWxsSW50NjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFQUxMWV9TTUFMTF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAyMTsKICAgIHByaXZhdGUgaW50IHJlYWxseVNtYWxsSW50MzJfID0gLTIxNDc0ODM2NDg7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHJlYWxseV9zbWFsbF9pbnQzMiA9IDIxIFtkZWZhdWx0ID0gLTIxNDc0ODM2NDhdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVhbGx5U21hbGxJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1JlYWxseVNtYWxsSW50MzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgcmVhbGx5X3NtYWxsX2ludDMyID0gMjEgW2RlZmF1bHQgPSAtMjE0NzQ4MzY0OF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVhbGx5U21hbGxJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZWFsbHlTbWFsbEludDMyKCkgewogICAgICByZXR1cm4gcmVhbGx5U21hbGxJbnQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVBTExZX1NNQUxMX0lOVDY0X0ZJRUxEX05VTUJFUiA9IDIyOwogICAgcHJpdmF0ZSBsb25nIHJlYWxseVNtYWxsSW50NjRfID0gLTkyMjMzNzIwMzY4NTQ3NzU4MDhMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCByZWFsbHlfc21hbGxfaW50NjQgPSAyMiBbZGVmYXVsdCA9IC05MjIzMzcyMDM2ODU0Nzc1ODA4XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlYWxseVNtYWxsSW50NjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNSZWFsbHlTbWFsbEludDY0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IHJlYWxseV9zbWFsbF9pbnQ2NCA9IDIyIFtkZWZhdWx0ID0gLTkyMjMzNzIwMzY4NTQ3NzU4MDhdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlYWxseVNtYWxsSW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldFJlYWxseVNtYWxsSW50NjQoKSB7CiAgICAgIHJldHVybiByZWFsbHlTbWFsbEludDY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVVEY4X1NUUklOR19GSUVMRF9OVU1CRVIgPSA2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgdXRmOFN0cmluZ18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLnN0cmluZ0RlZmF1bHRWYWx1ZSgiXDM0MVwyMTBcMjY0Iik7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBoZXJlIGlzIFVURi04IGZvciAiJiM5Mjt1MTIzNCIuICAoV2UgY291bGQgYWxzbyBqdXN0IHR5cGUKICAgICAqIHRoZSBVVEYtOCB0ZXh0IGRpcmVjdGx5IGludG8gdGhpcyB0ZXh0IGZpbGUgcmF0aGVyIHRoYW4gZXNjYXBlIGl0LCBidXQKICAgICAqIGxvdHMgb2YgcGVvcGxlIHVzZSBlZGl0b3JzIHRoYXQgd291bGQgYmUgY29uZnVzZWQgYnkgdGhpcy4pCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgdXRmOF9zdHJpbmcgPSA2IFtkZWZhdWx0ID0gIiYjOTI7MzQxJiM5MjsyMTAmIzkyOzI2NCJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgdXRmOFN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1V0ZjhTdHJpbmcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlIGhlcmUgaXMgVVRGLTggZm9yICImIzkyO3UxMjM0Ii4gIChXZSBjb3VsZCBhbHNvIGp1c3QgdHlwZQogICAgICogdGhlIFVURi04IHRleHQgZGlyZWN0bHkgaW50byB0aGlzIHRleHQgZmlsZSByYXRoZXIgdGhhbiBlc2NhcGUgaXQsIGJ1dAogICAgICogbG90cyBvZiBwZW9wbGUgdXNlIGVkaXRvcnMgdGhhdCB3b3VsZCBiZSBjb25mdXNlZCBieSB0aGlzLikKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyB1dGY4X3N0cmluZyA9IDYgW2RlZmF1bHQgPSAiJiM5MjszNDEmIzkyOzIxMCYjOTI7MjY0Il07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgdXRmOFN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0VXRmOFN0cmluZygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSB1dGY4U3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICB1dGY4U3RyaW5nXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBoZXJlIGlzIFVURi04IGZvciAiJiM5Mjt1MTIzNCIuICAoV2UgY291bGQgYWxzbyBqdXN0IHR5cGUKICAgICAqIHRoZSBVVEYtOCB0ZXh0IGRpcmVjdGx5IGludG8gdGhpcyB0ZXh0IGZpbGUgcmF0aGVyIHRoYW4gZXNjYXBlIGl0LCBidXQKICAgICAqIGxvdHMgb2YgcGVvcGxlIHVzZSBlZGl0b3JzIHRoYXQgd291bGQgYmUgY29uZnVzZWQgYnkgdGhpcy4pCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgdXRmOF9zdHJpbmcgPSA2IFtkZWZhdWx0ID0gIiYjOTI7MzQxJiM5MjsyMTAmIzkyOzI2NCJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciB1dGY4U3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0VXRmOFN0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHV0ZjhTdHJpbmdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICB1dGY4U3RyaW5nXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFpFUk9fRkxPQVRfRklFTERfTlVNQkVSID0gNzsKICAgIHByaXZhdGUgZmxvYXQgemVyb0Zsb2F0XyA9IDBGOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdHMgZm9yIHNpbmdsZS1wcmVjaXNpb24gZmxvYXRpbmctcG9pbnQgdmFsdWVzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgemVyb19mbG9hdCA9IDcgW2RlZmF1bHQgPSAwXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHplcm9GbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1plcm9GbG9hdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdHMgZm9yIHNpbmdsZS1wcmVjaXNpb24gZmxvYXRpbmctcG9pbnQgdmFsdWVzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgemVyb19mbG9hdCA9IDcgW2RlZmF1bHQgPSAwXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSB6ZXJvRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRaZXJvRmxvYXQoKSB7CiAgICAgIHJldHVybiB6ZXJvRmxvYXRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORV9GTE9BVF9GSUVMRF9OVU1CRVIgPSA4OwogICAgcHJpdmF0ZSBmbG9hdCBvbmVGbG9hdF8gPSAxRjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgb25lX2Zsb2F0ID0gOCBbZGVmYXVsdCA9IDFdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVGbG9hdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBvbmVfZmxvYXQgPSA4IFtkZWZhdWx0ID0gMV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRPbmVGbG9hdCgpIHsKICAgICAgcmV0dXJuIG9uZUZsb2F0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTTUFMTF9GTE9BVF9GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBmbG9hdCBzbWFsbEZsb2F0XyA9IDEuNUY7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHNtYWxsX2Zsb2F0ID0gOSBbZGVmYXVsdCA9IDEuNV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzbWFsbEZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU21hbGxGbG9hdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBzbWFsbF9mbG9hdCA9IDkgW2RlZmF1bHQgPSAxLjVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHNtYWxsRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRTbWFsbEZsb2F0KCkgewogICAgICByZXR1cm4gc21hbGxGbG9hdF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkVHQVRJVkVfT05FX0ZMT0FUX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgcHJpdmF0ZSBmbG9hdCBuZWdhdGl2ZU9uZUZsb2F0XyA9IC0xRjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbmVnYXRpdmVfb25lX2Zsb2F0ID0gMTAgW2RlZmF1bHQgPSAtMV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuZWdhdGl2ZU9uZUZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTmVnYXRpdmVPbmVGbG9hdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBuZWdhdGl2ZV9vbmVfZmxvYXQgPSAxMCBbZGVmYXVsdCA9IC0xXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBuZWdhdGl2ZU9uZUZsb2F0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmxvYXQgZ2V0TmVnYXRpdmVPbmVGbG9hdCgpIHsKICAgICAgcmV0dXJuIG5lZ2F0aXZlT25lRmxvYXRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5FR0FUSVZFX0ZMT0FUX0ZJRUxEX05VTUJFUiA9IDExOwogICAgcHJpdmF0ZSBmbG9hdCBuZWdhdGl2ZUZsb2F0XyA9IC0xLjVGOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBuZWdhdGl2ZV9mbG9hdCA9IDExIFtkZWZhdWx0ID0gLTEuNV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuZWdhdGl2ZUZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTmVnYXRpdmVGbG9hdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBuZWdhdGl2ZV9mbG9hdCA9IDExIFtkZWZhdWx0ID0gLTEuNV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbmVnYXRpdmVGbG9hdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldE5lZ2F0aXZlRmxvYXQoKSB7CiAgICAgIHJldHVybiBuZWdhdGl2ZUZsb2F0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMQVJHRV9GTE9BVF9GSUVMRF9OVU1CRVIgPSAxMjsKICAgIHByaXZhdGUgZmxvYXQgbGFyZ2VGbG9hdF8gPSAyZSswOEY7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBVc2luZyBleHBvbmVudHMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGxhcmdlX2Zsb2F0ID0gMTIgW2RlZmF1bHQgPSAyZSswOF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsYXJnZUZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTGFyZ2VGbG9hdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVXNpbmcgZXhwb25lbnRzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBsYXJnZV9mbG9hdCA9IDEyIFtkZWZhdWx0ID0gMmUrMDhdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxhcmdlRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRMYXJnZUZsb2F0KCkgewogICAgICByZXR1cm4gbGFyZ2VGbG9hdF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU01BTExfTkVHQVRJVkVfRkxPQVRfRklFTERfTlVNQkVSID0gMTM7CiAgICBwcml2YXRlIGZsb2F0IHNtYWxsTmVnYXRpdmVGbG9hdF8gPSAtOGUtMjhGOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBzbWFsbF9uZWdhdGl2ZV9mbG9hdCA9IDEzIFtkZWZhdWx0ID0gLThlLTI4XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNtYWxsTmVnYXRpdmVGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1NtYWxsTmVnYXRpdmVGbG9hdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBzbWFsbF9uZWdhdGl2ZV9mbG9hdCA9IDEzIFtkZWZhdWx0ID0gLThlLTI4XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzbWFsbE5lZ2F0aXZlRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRTbWFsbE5lZ2F0aXZlRmxvYXQoKSB7CiAgICAgIHJldHVybiBzbWFsbE5lZ2F0aXZlRmxvYXRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElORl9ET1VCTEVfRklFTERfTlVNQkVSID0gMTQ7CiAgICBwcml2YXRlIGRvdWJsZSBpbmZEb3VibGVfID0gRG91YmxlLlBPU0lUSVZFX0lORklOSVRZOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGV4dCBmb3Igbm9uZmluaXRlIGZsb2F0aW5nLXBvaW50IHZhbHVlcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBpbmZfZG91YmxlID0gMTQgW2RlZmF1bHQgPSBpbmZdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW5mRG91YmxlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzSW5mRG91YmxlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXh0IGZvciBub25maW5pdGUgZmxvYXRpbmctcG9pbnQgdmFsdWVzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGluZl9kb3VibGUgPSAxNCBbZGVmYXVsdCA9IGluZl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgaW5mRG91YmxlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldEluZkRvdWJsZSgpIHsKICAgICAgcmV0dXJuIGluZkRvdWJsZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkVHX0lORl9ET1VCTEVfRklFTERfTlVNQkVSID0gMTU7CiAgICBwcml2YXRlIGRvdWJsZSBuZWdJbmZEb3VibGVfID0gRG91YmxlLk5FR0FUSVZFX0lORklOSVRZOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgbmVnX2luZl9kb3VibGUgPSAxNSBbZGVmYXVsdCA9IC1pbmZdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmVnSW5mRG91YmxlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTmVnSW5mRG91YmxlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBuZWdfaW5mX2RvdWJsZSA9IDE1IFtkZWZhdWx0ID0gLWluZl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbmVnSW5mRG91YmxlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZG91YmxlIGdldE5lZ0luZkRvdWJsZSgpIHsKICAgICAgcmV0dXJuIG5lZ0luZkRvdWJsZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkFOX0RPVUJMRV9GSUVMRF9OVU1CRVIgPSAxNjsKICAgIHByaXZhdGUgZG91YmxlIG5hbkRvdWJsZV8gPSBEb3VibGUuTmFOOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgbmFuX2RvdWJsZSA9IDE2IFtkZWZhdWx0ID0gbmFuXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5hbkRvdWJsZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc05hbkRvdWJsZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgbmFuX2RvdWJsZSA9IDE2IFtkZWZhdWx0ID0gbmFuXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBuYW5Eb3VibGUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBkb3VibGUgZ2V0TmFuRG91YmxlKCkgewogICAgICByZXR1cm4gbmFuRG91YmxlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJTkZfRkxPQVRfRklFTERfTlVNQkVSID0gMTc7CiAgICBwcml2YXRlIGZsb2F0IGluZkZsb2F0XyA9IEZsb2F0LlBPU0lUSVZFX0lORklOSVRZOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBpbmZfZmxvYXQgPSAxNyBbZGVmYXVsdCA9IGluZl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbmZGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0luZkZsb2F0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGluZl9mbG9hdCA9IDE3IFtkZWZhdWx0ID0gaW5mXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpbmZGbG9hdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZsb2F0IGdldEluZkZsb2F0KCkgewogICAgICByZXR1cm4gaW5mRmxvYXRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5FR19JTkZfRkxPQVRfRklFTERfTlVNQkVSID0gMTg7CiAgICBwcml2YXRlIGZsb2F0IG5lZ0luZkZsb2F0XyA9IEZsb2F0Lk5FR0FUSVZFX0lORklOSVRZOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBuZWdfaW5mX2Zsb2F0ID0gMTggW2RlZmF1bHQgPSAtaW5mXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lZ0luZkZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTmVnSW5mRmxvYXQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbmVnX2luZl9mbG9hdCA9IDE4IFtkZWZhdWx0ID0gLWluZl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbmVnSW5mRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXROZWdJbmZGbG9hdCgpIHsKICAgICAgcmV0dXJuIG5lZ0luZkZsb2F0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBOQU5fRkxPQVRfRklFTERfTlVNQkVSID0gMTk7CiAgICBwcml2YXRlIGZsb2F0IG5hbkZsb2F0XyA9IEZsb2F0Lk5hTjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbmFuX2Zsb2F0ID0gMTkgW2RlZmF1bHQgPSBuYW5dOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmFuRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNOYW5GbG9hdCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBuYW5fZmxvYXQgPSAxOSBbZGVmYXVsdCA9IG5hbl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbmFuRmxvYXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXROYW5GbG9hdCgpIHsKICAgICAgcmV0dXJuIG5hbkZsb2F0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDUFBfVFJJR1JBUEhfRklFTERfTlVNQkVSID0gMjA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBjcHBUcmlncmFwaF8gPSAiPyA/ID8/ID8/ID8/PyA/Py8gPz8tIjsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRlc3RzIGZvciBDKysgdHJpZ3JhcGhzLgogICAgICogVHJpZ3JhcGhzIHNob3VsZCBiZSBlc2NhcGVkIGluIEMrKyBnZW5lcmF0ZWQgZmlsZXMsIGJ1dCB0aGV5IHNob3VsZCBub3QgYmUKICAgICAqIGVzY2FwZWQgZm9yIG90aGVyIGxhbmd1YWdlcy4KICAgICAqIE5vdGUgdGhhdCBpbiAucHJvdG8gZmlsZSwgIiYjOTI7PyIgaXMgYSB2YWxpZCB3YXkgdG8gZXNjYXBlID8gaW4gc3RyaW5nCiAgICAgKiBsaXRlcmFscy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjcHBfdHJpZ3JhcGggPSAyMCBbZGVmYXVsdCA9ICI/ID8gPz8gPz8gPz8/ID8/LyA/Py0iXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGNwcFRyaWdyYXBoIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQ3BwVHJpZ3JhcGgoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRlc3RzIGZvciBDKysgdHJpZ3JhcGhzLgogICAgICogVHJpZ3JhcGhzIHNob3VsZCBiZSBlc2NhcGVkIGluIEMrKyBnZW5lcmF0ZWQgZmlsZXMsIGJ1dCB0aGV5IHNob3VsZCBub3QgYmUKICAgICAqIGVzY2FwZWQgZm9yIG90aGVyIGxhbmd1YWdlcy4KICAgICAqIE5vdGUgdGhhdCBpbiAucHJvdG8gZmlsZSwgIiYjOTI7PyIgaXMgYSB2YWxpZCB3YXkgdG8gZXNjYXBlID8gaW4gc3RyaW5nCiAgICAgKiBsaXRlcmFscy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjcHBfdHJpZ3JhcGggPSAyMCBbZGVmYXVsdCA9ICI/ID8gPz8gPz8gPz8/ID8/LyA/Py0iXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjcHBUcmlncmFwaC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Q3BwVHJpZ3JhcGgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gY3BwVHJpZ3JhcGhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGNwcFRyaWdyYXBoXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0cyBmb3IgQysrIHRyaWdyYXBocy4KICAgICAqIFRyaWdyYXBocyBzaG91bGQgYmUgZXNjYXBlZCBpbiBDKysgZ2VuZXJhdGVkIGZpbGVzLCBidXQgdGhleSBzaG91bGQgbm90IGJlCiAgICAgKiBlc2NhcGVkIGZvciBvdGhlciBsYW5ndWFnZXMuCiAgICAgKiBOb3RlIHRoYXQgaW4gLnByb3RvIGZpbGUsICImIzkyOz8iIGlzIGEgdmFsaWQgd2F5IHRvIGVzY2FwZSA/IGluIHN0cmluZwogICAgICogbGl0ZXJhbHMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgY3BwX3RyaWdyYXBoID0gMjAgW2RlZmF1bHQgPSAiPyA/ID8/ID8/ID8/PyA/Py8gPz8tIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGNwcFRyaWdyYXBoLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0Q3BwVHJpZ3JhcGhCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBjcHBUcmlncmFwaF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGNwcFRyaWdyYXBoXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklOR19XSVRIX1pFUk9fRklFTERfTlVNQkVSID0gMjM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBzdHJpbmdXaXRoWmVyb18gPSAiaGVsXDAwMGxvIjsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFN0cmluZyBkZWZhdWx0cyBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXIgJyYjOTI7MDAwJwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ193aXRoX3plcm8gPSAyMyBbZGVmYXVsdCA9ICJoZWwmIzkyOzAwMGxvIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdXaXRoWmVybyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cmluZ1dpdGhaZXJvKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBTdHJpbmcgZGVmYXVsdHMgY29udGFpbmluZyB0aGUgY2hhcmFjdGVyICcmIzkyOzAwMCcKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfd2l0aF96ZXJvID0gMjMgW2RlZmF1bHQgPSAiaGVsJiM5MjswMDBsbyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ1dpdGhaZXJvLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHJpbmdXaXRoWmVybygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJpbmdXaXRoWmVyb187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgc3RyaW5nV2l0aFplcm9fID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFN0cmluZyBkZWZhdWx0cyBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXIgJyYjOTI7MDAwJwogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ193aXRoX3plcm8gPSAyMyBbZGVmYXVsdCA9ICJoZWwmIzkyOzAwMGxvIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cmluZ1dpdGhaZXJvLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyaW5nV2l0aFplcm9CeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJpbmdXaXRoWmVyb187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIHN0cmluZ1dpdGhaZXJvXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJZVEVTX1dJVEhfWkVST19GSUVMRF9OVU1CRVIgPSAyNDsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJ5dGVzV2l0aFplcm9fID0gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5ieXRlc0RlZmF1bHRWYWx1ZSgid29yXDAwMGxkIik7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGJ5dGVzX3dpdGhfemVybyA9IDI0IFtkZWZhdWx0ID0gIndvciYjOTI7MDAwbGQiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJ5dGVzV2l0aFplcm8gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNCeXRlc1dpdGhaZXJvKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGJ5dGVzX3dpdGhfemVybyA9IDI0IFtkZWZhdWx0ID0gIndvciYjOTI7MDAwbGQiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlc1dpdGhaZXJvLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEJ5dGVzV2l0aFplcm8oKSB7CiAgICAgIHJldHVybiBieXRlc1dpdGhaZXJvXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFJJTkdfUElFQ0VfV0lUSF9aRVJPX0ZJRUxEX05VTUJFUiA9IDI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgc3RyaW5nUGllY2VXaXRoWmVyb18gPSAiYWJcMDAwYyI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfcGllY2Vfd2l0aF96ZXJvID0gMjUgW2RlZmF1bHQgPSAiYWImIzkyOzAwMGMiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdQaWVjZVdpdGhaZXJvIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyaW5nUGllY2VXaXRoWmVybygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX3BpZWNlX3dpdGhfemVybyA9IDI1IFtkZWZhdWx0ID0gImFiJiM5MjswMDBjIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ1BpZWNlV2l0aFplcm8uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ1BpZWNlV2l0aFplcm8oKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nUGllY2VXaXRoWmVyb187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgc3RyaW5nUGllY2VXaXRoWmVyb18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX3BpZWNlX3dpdGhfemVybyA9IDI1IFtkZWZhdWx0ID0gImFiJiM5MjswMDBjIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHJpbmdQaWVjZVdpdGhaZXJvLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyaW5nUGllY2VXaXRoWmVyb0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cmluZ1BpZWNlV2l0aFplcm9fOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHJpbmdQaWVjZVdpdGhaZXJvXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENPUkRfV0lUSF9aRVJPX0ZJRUxEX05VTUJFUiA9IDI2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgY29yZFdpdGhaZXJvXyA9ICIxMlwwMDAzIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGNvcmRfd2l0aF96ZXJvID0gMjYgW2RlZmF1bHQgPSAiMTImIzkyOzAwMDMiLCBjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY29yZFdpdGhaZXJvIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQ29yZFdpdGhaZXJvKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjb3JkX3dpdGhfemVybyA9IDI2IFtkZWZhdWx0ID0gIjEyJiM5MjswMDAzIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3JkV2l0aFplcm8uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldENvcmRXaXRoWmVybygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBjb3JkV2l0aFplcm9fOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGNvcmRXaXRoWmVyb18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgY29yZF93aXRoX3plcm8gPSAyNiBbZGVmYXVsdCA9ICIxMiYjOTI7MDAwMyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGNvcmRXaXRoWmVyby4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldENvcmRXaXRoWmVyb0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGNvcmRXaXRoWmVyb187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGNvcmRXaXRoWmVyb18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBMQUNFTUVOVF9TVFJJTkdfRklFTERfTlVNQkVSID0gMjc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCByZXBsYWNlbWVudFN0cmluZ18gPSAiJHt1bmtub3dufSI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyByZXBsYWNlbWVudF9zdHJpbmcgPSAyNyBbZGVmYXVsdCA9ICIke3Vua25vd259Il07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXBsYWNlbWVudFN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1JlcGxhY2VtZW50U3RyaW5nKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyByZXBsYWNlbWVudF9zdHJpbmcgPSAyNyBbZGVmYXVsdCA9ICIke3Vua25vd259Il07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcmVwbGFjZW1lbnRTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGxhY2VtZW50U3RyaW5nKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHJlcGxhY2VtZW50U3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICByZXBsYWNlbWVudFN0cmluZ18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcmVwbGFjZW1lbnRfc3RyaW5nID0gMjcgW2RlZmF1bHQgPSAiJHt1bmtub3dufSJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciByZXBsYWNlbWVudFN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGxhY2VtZW50U3RyaW5nQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gcmVwbGFjZW1lbnRTdHJpbmdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICByZXBsYWNlbWVudFN0cmluZ18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDEsIGVzY2FwZWRCeXRlc18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigyLCBsYXJnZVVpbnQzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCgzLCBsYXJnZVVpbnQ2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDQsIHNtYWxsSW50MzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCg1LCBzbWFsbEludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA2LCB1dGY4U3RyaW5nXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoNywgemVyb0Zsb2F0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoOCwgb25lRmxvYXRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdCg5LCBzbWFsbEZsb2F0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMTAsIG5lZ2F0aXZlT25lRmxvYXRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdCgxMSwgbmVnYXRpdmVGbG9hdF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0KDEyLCBsYXJnZUZsb2F0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXQoMTMsIHNtYWxsTmVnYXRpdmVGbG9hdF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgxNCwgaW5mRG91YmxlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKDE1LCBuZWdJbmZEb3VibGVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVEb3VibGUoMTYsIG5hbkRvdWJsZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0KDE3LCBpbmZGbG9hdF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0KDE4LCBuZWdJbmZGbG9hdF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0KDE5LCBuYW5GbG9hdF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjAsIGNwcFRyaWdyYXBoXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMjEsIHJlYWxseVNtYWxsSW50MzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgyMiwgcmVhbGx5U21hbGxJbnQ2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjMsIHN0cmluZ1dpdGhaZXJvXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMjQsIGJ5dGVzV2l0aFplcm9fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDI1LCBzdHJpbmdQaWVjZVdpdGhaZXJvXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyNiwgY29yZFdpdGhaZXJvXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyNywgcmVwbGFjZW1lbnRTdHJpbmdfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgxLCBlc2NhcGVkQnl0ZXNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSgyLCBsYXJnZVVpbnQzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplKDMsIGxhcmdlVWludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg0LCBzbWFsbEludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSg1LCBzbWFsbEludDY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSg2LCB1dGY4U3RyaW5nXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZsb2F0U2l6ZSg3LCB6ZXJvRmxvYXRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRmxvYXRTaXplKDgsIG9uZUZsb2F0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZsb2F0U2l6ZSg5LCBzbWFsbEZsb2F0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZsb2F0U2l6ZSgxMCwgbmVnYXRpdmVPbmVGbG9hdF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGbG9hdFNpemUoMTEsIG5lZ2F0aXZlRmxvYXRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRmxvYXRTaXplKDEyLCBsYXJnZUZsb2F0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZsb2F0U2l6ZSgxMywgc21hbGxOZWdhdGl2ZUZsb2F0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZURvdWJsZVNpemUoMTQsIGluZkRvdWJsZV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVEb3VibGVTaXplKDE1LCBuZWdJbmZEb3VibGVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRG91YmxlU2l6ZSgxNiwgbmFuRG91YmxlXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZsb2F0U2l6ZSgxNywgaW5mRmxvYXRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRmxvYXRTaXplKDE4LCBuZWdJbmZGbG9hdF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVGbG9hdFNpemUoMTksIG5hbkZsb2F0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyMCwgY3BwVHJpZ3JhcGhfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIxLCByZWFsbHlTbWFsbEludDMyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSgyMiwgcmVhbGx5U21hbGxJbnQ2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMjMsIHN0cmluZ1dpdGhaZXJvXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgyNCwgYnl0ZXNXaXRoWmVyb18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMjUsIHN0cmluZ1BpZWNlV2l0aFplcm9fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDI2LCBjb3JkV2l0aFplcm9fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDI3LCByZXBsYWNlbWVudFN0cmluZ18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcykgb2JqOwoKICAgICAgaWYgKGhhc0VzY2FwZWRCeXRlcygpICE9IG90aGVyLmhhc0VzY2FwZWRCeXRlcygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNFc2NhcGVkQnl0ZXMoKSkgewogICAgICAgIGlmICghZ2V0RXNjYXBlZEJ5dGVzKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRFc2NhcGVkQnl0ZXMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzTGFyZ2VVaW50MzIoKSAhPSBvdGhlci5oYXNMYXJnZVVpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNMYXJnZVVpbnQzMigpKSB7CiAgICAgICAgaWYgKGdldExhcmdlVWludDMyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0TGFyZ2VVaW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNMYXJnZVVpbnQ2NCgpICE9IG90aGVyLmhhc0xhcmdlVWludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0xhcmdlVWludDY0KCkpIHsKICAgICAgICBpZiAoZ2V0TGFyZ2VVaW50NjQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRMYXJnZVVpbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1NtYWxsSW50MzIoKSAhPSBvdGhlci5oYXNTbWFsbEludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1NtYWxsSW50MzIoKSkgewogICAgICAgIGlmIChnZXRTbWFsbEludDMyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0U21hbGxJbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1NtYWxsSW50NjQoKSAhPSBvdGhlci5oYXNTbWFsbEludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1NtYWxsSW50NjQoKSkgewogICAgICAgIGlmIChnZXRTbWFsbEludDY0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0U21hbGxJbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1JlYWxseVNtYWxsSW50MzIoKSAhPSBvdGhlci5oYXNSZWFsbHlTbWFsbEludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1JlYWxseVNtYWxsSW50MzIoKSkgewogICAgICAgIGlmIChnZXRSZWFsbHlTbWFsbEludDMyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0UmVhbGx5U21hbGxJbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1JlYWxseVNtYWxsSW50NjQoKSAhPSBvdGhlci5oYXNSZWFsbHlTbWFsbEludDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1JlYWxseVNtYWxsSW50NjQoKSkgewogICAgICAgIGlmIChnZXRSZWFsbHlTbWFsbEludDY0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0UmVhbGx5U21hbGxJbnQ2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1V0ZjhTdHJpbmcoKSAhPSBvdGhlci5oYXNVdGY4U3RyaW5nKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1V0ZjhTdHJpbmcoKSkgewogICAgICAgIGlmICghZ2V0VXRmOFN0cmluZygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0VXRmOFN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNaZXJvRmxvYXQoKSAhPSBvdGhlci5oYXNaZXJvRmxvYXQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzWmVyb0Zsb2F0KCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKGdldFplcm9GbG9hdCgpKQogICAgICAgICAgICAhPSBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgICBvdGhlci5nZXRaZXJvRmxvYXQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT25lRmxvYXQoKSAhPSBvdGhlci5oYXNPbmVGbG9hdCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPbmVGbG9hdCgpKSB7CiAgICAgICAgaWYgKGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhnZXRPbmVGbG9hdCgpKQogICAgICAgICAgICAhPSBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgICBvdGhlci5nZXRPbmVGbG9hdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTbWFsbEZsb2F0KCkgIT0gb3RoZXIuaGFzU21hbGxGbG9hdCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTbWFsbEZsb2F0KCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKGdldFNtYWxsRmxvYXQoKSkKICAgICAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICAgICAgb3RoZXIuZ2V0U21hbGxGbG9hdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNOZWdhdGl2ZU9uZUZsb2F0KCkgIT0gb3RoZXIuaGFzTmVnYXRpdmVPbmVGbG9hdCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNOZWdhdGl2ZU9uZUZsb2F0KCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKGdldE5lZ2F0aXZlT25lRmxvYXQoKSkKICAgICAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICAgICAgb3RoZXIuZ2V0TmVnYXRpdmVPbmVGbG9hdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNOZWdhdGl2ZUZsb2F0KCkgIT0gb3RoZXIuaGFzTmVnYXRpdmVGbG9hdCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNOZWdhdGl2ZUZsb2F0KCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKGdldE5lZ2F0aXZlRmxvYXQoKSkKICAgICAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICAgICAgb3RoZXIuZ2V0TmVnYXRpdmVGbG9hdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNMYXJnZUZsb2F0KCkgIT0gb3RoZXIuaGFzTGFyZ2VGbG9hdCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNMYXJnZUZsb2F0KCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKGdldExhcmdlRmxvYXQoKSkKICAgICAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICAgICAgb3RoZXIuZ2V0TGFyZ2VGbG9hdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTbWFsbE5lZ2F0aXZlRmxvYXQoKSAhPSBvdGhlci5oYXNTbWFsbE5lZ2F0aXZlRmxvYXQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzU21hbGxOZWdhdGl2ZUZsb2F0KCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKGdldFNtYWxsTmVnYXRpdmVGbG9hdCgpKQogICAgICAgICAgICAhPSBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgICBvdGhlci5nZXRTbWFsbE5lZ2F0aXZlRmxvYXQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzSW5mRG91YmxlKCkgIT0gb3RoZXIuaGFzSW5mRG91YmxlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0luZkRvdWJsZSgpKSB7CiAgICAgICAgaWYgKGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRJbmZEb3VibGUoKSkKICAgICAgICAgICAgIT0gamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKAogICAgICAgICAgICAgICAgb3RoZXIuZ2V0SW5mRG91YmxlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc05lZ0luZkRvdWJsZSgpICE9IG90aGVyLmhhc05lZ0luZkRvdWJsZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNOZWdJbmZEb3VibGUoKSkgewogICAgICAgIGlmIChqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0TmVnSW5mRG91YmxlKCkpCiAgICAgICAgICAgICE9IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cygKICAgICAgICAgICAgICAgIG90aGVyLmdldE5lZ0luZkRvdWJsZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNOYW5Eb3VibGUoKSAhPSBvdGhlci5oYXNOYW5Eb3VibGUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTmFuRG91YmxlKCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkRvdWJsZS5kb3VibGVUb0xvbmdCaXRzKGdldE5hbkRvdWJsZSgpKQogICAgICAgICAgICAhPSBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoCiAgICAgICAgICAgICAgICBvdGhlci5nZXROYW5Eb3VibGUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzSW5mRmxvYXQoKSAhPSBvdGhlci5oYXNJbmZGbG9hdCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNJbmZGbG9hdCgpKSB7CiAgICAgICAgaWYgKGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhnZXRJbmZGbG9hdCgpKQogICAgICAgICAgICAhPSBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgICAgICBvdGhlci5nZXRJbmZGbG9hdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNOZWdJbmZGbG9hdCgpICE9IG90aGVyLmhhc05lZ0luZkZsb2F0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc05lZ0luZkZsb2F0KCkpIHsKICAgICAgICBpZiAoamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKGdldE5lZ0luZkZsb2F0KCkpCiAgICAgICAgICAgICE9IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgICAgIG90aGVyLmdldE5lZ0luZkZsb2F0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc05hbkZsb2F0KCkgIT0gb3RoZXIuaGFzTmFuRmxvYXQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTmFuRmxvYXQoKSkgewogICAgICAgIGlmIChqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoZ2V0TmFuRmxvYXQoKSkKICAgICAgICAgICAgIT0gamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICAgICAgb3RoZXIuZ2V0TmFuRmxvYXQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzQ3BwVHJpZ3JhcGgoKSAhPSBvdGhlci5oYXNDcHBUcmlncmFwaCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNDcHBUcmlncmFwaCgpKSB7CiAgICAgICAgaWYgKCFnZXRDcHBUcmlncmFwaCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Q3BwVHJpZ3JhcGgoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyaW5nV2l0aFplcm8oKSAhPSBvdGhlci5oYXNTdHJpbmdXaXRoWmVybygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTdHJpbmdXaXRoWmVybygpKSB7CiAgICAgICAgaWYgKCFnZXRTdHJpbmdXaXRoWmVybygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyaW5nV2l0aFplcm8oKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzQnl0ZXNXaXRoWmVybygpICE9IG90aGVyLmhhc0J5dGVzV2l0aFplcm8oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQnl0ZXNXaXRoWmVybygpKSB7CiAgICAgICAgaWYgKCFnZXRCeXRlc1dpdGhaZXJvKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRCeXRlc1dpdGhaZXJvKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cmluZ1BpZWNlV2l0aFplcm8oKSAhPSBvdGhlci5oYXNTdHJpbmdQaWVjZVdpdGhaZXJvKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cmluZ1BpZWNlV2l0aFplcm8oKSkgewogICAgICAgIGlmICghZ2V0U3RyaW5nUGllY2VXaXRoWmVybygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyaW5nUGllY2VXaXRoWmVybygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNDb3JkV2l0aFplcm8oKSAhPSBvdGhlci5oYXNDb3JkV2l0aFplcm8oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzQ29yZFdpdGhaZXJvKCkpIHsKICAgICAgICBpZiAoIWdldENvcmRXaXRoWmVybygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Q29yZFdpdGhaZXJvKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1JlcGxhY2VtZW50U3RyaW5nKCkgIT0gb3RoZXIuaGFzUmVwbGFjZW1lbnRTdHJpbmcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUmVwbGFjZW1lbnRTdHJpbmcoKSkgewogICAgICAgIGlmICghZ2V0UmVwbGFjZW1lbnRTdHJpbmcoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGxhY2VtZW50U3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzRXNjYXBlZEJ5dGVzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBFU0NBUEVEX0JZVEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRFc2NhcGVkQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNMYXJnZVVpbnQzMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTEFSR0VfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRMYXJnZVVpbnQzMigpOwogICAgICB9CiAgICAgIGlmIChoYXNMYXJnZVVpbnQ2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTEFSR0VfVUlOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXRMYXJnZVVpbnQ2NCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzU21hbGxJbnQzMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU01BTExfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFNtYWxsSW50MzIoKTsKICAgICAgfQogICAgICBpZiAoaGFzU21hbGxJbnQ2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU01BTExfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldFNtYWxsSW50NjQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc1JlYWxseVNtYWxsSW50MzIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFQUxMWV9TTUFMTF9JTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVhbGx5U21hbGxJbnQzMigpOwogICAgICB9CiAgICAgIGlmIChoYXNSZWFsbHlTbWFsbEludDY0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRUFMTFlfU01BTExfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldFJlYWxseVNtYWxsSW50NjQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc1V0ZjhTdHJpbmcoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVURjhfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRVdGY4U3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzWmVyb0Zsb2F0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBaRVJPX0ZMT0FUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgIGdldFplcm9GbG9hdCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzT25lRmxvYXQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9ORV9GTE9BVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICBnZXRPbmVGbG9hdCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzU21hbGxGbG9hdCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU01BTExfRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgZ2V0U21hbGxGbG9hdCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzTmVnYXRpdmVPbmVGbG9hdCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTkVHQVRJVkVfT05FX0ZMT0FUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgIGdldE5lZ2F0aXZlT25lRmxvYXQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc05lZ2F0aXZlRmxvYXQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE5FR0FUSVZFX0ZMT0FUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgIGdldE5lZ2F0aXZlRmxvYXQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0xhcmdlRmxvYXQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIExBUkdFX0ZMT0FUX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBqYXZhLmxhbmcuRmxvYXQuZmxvYXRUb0ludEJpdHMoCiAgICAgICAgICAgIGdldExhcmdlRmxvYXQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc1NtYWxsTmVnYXRpdmVGbG9hdCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU01BTExfTkVHQVRJVkVfRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgZ2V0U21hbGxOZWdhdGl2ZUZsb2F0KCkpOwogICAgICB9CiAgICAgIGlmIChoYXNJbmZEb3VibGUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElORl9ET1VCTEVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRJbmZEb3VibGUoKSkpOwogICAgICB9CiAgICAgIGlmIChoYXNOZWdJbmZEb3VibGUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE5FR19JTkZfRE9VQkxFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0TmVnSW5mRG91YmxlKCkpKTsKICAgICAgfQogICAgICBpZiAoaGFzTmFuRG91YmxlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBOQU5fRE9VQkxFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0TmFuRG91YmxlKCkpKTsKICAgICAgfQogICAgICBpZiAoaGFzSW5mRmxvYXQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIElORl9GTE9BVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICBnZXRJbmZGbG9hdCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzTmVnSW5mRmxvYXQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE5FR19JTkZfRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgZ2V0TmVnSW5mRmxvYXQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc05hbkZsb2F0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBOQU5fRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgZ2V0TmFuRmxvYXQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc0NwcFRyaWdyYXBoKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDUFBfVFJJR1JBUEhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldENwcFRyaWdyYXBoKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyaW5nV2l0aFplcm8oKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUklOR19XSVRIX1pFUk9fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cmluZ1dpdGhaZXJvKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzQnl0ZXNXaXRoWmVybygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQllURVNfV0lUSF9aRVJPX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCeXRlc1dpdGhaZXJvKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyaW5nUGllY2VXaXRoWmVybygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSSU5HX1BJRUNFX1dJVEhfWkVST19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyaW5nUGllY2VXaXRoWmVybygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0NvcmRXaXRoWmVybygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQ09SRF9XSVRIX1pFUk9fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldENvcmRXaXRoWmVybygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1JlcGxhY2VtZW50U3RyaW5nKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBMQUNFTUVOVF9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGxhY2VtZW50U3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRyZW1lRGVmYXVsdFZhbHVlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgZXNjYXBlZEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuYnl0ZXNEZWZhdWx0VmFsdWUoIlwwMDBcMDAxXDAwN1wwMTBcMDE0XG5cclx0XDAxM1xcXCdcIlwzNzYiKTsKICAgICAgICBsYXJnZVVpbnQzMl8gPSAtMTsKICAgICAgICBsYXJnZVVpbnQ2NF8gPSAtMUw7CiAgICAgICAgc21hbGxJbnQzMl8gPSAtMjE0NzQ4MzY0NzsKICAgICAgICBzbWFsbEludDY0XyA9IC05MjIzMzcyMDM2ODU0Nzc1ODA3TDsKICAgICAgICByZWFsbHlTbWFsbEludDMyXyA9IC0yMTQ3NDgzNjQ4OwogICAgICAgIHJlYWxseVNtYWxsSW50NjRfID0gLTkyMjMzNzIwMzY4NTQ3NzU4MDhMOwogICAgICAgIHV0ZjhTdHJpbmdfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5zdHJpbmdEZWZhdWx0VmFsdWUoIlwzNDFcMjEwXDI2NCIpOwogICAgICAgIHplcm9GbG9hdF8gPSAwRjsKICAgICAgICBvbmVGbG9hdF8gPSAxRjsKICAgICAgICBzbWFsbEZsb2F0XyA9IDEuNUY7CiAgICAgICAgbmVnYXRpdmVPbmVGbG9hdF8gPSAtMUY7CiAgICAgICAgbmVnYXRpdmVGbG9hdF8gPSAtMS41RjsKICAgICAgICBsYXJnZUZsb2F0XyA9IDJlKzA4RjsKICAgICAgICBzbWFsbE5lZ2F0aXZlRmxvYXRfID0gLThlLTI4RjsKICAgICAgICBpbmZEb3VibGVfID0gRG91YmxlLlBPU0lUSVZFX0lORklOSVRZOwogICAgICAgIG5lZ0luZkRvdWJsZV8gPSBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFk7CiAgICAgICAgbmFuRG91YmxlXyA9IERvdWJsZS5OYU47CiAgICAgICAgaW5mRmxvYXRfID0gRmxvYXQuUE9TSVRJVkVfSU5GSU5JVFk7CiAgICAgICAgbmVnSW5mRmxvYXRfID0gRmxvYXQuTkVHQVRJVkVfSU5GSU5JVFk7CiAgICAgICAgbmFuRmxvYXRfID0gRmxvYXQuTmFOOwogICAgICAgIGNwcFRyaWdyYXBoXyA9ICI/ID8gPz8gPz8gPz8/ID8/LyA/Py0iOwogICAgICAgIHN0cmluZ1dpdGhaZXJvXyA9ICJoZWxcMDAwbG8iOwogICAgICAgIGJ5dGVzV2l0aFplcm9fID0gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5ieXRlc0RlZmF1bHRWYWx1ZSgid29yXDAwMGxkIik7CiAgICAgICAgc3RyaW5nUGllY2VXaXRoWmVyb18gPSAiYWJcMDAwYyI7CiAgICAgICAgY29yZFdpdGhaZXJvXyA9ICIxMlwwMDAzIjsKICAgICAgICByZXBsYWNlbWVudFN0cmluZ18gPSAiJHt1bmtub3dufSI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRyZW1lRGVmYXVsdFZhbHVlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmVzY2FwZWRCeXRlc18gPSBlc2NhcGVkQnl0ZXNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmxhcmdlVWludDMyXyA9IGxhcmdlVWludDMyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sYXJnZVVpbnQ2NF8gPSBsYXJnZVVpbnQ2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc21hbGxJbnQzMl8gPSBzbWFsbEludDMyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zbWFsbEludDY0XyA9IHNtYWxsSW50NjRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnJlYWxseVNtYWxsSW50MzJfID0gcmVhbGx5U21hbGxJbnQzMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucmVhbGx5U21hbGxJbnQ2NF8gPSByZWFsbHlTbWFsbEludDY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC51dGY4U3RyaW5nXyA9IHV0ZjhTdHJpbmdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lnplcm9GbG9hdF8gPSB6ZXJvRmxvYXRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9uZUZsb2F0XyA9IG9uZUZsb2F0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zbWFsbEZsb2F0XyA9IHNtYWxsRmxvYXRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm5lZ2F0aXZlT25lRmxvYXRfID0gbmVnYXRpdmVPbmVGbG9hdF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubmVnYXRpdmVGbG9hdF8gPSBuZWdhdGl2ZUZsb2F0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sYXJnZUZsb2F0XyA9IGxhcmdlRmxvYXRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA0MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnNtYWxsTmVnYXRpdmVGbG9hdF8gPSBzbWFsbE5lZ2F0aXZlRmxvYXRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmluZkRvdWJsZV8gPSBpbmZEb3VibGVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm5lZ0luZkRvdWJsZV8gPSBuZWdJbmZEb3VibGVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm5hbkRvdWJsZV8gPSBuYW5Eb3VibGVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmluZkZsb2F0XyA9IGluZkZsb2F0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5uZWdJbmZGbG9hdF8gPSBuZWdJbmZGbG9hdF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubmFuRmxvYXRfID0gbmFuRmxvYXRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNwcFRyaWdyYXBoXyA9IGNwcFRyaWdyYXBoXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHJpbmdXaXRoWmVyb18gPSBzdHJpbmdXaXRoWmVyb187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuYnl0ZXNXaXRoWmVyb18gPSBieXRlc1dpdGhaZXJvXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHJpbmdQaWVjZVdpdGhaZXJvXyA9IHN0cmluZ1BpZWNlV2l0aFplcm9fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmNvcmRXaXRoWmVyb18gPSBjb3JkV2l0aFplcm9fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDA0MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnJlcGxhY2VtZW50U3RyaW5nXyA9IHJlcGxhY2VtZW50U3RyaW5nXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0VzY2FwZWRCeXRlcygpKSB7CiAgICAgICAgICBzZXRFc2NhcGVkQnl0ZXMob3RoZXIuZ2V0RXNjYXBlZEJ5dGVzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzTGFyZ2VVaW50MzIoKSkgewogICAgICAgICAgc2V0TGFyZ2VVaW50MzIob3RoZXIuZ2V0TGFyZ2VVaW50MzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNMYXJnZVVpbnQ2NCgpKSB7CiAgICAgICAgICBzZXRMYXJnZVVpbnQ2NChvdGhlci5nZXRMYXJnZVVpbnQ2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1NtYWxsSW50MzIoKSkgewogICAgICAgICAgc2V0U21hbGxJbnQzMihvdGhlci5nZXRTbWFsbEludDMyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU21hbGxJbnQ2NCgpKSB7CiAgICAgICAgICBzZXRTbWFsbEludDY0KG90aGVyLmdldFNtYWxsSW50NjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNSZWFsbHlTbWFsbEludDMyKCkpIHsKICAgICAgICAgIHNldFJlYWxseVNtYWxsSW50MzIob3RoZXIuZ2V0UmVhbGx5U21hbGxJbnQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1JlYWxseVNtYWxsSW50NjQoKSkgewogICAgICAgICAgc2V0UmVhbGx5U21hbGxJbnQ2NChvdGhlci5nZXRSZWFsbHlTbWFsbEludDY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzVXRmOFN0cmluZygpKSB7CiAgICAgICAgICB1dGY4U3RyaW5nXyA9IG90aGVyLnV0ZjhTdHJpbmdfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNaZXJvRmxvYXQoKSkgewogICAgICAgICAgc2V0WmVyb0Zsb2F0KG90aGVyLmdldFplcm9GbG9hdCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09uZUZsb2F0KCkpIHsKICAgICAgICAgIHNldE9uZUZsb2F0KG90aGVyLmdldE9uZUZsb2F0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU21hbGxGbG9hdCgpKSB7CiAgICAgICAgICBzZXRTbWFsbEZsb2F0KG90aGVyLmdldFNtYWxsRmxvYXQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNOZWdhdGl2ZU9uZUZsb2F0KCkpIHsKICAgICAgICAgIHNldE5lZ2F0aXZlT25lRmxvYXQob3RoZXIuZ2V0TmVnYXRpdmVPbmVGbG9hdCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc05lZ2F0aXZlRmxvYXQoKSkgewogICAgICAgICAgc2V0TmVnYXRpdmVGbG9hdChvdGhlci5nZXROZWdhdGl2ZUZsb2F0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzTGFyZ2VGbG9hdCgpKSB7CiAgICAgICAgICBzZXRMYXJnZUZsb2F0KG90aGVyLmdldExhcmdlRmxvYXQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTbWFsbE5lZ2F0aXZlRmxvYXQoKSkgewogICAgICAgICAgc2V0U21hbGxOZWdhdGl2ZUZsb2F0KG90aGVyLmdldFNtYWxsTmVnYXRpdmVGbG9hdCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0luZkRvdWJsZSgpKSB7CiAgICAgICAgICBzZXRJbmZEb3VibGUob3RoZXIuZ2V0SW5mRG91YmxlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzTmVnSW5mRG91YmxlKCkpIHsKICAgICAgICAgIHNldE5lZ0luZkRvdWJsZShvdGhlci5nZXROZWdJbmZEb3VibGUoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNOYW5Eb3VibGUoKSkgewogICAgICAgICAgc2V0TmFuRG91YmxlKG90aGVyLmdldE5hbkRvdWJsZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0luZkZsb2F0KCkpIHsKICAgICAgICAgIHNldEluZkZsb2F0KG90aGVyLmdldEluZkZsb2F0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzTmVnSW5mRmxvYXQoKSkgewogICAgICAgICAgc2V0TmVnSW5mRmxvYXQob3RoZXIuZ2V0TmVnSW5mRmxvYXQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNOYW5GbG9hdCgpKSB7CiAgICAgICAgICBzZXROYW5GbG9hdChvdGhlci5nZXROYW5GbG9hdCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0NwcFRyaWdyYXBoKCkpIHsKICAgICAgICAgIGNwcFRyaWdyYXBoXyA9IG90aGVyLmNwcFRyaWdyYXBoXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyaW5nV2l0aFplcm8oKSkgewogICAgICAgICAgc3RyaW5nV2l0aFplcm9fID0gb3RoZXIuc3RyaW5nV2l0aFplcm9fOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNCeXRlc1dpdGhaZXJvKCkpIHsKICAgICAgICAgIHNldEJ5dGVzV2l0aFplcm8ob3RoZXIuZ2V0Qnl0ZXNXaXRoWmVybygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1N0cmluZ1BpZWNlV2l0aFplcm8oKSkgewogICAgICAgICAgc3RyaW5nUGllY2VXaXRoWmVyb18gPSBvdGhlci5zdHJpbmdQaWVjZVdpdGhaZXJvXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzQ29yZFdpdGhaZXJvKCkpIHsKICAgICAgICAgIGNvcmRXaXRoWmVyb18gPSBvdGhlci5jb3JkV2l0aFplcm9fOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNSZXBsYWNlbWVudFN0cmluZygpKSB7CiAgICAgICAgICByZXBsYWNlbWVudFN0cmluZ18gPSBvdGhlci5yZXBsYWNlbWVudFN0cmluZ187CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgZXNjYXBlZEJ5dGVzXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgbGFyZ2VVaW50MzJfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgbGFyZ2VVaW50NjRfID0gaW5wdXQucmVhZFVJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgICAgY2FzZSAzMjogewogICAgICAgICAgICAgICAgc21hbGxJbnQzMl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMgogICAgICAgICAgICAgIGNhc2UgNDA6IHsKICAgICAgICAgICAgICAgIHNtYWxsSW50NjRfID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAKICAgICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgICB1dGY4U3RyaW5nXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA2MTogewogICAgICAgICAgICAgICAgemVyb0Zsb2F0XyA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDYxCiAgICAgICAgICAgICAgY2FzZSA2OTogewogICAgICAgICAgICAgICAgb25lRmxvYXRfID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNjkKICAgICAgICAgICAgICBjYXNlIDc3OiB7CiAgICAgICAgICAgICAgICBzbWFsbEZsb2F0XyA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc3CiAgICAgICAgICAgICAgY2FzZSA4NTogewogICAgICAgICAgICAgICAgbmVnYXRpdmVPbmVGbG9hdF8gPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4NQogICAgICAgICAgICAgIGNhc2UgOTM6IHsKICAgICAgICAgICAgICAgIG5lZ2F0aXZlRmxvYXRfID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTMKICAgICAgICAgICAgICBjYXNlIDEwMTogewogICAgICAgICAgICAgICAgbGFyZ2VGbG9hdF8gPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDEKICAgICAgICAgICAgICBjYXNlIDEwOTogewogICAgICAgICAgICAgICAgc21hbGxOZWdhdGl2ZUZsb2F0XyA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwOQogICAgICAgICAgICAgIGNhc2UgMTEzOiB7CiAgICAgICAgICAgICAgICBpbmZEb3VibGVfID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExMwogICAgICAgICAgICAgIGNhc2UgMTIxOiB7CiAgICAgICAgICAgICAgICBuZWdJbmZEb3VibGVfID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMQogICAgICAgICAgICAgIGNhc2UgMTI5OiB7CiAgICAgICAgICAgICAgICBuYW5Eb3VibGVfID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyOQogICAgICAgICAgICAgIGNhc2UgMTQxOiB7CiAgICAgICAgICAgICAgICBpbmZGbG9hdF8gPSBpbnB1dC5yZWFkRmxvYXQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDEKICAgICAgICAgICAgICBjYXNlIDE0OTogewogICAgICAgICAgICAgICAgbmVnSW5mRmxvYXRfID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTQ5CiAgICAgICAgICAgICAgY2FzZSAxNTc6IHsKICAgICAgICAgICAgICAgIG5hbkZsb2F0XyA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE1NwogICAgICAgICAgICAgIGNhc2UgMTYyOiB7CiAgICAgICAgICAgICAgICBjcHBUcmlncmFwaF8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjIKICAgICAgICAgICAgICBjYXNlIDE2ODogewogICAgICAgICAgICAgICAgcmVhbGx5U21hbGxJbnQzMl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjgKICAgICAgICAgICAgICBjYXNlIDE3NjogewogICAgICAgICAgICAgICAgcmVhbGx5U21hbGxJbnQ2NF8gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzYKICAgICAgICAgICAgICBjYXNlIDE4NjogewogICAgICAgICAgICAgICAgc3RyaW5nV2l0aFplcm9fID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTg2CiAgICAgICAgICAgICAgY2FzZSAxOTQ6IHsKICAgICAgICAgICAgICAgIGJ5dGVzV2l0aFplcm9fID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTk0CiAgICAgICAgICAgICAgY2FzZSAyMDI6IHsKICAgICAgICAgICAgICAgIHN0cmluZ1BpZWNlV2l0aFplcm9fID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjAyCiAgICAgICAgICAgICAgY2FzZSAyMTA6IHsKICAgICAgICAgICAgICAgIGNvcmRXaXRoWmVyb18gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMTAKICAgICAgICAgICAgICBjYXNlIDIxODogewogICAgICAgICAgICAgICAgcmVwbGFjZW1lbnRTdHJpbmdfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjE4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGVzY2FwZWRCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmJ5dGVzRGVmYXVsdFZhbHVlKCJcMDAwXDAwMVwwMDdcMDEwXDAxNFxuXHJcdFwwMTNcXFwnXCJcMzc2Iik7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBlc2NhcGVkX2J5dGVzID0gMSBbZGVmYXVsdCA9ICImIzkyOzAwMCYjOTI7MDAxJiM5MjswMDcmIzkyOzAxMCYjOTI7MDE0JiM5MjtuJiM5MjtyJiM5Mjt0JiM5MjswMTMmIzkyOyYjOTI7JiM5MjsnJiM5MjsiJiM5MjszNzYiXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZXNjYXBlZEJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRXNjYXBlZEJ5dGVzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZXNjYXBlZF9ieXRlcyA9IDEgW2RlZmF1bHQgPSAiJiM5MjswMDAmIzkyOzAwMSYjOTI7MDA3JiM5MjswMTAmIzkyOzAxNCYjOTI7biYjOTI7ciYjOTI7dCYjOTI7MDEzJiM5MjsmIzkyOyYjOTI7JyYjOTI7IiYjOTI7Mzc2Il07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBlc2NhcGVkQnl0ZXMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RXNjYXBlZEJ5dGVzKCkgewogICAgICAgIHJldHVybiBlc2NhcGVkQnl0ZXNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBlc2NhcGVkX2J5dGVzID0gMSBbZGVmYXVsdCA9ICImIzkyOzAwMCYjOTI7MDAxJiM5MjswMDcmIzkyOzAxMCYjOTI7MDE0JiM5MjtuJiM5MjtyJiM5Mjt0JiM5MjswMTMmIzkyOyYjOTI7JiM5MjsnJiM5MjsiJiM5MjszNzYiXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZXNjYXBlZEJ5dGVzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RXNjYXBlZEJ5dGVzKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZXNjYXBlZEJ5dGVzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZXNjYXBlZF9ieXRlcyA9IDEgW2RlZmF1bHQgPSAiJiM5MjswMDAmIzkyOzAwMSYjOTI7MDA3JiM5MjswMTAmIzkyOzAxNCYjOTI7biYjOTI7ciYjOTI7dCYjOTI7MDEzJiM5MjsmIzkyOyYjOTI7JyYjOTI7IiYjOTI7Mzc2Il07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckVzY2FwZWRCeXRlcygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgZXNjYXBlZEJ5dGVzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldEVzY2FwZWRCeXRlcygpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBsYXJnZVVpbnQzMl8gPSAtMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBsYXJnZV91aW50MzIgPSAyIFtkZWZhdWx0ID0gNDI5NDk2NzI5NV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxhcmdlVWludDMyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzTGFyZ2VVaW50MzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgbGFyZ2VfdWludDMyID0gMiBbZGVmYXVsdCA9IDQyOTQ5NjcyOTVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbGFyZ2VVaW50MzIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0TGFyZ2VVaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIGxhcmdlVWludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIGxhcmdlX3VpbnQzMiA9IDIgW2RlZmF1bHQgPSA0Mjk0OTY3Mjk1XTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbGFyZ2VVaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMYXJnZVVpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgbGFyZ2VVaW50MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgbGFyZ2VfdWludDMyID0gMiBbZGVmYXVsdCA9IDQyOTQ5NjcyOTVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJMYXJnZVVpbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgbGFyZ2VVaW50MzJfID0gLTE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBsYXJnZVVpbnQ2NF8gPSAtMUw7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgbGFyZ2VfdWludDY0ID0gMyBbZGVmYXVsdCA9IDE4NDQ2NzQ0MDczNzA5NTUxNjE1XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbGFyZ2VVaW50NjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMYXJnZVVpbnQ2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBsYXJnZV91aW50NjQgPSAzIFtkZWZhdWx0ID0gMTg0NDY3NDQwNzM3MDk1NTE2MTVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbGFyZ2VVaW50NjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldExhcmdlVWludDY0KCkgewogICAgICAgIHJldHVybiBsYXJnZVVpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBsYXJnZV91aW50NjQgPSAzIFtkZWZhdWx0ID0gMTg0NDY3NDQwNzM3MDk1NTE2MTVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBsYXJnZVVpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExhcmdlVWludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgbGFyZ2VVaW50NjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgbGFyZ2VfdWludDY0ID0gMyBbZGVmYXVsdCA9IDE4NDQ2NzQ0MDczNzA5NTUxNjE1XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTGFyZ2VVaW50NjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGxhcmdlVWludDY0XyA9IC0xTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgc21hbGxJbnQzMl8gPSAtMjE0NzQ4MzY0NzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHNtYWxsX2ludDMyID0gNCBbZGVmYXVsdCA9IC0yMTQ3NDgzNjQ3XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc21hbGxJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1NtYWxsSW50MzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBzbWFsbF9pbnQzMiA9IDQgW2RlZmF1bHQgPSAtMjE0NzQ4MzY0N107PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzbWFsbEludDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNtYWxsSW50MzIoKSB7CiAgICAgICAgcmV0dXJuIHNtYWxsSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBzbWFsbF9pbnQzMiA9IDQgW2RlZmF1bHQgPSAtMjE0NzQ4MzY0N107PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHNtYWxsSW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTbWFsbEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBzbWFsbEludDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgc21hbGxfaW50MzIgPSA0IFtkZWZhdWx0ID0gLTIxNDc0ODM2NDddOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTbWFsbEludDMyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBzbWFsbEludDMyXyA9IC0yMTQ3NDgzNjQ3OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgc21hbGxJbnQ2NF8gPSAtOTIyMzM3MjAzNjg1NDc3NTgwN0w7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBzbWFsbF9pbnQ2NCA9IDUgW2RlZmF1bHQgPSAtOTIyMzM3MjAzNjg1NDc3NTgwN107PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNtYWxsSW50NjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTbWFsbEludDY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgc21hbGxfaW50NjQgPSA1IFtkZWZhdWx0ID0gLTkyMjMzNzIwMzY4NTQ3NzU4MDddOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgc21hbGxJbnQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0U21hbGxJbnQ2NCgpIHsKICAgICAgICByZXR1cm4gc21hbGxJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IHNtYWxsX2ludDY0ID0gNSBbZGVmYXVsdCA9IC05MjIzMzcyMDM2ODU0Nzc1ODA3XTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc21hbGxJbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFNtYWxsSW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBzbWFsbEludDY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgc21hbGxfaW50NjQgPSA1IFtkZWZhdWx0ID0gLTkyMjMzNzIwMzY4NTQ3NzU4MDddOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTbWFsbEludDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBzbWFsbEludDY0XyA9IC05MjIzMzcyMDM2ODU0Nzc1ODA3TDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgcmVhbGx5U21hbGxJbnQzMl8gPSAtMjE0NzQ4MzY0ODsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHJlYWxseV9zbWFsbF9pbnQzMiA9IDIxIFtkZWZhdWx0ID0gLTIxNDc0ODM2NDhdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZWFsbHlTbWFsbEludDMyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUmVhbGx5U21hbGxJbnQzMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHJlYWxseV9zbWFsbF9pbnQzMiA9IDIxIFtkZWZhdWx0ID0gLTIxNDc0ODM2NDhdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVhbGx5U21hbGxJbnQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRSZWFsbHlTbWFsbEludDMyKCkgewogICAgICAgIHJldHVybiByZWFsbHlTbWFsbEludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgcmVhbGx5X3NtYWxsX2ludDMyID0gMjEgW2RlZmF1bHQgPSAtMjE0NzQ4MzY0OF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlYWxseVNtYWxsSW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZWFsbHlTbWFsbEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICByZWFsbHlTbWFsbEludDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgcmVhbGx5X3NtYWxsX2ludDMyID0gMjEgW2RlZmF1bHQgPSAtMjE0NzQ4MzY0OF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlYWxseVNtYWxsSW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIHJlYWxseVNtYWxsSW50MzJfID0gLTIxNDc0ODM2NDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyByZWFsbHlTbWFsbEludDY0XyA9IC05MjIzMzcyMDM2ODU0Nzc1ODA4TDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IHJlYWxseV9zbWFsbF9pbnQ2NCA9IDIyIFtkZWZhdWx0ID0gLTkyMjMzNzIwMzY4NTQ3NzU4MDhdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZWFsbHlTbWFsbEludDY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUmVhbGx5U21hbGxJbnQ2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IHJlYWxseV9zbWFsbF9pbnQ2NCA9IDIyIFtkZWZhdWx0ID0gLTkyMjMzNzIwMzY4NTQ3NzU4MDhdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVhbGx5U21hbGxJbnQ2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0UmVhbGx5U21hbGxJbnQ2NCgpIHsKICAgICAgICByZXR1cm4gcmVhbGx5U21hbGxJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IHJlYWxseV9zbWFsbF9pbnQ2NCA9IDIyIFtkZWZhdWx0ID0gLTkyMjMzNzIwMzY4NTQ3NzU4MDhdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZWFsbHlTbWFsbEludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVhbGx5U21hbGxJbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIHJlYWxseVNtYWxsSW50NjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCByZWFsbHlfc21hbGxfaW50NjQgPSAyMiBbZGVmYXVsdCA9IC05MjIzMzcyMDM2ODU0Nzc1ODA4XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVhbGx5U21hbGxJbnQ2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgcmVhbGx5U21hbGxJbnQ2NF8gPSAtOTIyMzM3MjAzNjg1NDc3NTgwOEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCB1dGY4U3RyaW5nXyA9IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuc3RyaW5nRGVmYXVsdFZhbHVlKCJcMzQxXDIxMFwyNjQiKTsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlIGhlcmUgaXMgVVRGLTggZm9yICImIzkyO3UxMjM0Ii4gIChXZSBjb3VsZCBhbHNvIGp1c3QgdHlwZQogICAgICAgKiB0aGUgVVRGLTggdGV4dCBkaXJlY3RseSBpbnRvIHRoaXMgdGV4dCBmaWxlIHJhdGhlciB0aGFuIGVzY2FwZSBpdCwgYnV0CiAgICAgICAqIGxvdHMgb2YgcGVvcGxlIHVzZSBlZGl0b3JzIHRoYXQgd291bGQgYmUgY29uZnVzZWQgYnkgdGhpcy4pCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgdXRmOF9zdHJpbmcgPSA2IFtkZWZhdWx0ID0gIiYjOTI7MzQxJiM5MjsyMTAmIzkyOzI2NCJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSB1dGY4U3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1V0ZjhTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBoZXJlIGlzIFVURi04IGZvciAiJiM5Mjt1MTIzNCIuICAoV2UgY291bGQgYWxzbyBqdXN0IHR5cGUKICAgICAgICogdGhlIFVURi04IHRleHQgZGlyZWN0bHkgaW50byB0aGlzIHRleHQgZmlsZSByYXRoZXIgdGhhbiBlc2NhcGUgaXQsIGJ1dAogICAgICAgKiBsb3RzIG9mIHBlb3BsZSB1c2UgZWRpdG9ycyB0aGF0IHdvdWxkIGJlIGNvbmZ1c2VkIGJ5IHRoaXMuKQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHV0Zjhfc3RyaW5nID0gNiBbZGVmYXVsdCA9ICImIzkyOzM0MSYjOTI7MjEwJiM5MjsyNjQiXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHV0ZjhTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRVdGY4U3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gdXRmOFN0cmluZ187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICB1dGY4U3RyaW5nXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBoZXJlIGlzIFVURi04IGZvciAiJiM5Mjt1MTIzNCIuICAoV2UgY291bGQgYWxzbyBqdXN0IHR5cGUKICAgICAgICogdGhlIFVURi04IHRleHQgZGlyZWN0bHkgaW50byB0aGlzIHRleHQgZmlsZSByYXRoZXIgdGhhbiBlc2NhcGUgaXQsIGJ1dAogICAgICAgKiBsb3RzIG9mIHBlb3BsZSB1c2UgZWRpdG9ycyB0aGF0IHdvdWxkIGJlIGNvbmZ1c2VkIGJ5IHRoaXMuKQogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHV0Zjhfc3RyaW5nID0gNiBbZGVmYXVsdCA9ICImIzkyOzM0MSYjOTI7MjEwJiM5MjsyNjQiXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciB1dGY4U3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0VXRmOFN0cmluZ0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gdXRmOFN0cmluZ187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIHV0ZjhTdHJpbmdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlIGRlZmF1bHQgdmFsdWUgaGVyZSBpcyBVVEYtOCBmb3IgIiYjOTI7dTEyMzQiLiAgKFdlIGNvdWxkIGFsc28ganVzdCB0eXBlCiAgICAgICAqIHRoZSBVVEYtOCB0ZXh0IGRpcmVjdGx5IGludG8gdGhpcyB0ZXh0IGZpbGUgcmF0aGVyIHRoYW4gZXNjYXBlIGl0LCBidXQKICAgICAgICogbG90cyBvZiBwZW9wbGUgdXNlIGVkaXRvcnMgdGhhdCB3b3VsZCBiZSBjb25mdXNlZCBieSB0aGlzLikKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyB1dGY4X3N0cmluZyA9IDYgW2RlZmF1bHQgPSAiJiM5MjszNDEmIzkyOzIxMCYjOTI7MjY0Il07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHV0ZjhTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRVdGY4U3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgdXRmOFN0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlIGhlcmUgaXMgVVRGLTggZm9yICImIzkyO3UxMjM0Ii4gIChXZSBjb3VsZCBhbHNvIGp1c3QgdHlwZQogICAgICAgKiB0aGUgVVRGLTggdGV4dCBkaXJlY3RseSBpbnRvIHRoaXMgdGV4dCBmaWxlIHJhdGhlciB0aGFuIGVzY2FwZSBpdCwgYnV0CiAgICAgICAqIGxvdHMgb2YgcGVvcGxlIHVzZSBlZGl0b3JzIHRoYXQgd291bGQgYmUgY29uZnVzZWQgYnkgdGhpcy4pCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgdXRmOF9zdHJpbmcgPSA2IFtkZWZhdWx0ID0gIiYjOTI7MzQxJiM5MjsyMTAmIzkyOzI2NCJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVdGY4U3RyaW5nKCkgewogICAgICAgIHV0ZjhTdHJpbmdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0VXRmOFN0cmluZygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlIGRlZmF1bHQgdmFsdWUgaGVyZSBpcyBVVEYtOCBmb3IgIiYjOTI7dTEyMzQiLiAgKFdlIGNvdWxkIGFsc28ganVzdCB0eXBlCiAgICAgICAqIHRoZSBVVEYtOCB0ZXh0IGRpcmVjdGx5IGludG8gdGhpcyB0ZXh0IGZpbGUgcmF0aGVyIHRoYW4gZXNjYXBlIGl0LCBidXQKICAgICAgICogbG90cyBvZiBwZW9wbGUgdXNlIGVkaXRvcnMgdGhhdCB3b3VsZCBiZSBjb25mdXNlZCBieSB0aGlzLikKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyB1dGY4X3N0cmluZyA9IDYgW2RlZmF1bHQgPSAiJiM5MjszNDEmIzkyOzIxMCYjOTI7MjY0Il07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciB1dGY4U3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VXRmOFN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICB1dGY4U3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmbG9hdCB6ZXJvRmxvYXRfIDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRlc3RzIGZvciBzaW5nbGUtcHJlY2lzaW9uIGZsb2F0aW5nLXBvaW50IHZhbHVlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHplcm9fZmxvYXQgPSA3IFtkZWZhdWx0ID0gMF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHplcm9GbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1plcm9GbG9hdCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRlc3RzIGZvciBzaW5nbGUtcHJlY2lzaW9uIGZsb2F0aW5nLXBvaW50IHZhbHVlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHplcm9fZmxvYXQgPSA3IFtkZWZhdWx0ID0gMF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSB6ZXJvRmxvYXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRaZXJvRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuIHplcm9GbG9hdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRlc3RzIGZvciBzaW5nbGUtcHJlY2lzaW9uIGZsb2F0aW5nLXBvaW50IHZhbHVlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHplcm9fZmxvYXQgPSA3IFtkZWZhdWx0ID0gMF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHplcm9GbG9hdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFplcm9GbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICB6ZXJvRmxvYXRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUZXN0cyBmb3Igc2luZ2xlLXByZWNpc2lvbiBmbG9hdGluZy1wb2ludCB2YWx1ZXMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCB6ZXJvX2Zsb2F0ID0gNyBbZGVmYXVsdCA9IDBdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJaZXJvRmxvYXQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIHplcm9GbG9hdF8gPSAwRjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmbG9hdCBvbmVGbG9hdF8gPSAxRjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG9uZV9mbG9hdCA9IDggW2RlZmF1bHQgPSAxXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPbmVGbG9hdCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG9uZV9mbG9hdCA9IDggW2RlZmF1bHQgPSAxXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9uZUZsb2F0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0T25lRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuIG9uZUZsb2F0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgb25lX2Zsb2F0ID0gOCBbZGVmYXVsdCA9IDFdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVGbG9hdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZUZsb2F0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIG9uZUZsb2F0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgb25lX2Zsb2F0ID0gOCBbZGVmYXVsdCA9IDFdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVGbG9hdCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb25lRmxvYXRfID0gMUY7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmxvYXQgc21hbGxGbG9hdF8gPSAxLjVGOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgc21hbGxfZmxvYXQgPSA5IFtkZWZhdWx0ID0gMS41XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc21hbGxGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1NtYWxsRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBzbWFsbF9mbG9hdCA9IDkgW2RlZmF1bHQgPSAxLjVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgc21hbGxGbG9hdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldFNtYWxsRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuIHNtYWxsRmxvYXRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBzbWFsbF9mbG9hdCA9IDkgW2RlZmF1bHQgPSAxLjVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzbWFsbEZsb2F0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U21hbGxGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBzbWFsbEZsb2F0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgc21hbGxfZmxvYXQgPSA5IFtkZWZhdWx0ID0gMS41XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU21hbGxGbG9hdCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgc21hbGxGbG9hdF8gPSAxLjVGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IG5lZ2F0aXZlT25lRmxvYXRfID0gLTFGOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbmVnYXRpdmVfb25lX2Zsb2F0ID0gMTAgW2RlZmF1bHQgPSAtMV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lZ2F0aXZlT25lRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZWdhdGl2ZU9uZUZsb2F0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbmVnYXRpdmVfb25lX2Zsb2F0ID0gMTAgW2RlZmF1bHQgPSAtMV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBuZWdhdGl2ZU9uZUZsb2F0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0TmVnYXRpdmVPbmVGbG9hdCgpIHsKICAgICAgICByZXR1cm4gbmVnYXRpdmVPbmVGbG9hdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG5lZ2F0aXZlX29uZV9mbG9hdCA9IDEwIFtkZWZhdWx0ID0gLTFdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBuZWdhdGl2ZU9uZUZsb2F0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TmVnYXRpdmVPbmVGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBuZWdhdGl2ZU9uZUZsb2F0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbmVnYXRpdmVfb25lX2Zsb2F0ID0gMTAgW2RlZmF1bHQgPSAtMV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck5lZ2F0aXZlT25lRmxvYXQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG5lZ2F0aXZlT25lRmxvYXRfID0gLTFGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IG5lZ2F0aXZlRmxvYXRfID0gLTEuNUY7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBuZWdhdGl2ZV9mbG9hdCA9IDExIFtkZWZhdWx0ID0gLTEuNV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lZ2F0aXZlRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZWdhdGl2ZUZsb2F0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbmVnYXRpdmVfZmxvYXQgPSAxMSBbZGVmYXVsdCA9IC0xLjVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbmVnYXRpdmVGbG9hdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldE5lZ2F0aXZlRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuIG5lZ2F0aXZlRmxvYXRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBuZWdhdGl2ZV9mbG9hdCA9IDExIFtkZWZhdWx0ID0gLTEuNV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG5lZ2F0aXZlRmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXROZWdhdGl2ZUZsb2F0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIG5lZ2F0aXZlRmxvYXRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBuZWdhdGl2ZV9mbG9hdCA9IDExIFtkZWZhdWx0ID0gLTEuNV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck5lZ2F0aXZlRmxvYXQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG5lZ2F0aXZlRmxvYXRfID0gLTEuNUY7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmxvYXQgbGFyZ2VGbG9hdF8gPSAyZSswOEY7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBVc2luZyBleHBvbmVudHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGxhcmdlX2Zsb2F0ID0gMTIgW2RlZmF1bHQgPSAyZSswOF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxhcmdlRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMYXJnZUZsb2F0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVXNpbmcgZXhwb25lbnRzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBsYXJnZV9mbG9hdCA9IDEyIFtkZWZhdWx0ID0gMmUrMDhdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbGFyZ2VGbG9hdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldExhcmdlRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuIGxhcmdlRmxvYXRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBVc2luZyBleHBvbmVudHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGxhcmdlX2Zsb2F0ID0gMTIgW2RlZmF1bHQgPSAyZSswOF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGxhcmdlRmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRMYXJnZUZsb2F0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGxhcmdlRmxvYXRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBVc2luZyBleHBvbmVudHMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGxhcmdlX2Zsb2F0ID0gMTIgW2RlZmF1bHQgPSAyZSswOF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxhcmdlRmxvYXQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIGxhcmdlRmxvYXRfID0gMmUrMDhGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IHNtYWxsTmVnYXRpdmVGbG9hdF8gPSAtOGUtMjhGOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgc21hbGxfbmVnYXRpdmVfZmxvYXQgPSAxMyBbZGVmYXVsdCA9IC04ZS0yOF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNtYWxsTmVnYXRpdmVGbG9hdCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1NtYWxsTmVnYXRpdmVGbG9hdCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHNtYWxsX25lZ2F0aXZlX2Zsb2F0ID0gMTMgW2RlZmF1bHQgPSAtOGUtMjhdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgc21hbGxOZWdhdGl2ZUZsb2F0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0U21hbGxOZWdhdGl2ZUZsb2F0KCkgewogICAgICAgIHJldHVybiBzbWFsbE5lZ2F0aXZlRmxvYXRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBzbWFsbF9uZWdhdGl2ZV9mbG9hdCA9IDEzIFtkZWZhdWx0ID0gLThlLTI4XTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc21hbGxOZWdhdGl2ZUZsb2F0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U21hbGxOZWdhdGl2ZUZsb2F0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIHNtYWxsTmVnYXRpdmVGbG9hdF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IHNtYWxsX25lZ2F0aXZlX2Zsb2F0ID0gMTMgW2RlZmF1bHQgPSAtOGUtMjhdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTbWFsbE5lZ2F0aXZlRmxvYXQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIHNtYWxsTmVnYXRpdmVGbG9hdF8gPSAtOGUtMjhGOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGRvdWJsZSBpbmZEb3VibGVfID0gRG91YmxlLlBPU0lUSVZFX0lORklOSVRZOwogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGV4dCBmb3Igbm9uZmluaXRlIGZsb2F0aW5nLXBvaW50IHZhbHVlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBpbmZfZG91YmxlID0gMTQgW2RlZmF1bHQgPSBpbmZdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbmZEb3VibGUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbmZEb3VibGUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUZXh0IGZvciBub25maW5pdGUgZmxvYXRpbmctcG9pbnQgdmFsdWVzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGluZl9kb3VibGUgPSAxNCBbZGVmYXVsdCA9IGluZl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBpbmZEb3VibGUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBkb3VibGUgZ2V0SW5mRG91YmxlKCkgewogICAgICAgIHJldHVybiBpbmZEb3VibGVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUZXh0IGZvciBub25maW5pdGUgZmxvYXRpbmctcG9pbnQgdmFsdWVzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIGluZl9kb3VibGUgPSAxNCBbZGVmYXVsdCA9IGluZl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGluZkRvdWJsZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEluZkRvdWJsZShkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgaW5mRG91YmxlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGV4dCBmb3Igbm9uZmluaXRlIGZsb2F0aW5nLXBvaW50IHZhbHVlcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBpbmZfZG91YmxlID0gMTQgW2RlZmF1bHQgPSBpbmZdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJJbmZEb3VibGUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDgwMDApOwogICAgICAgIGluZkRvdWJsZV8gPSBEb3VibGUuUE9TSVRJVkVfSU5GSU5JVFk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZG91YmxlIG5lZ0luZkRvdWJsZV8gPSBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgbmVnX2luZl9kb3VibGUgPSAxNSBbZGVmYXVsdCA9IC1pbmZdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBuZWdJbmZEb3VibGUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOZWdJbmZEb3VibGUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgbmVnX2luZl9kb3VibGUgPSAxNSBbZGVmYXVsdCA9IC1pbmZdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbmVnSW5mRG91YmxlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldE5lZ0luZkRvdWJsZSgpIHsKICAgICAgICByZXR1cm4gbmVnSW5mRG91YmxlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIG5lZ19pbmZfZG91YmxlID0gMTUgW2RlZmF1bHQgPSAtaW5mXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbmVnSW5mRG91YmxlIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TmVnSW5mRG91YmxlKGRvdWJsZSB2YWx1ZSkgewoKICAgICAgICBuZWdJbmZEb3VibGVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBkb3VibGUgbmVnX2luZl9kb3VibGUgPSAxNSBbZGVmYXVsdCA9IC1pbmZdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJOZWdJbmZEb3VibGUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG5lZ0luZkRvdWJsZV8gPSBEb3VibGUuTkVHQVRJVkVfSU5GSU5JVFk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZG91YmxlIG5hbkRvdWJsZV8gPSBEb3VibGUuTmFOOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIG5hbl9kb3VibGUgPSAxNiBbZGVmYXVsdCA9IG5hbl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5hbkRvdWJsZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc05hbkRvdWJsZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGRvdWJsZSBuYW5fZG91YmxlID0gMTYgW2RlZmF1bHQgPSBuYW5dOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbmFuRG91YmxlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldE5hbkRvdWJsZSgpIHsKICAgICAgICByZXR1cm4gbmFuRG91YmxlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIG5hbl9kb3VibGUgPSAxNiBbZGVmYXVsdCA9IG5hbl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG5hbkRvdWJsZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE5hbkRvdWJsZShkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgbmFuRG91YmxlXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZG91YmxlIG5hbl9kb3VibGUgPSAxNiBbZGVmYXVsdCA9IG5hbl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck5hbkRvdWJsZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgbmFuRG91YmxlXyA9IERvdWJsZS5OYU47CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmxvYXQgaW5mRmxvYXRfID0gRmxvYXQuUE9TSVRJVkVfSU5GSU5JVFk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBpbmZfZmxvYXQgPSAxNyBbZGVmYXVsdCA9IGluZl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGluZkZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzSW5mRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBpbmZfZmxvYXQgPSAxNyBbZGVmYXVsdCA9IGluZl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBpbmZGbG9hdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZsb2F0IGdldEluZkZsb2F0KCkgewogICAgICAgIHJldHVybiBpbmZGbG9hdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGluZl9mbG9hdCA9IDE3IFtkZWZhdWx0ID0gaW5mXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgaW5mRmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRJbmZGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBpbmZGbG9hdF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGluZl9mbG9hdCA9IDE3IFtkZWZhdWx0ID0gaW5mXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFySW5mRmxvYXQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwNDAwMDApOwogICAgICAgIGluZkZsb2F0XyA9IEZsb2F0LlBPU0lUSVZFX0lORklOSVRZOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IG5lZ0luZkZsb2F0XyA9IEZsb2F0Lk5FR0FUSVZFX0lORklOSVRZOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbmVnX2luZl9mbG9hdCA9IDE4IFtkZWZhdWx0ID0gLWluZl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG5lZ0luZkZsb2F0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzTmVnSW5mRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBuZWdfaW5mX2Zsb2F0ID0gMTggW2RlZmF1bHQgPSAtaW5mXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG5lZ0luZkZsb2F0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0TmVnSW5mRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuIG5lZ0luZkZsb2F0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbmVnX2luZl9mbG9hdCA9IDE4IFtkZWZhdWx0ID0gLWluZl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG5lZ0luZkZsb2F0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TmVnSW5mRmxvYXQoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgbmVnSW5mRmxvYXRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBuZWdfaW5mX2Zsb2F0ID0gMTggW2RlZmF1bHQgPSAtaW5mXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTmVnSW5mRmxvYXQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIG5lZ0luZkZsb2F0XyA9IEZsb2F0Lk5FR0FUSVZFX0lORklOSVRZOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGZsb2F0IG5hbkZsb2F0XyA9IEZsb2F0Lk5hTjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG5hbl9mbG9hdCA9IDE5IFtkZWZhdWx0ID0gbmFuXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbmFuRmxvYXQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNOYW5GbG9hdCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IG5hbl9mbG9hdCA9IDE5IFtkZWZhdWx0ID0gbmFuXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG5hbkZsb2F0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmxvYXQgZ2V0TmFuRmxvYXQoKSB7CiAgICAgICAgcmV0dXJuIG5hbkZsb2F0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbmFuX2Zsb2F0ID0gMTkgW2RlZmF1bHQgPSBuYW5dOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBuYW5GbG9hdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE5hbkZsb2F0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIG5hbkZsb2F0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgbmFuX2Zsb2F0ID0gMTkgW2RlZmF1bHQgPSBuYW5dOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJOYW5GbG9hdCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgbmFuRmxvYXRfID0gRmxvYXQuTmFOOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgY3BwVHJpZ3JhcGhfID0gIj8gPyA/PyA/PyA/Pz8gPz8vID8/LSI7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUZXN0cyBmb3IgQysrIHRyaWdyYXBocy4KICAgICAgICogVHJpZ3JhcGhzIHNob3VsZCBiZSBlc2NhcGVkIGluIEMrKyBnZW5lcmF0ZWQgZmlsZXMsIGJ1dCB0aGV5IHNob3VsZCBub3QgYmUKICAgICAgICogZXNjYXBlZCBmb3Igb3RoZXIgbGFuZ3VhZ2VzLgogICAgICAgKiBOb3RlIHRoYXQgaW4gLnByb3RvIGZpbGUsICImIzkyOz8iIGlzIGEgdmFsaWQgd2F5IHRvIGVzY2FwZSA/IGluIHN0cmluZwogICAgICAgKiBsaXRlcmFscy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjcHBfdHJpZ3JhcGggPSAyMCBbZGVmYXVsdCA9ICI/ID8gPz8gPz8gPz8/ID8/LyA/Py0iXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY3BwVHJpZ3JhcGggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzQ3BwVHJpZ3JhcGgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUZXN0cyBmb3IgQysrIHRyaWdyYXBocy4KICAgICAgICogVHJpZ3JhcGhzIHNob3VsZCBiZSBlc2NhcGVkIGluIEMrKyBnZW5lcmF0ZWQgZmlsZXMsIGJ1dCB0aGV5IHNob3VsZCBub3QgYmUKICAgICAgICogZXNjYXBlZCBmb3Igb3RoZXIgbGFuZ3VhZ2VzLgogICAgICAgKiBOb3RlIHRoYXQgaW4gLnByb3RvIGZpbGUsICImIzkyOz8iIGlzIGEgdmFsaWQgd2F5IHRvIGVzY2FwZSA/IGluIHN0cmluZwogICAgICAgKiBsaXRlcmFscy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjcHBfdHJpZ3JhcGggPSAyMCBbZGVmYXVsdCA9ICI/ID8gPz8gPz8gPz8/ID8/LyA/Py0iXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNwcFRyaWdyYXBoLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Q3BwVHJpZ3JhcGgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBjcHBUcmlncmFwaF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBjcHBUcmlncmFwaF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGVzdHMgZm9yIEMrKyB0cmlncmFwaHMuCiAgICAgICAqIFRyaWdyYXBocyBzaG91bGQgYmUgZXNjYXBlZCBpbiBDKysgZ2VuZXJhdGVkIGZpbGVzLCBidXQgdGhleSBzaG91bGQgbm90IGJlCiAgICAgICAqIGVzY2FwZWQgZm9yIG90aGVyIGxhbmd1YWdlcy4KICAgICAgICogTm90ZSB0aGF0IGluIC5wcm90byBmaWxlLCAiJiM5Mjs/IiBpcyBhIHZhbGlkIHdheSB0byBlc2NhcGUgPyBpbiBzdHJpbmcKICAgICAgICogbGl0ZXJhbHMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgY3BwX3RyaWdyYXBoID0gMjAgW2RlZmF1bHQgPSAiPyA/ID8/ID8/ID8/PyA/Py8gPz8tIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgY3BwVHJpZ3JhcGguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRDcHBUcmlncmFwaEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gY3BwVHJpZ3JhcGhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBjcHBUcmlncmFwaF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUZXN0cyBmb3IgQysrIHRyaWdyYXBocy4KICAgICAgICogVHJpZ3JhcGhzIHNob3VsZCBiZSBlc2NhcGVkIGluIEMrKyBnZW5lcmF0ZWQgZmlsZXMsIGJ1dCB0aGV5IHNob3VsZCBub3QgYmUKICAgICAgICogZXNjYXBlZCBmb3Igb3RoZXIgbGFuZ3VhZ2VzLgogICAgICAgKiBOb3RlIHRoYXQgaW4gLnByb3RvIGZpbGUsICImIzkyOz8iIGlzIGEgdmFsaWQgd2F5IHRvIGVzY2FwZSA/IGluIHN0cmluZwogICAgICAgKiBsaXRlcmFscy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjcHBfdHJpZ3JhcGggPSAyMCBbZGVmYXVsdCA9ICI/ID8gPz8gPz8gPz8/ID8/LyA/Py0iXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgY3BwVHJpZ3JhcGggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRDcHBUcmlncmFwaCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNwcFRyaWdyYXBoXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGVzdHMgZm9yIEMrKyB0cmlncmFwaHMuCiAgICAgICAqIFRyaWdyYXBocyBzaG91bGQgYmUgZXNjYXBlZCBpbiBDKysgZ2VuZXJhdGVkIGZpbGVzLCBidXQgdGhleSBzaG91bGQgbm90IGJlCiAgICAgICAqIGVzY2FwZWQgZm9yIG90aGVyIGxhbmd1YWdlcy4KICAgICAgICogTm90ZSB0aGF0IGluIC5wcm90byBmaWxlLCAiJiM5Mjs/IiBpcyBhIHZhbGlkIHdheSB0byBlc2NhcGUgPyBpbiBzdHJpbmcKICAgICAgICogbGl0ZXJhbHMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgY3BwX3RyaWdyYXBoID0gMjAgW2RlZmF1bHQgPSAiPyA/ID8/ID8/ID8/PyA/Py8gPz8tIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNwcFRyaWdyYXBoKCkgewogICAgICAgIGNwcFRyaWdyYXBoXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldENwcFRyaWdyYXBoKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUZXN0cyBmb3IgQysrIHRyaWdyYXBocy4KICAgICAgICogVHJpZ3JhcGhzIHNob3VsZCBiZSBlc2NhcGVkIGluIEMrKyBnZW5lcmF0ZWQgZmlsZXMsIGJ1dCB0aGV5IHNob3VsZCBub3QgYmUKICAgICAgICogZXNjYXBlZCBmb3Igb3RoZXIgbGFuZ3VhZ2VzLgogICAgICAgKiBOb3RlIHRoYXQgaW4gLnByb3RvIGZpbGUsICImIzkyOz8iIGlzIGEgdmFsaWQgd2F5IHRvIGVzY2FwZSA/IGluIHN0cmluZwogICAgICAgKiBsaXRlcmFscy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjcHBfdHJpZ3JhcGggPSAyMCBbZGVmYXVsdCA9ICI/ID8gPz8gPz8gPz8/ID8/LyA/Py0iXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGNwcFRyaWdyYXBoIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Q3BwVHJpZ3JhcGhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgY3BwVHJpZ3JhcGhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyaW5nV2l0aFplcm9fID0gImhlbFwwMDBsbyI7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBTdHJpbmcgZGVmYXVsdHMgY29udGFpbmluZyB0aGUgY2hhcmFjdGVyICcmIzkyOzAwMCcKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfd2l0aF96ZXJvID0gMjMgW2RlZmF1bHQgPSAiaGVsJiM5MjswMDBsbyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHJpbmdXaXRoWmVybyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHJpbmdXaXRoWmVybygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFN0cmluZyBkZWZhdWx0cyBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXIgJyYjOTI7MDAwJwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ193aXRoX3plcm8gPSAyMyBbZGVmYXVsdCA9ICJoZWwmIzkyOzAwMGxvIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzdHJpbmdXaXRoWmVyby4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ1dpdGhaZXJvKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nV2l0aFplcm9fOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgc3RyaW5nV2l0aFplcm9fID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFN0cmluZyBkZWZhdWx0cyBjb250YWluaW5nIHRoZSBjaGFyYWN0ZXIgJyYjOTI7MDAwJwogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ193aXRoX3plcm8gPSAyMyBbZGVmYXVsdCA9ICJoZWwmIzkyOzAwMGxvIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyaW5nV2l0aFplcm8uCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHJpbmdXaXRoWmVyb0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nV2l0aFplcm9fOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHJpbmdXaXRoWmVyb18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBTdHJpbmcgZGVmYXVsdHMgY29udGFpbmluZyB0aGUgY2hhcmFjdGVyICcmIzkyOzAwMCcKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfd2l0aF96ZXJvID0gMjMgW2RlZmF1bHQgPSAiaGVsJiM5MjswMDBsbyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzdHJpbmdXaXRoWmVybyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cmluZ1dpdGhaZXJvKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyaW5nV2l0aFplcm9fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBTdHJpbmcgZGVmYXVsdHMgY29udGFpbmluZyB0aGUgY2hhcmFjdGVyICcmIzkyOzAwMCcKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHJpbmdfd2l0aF96ZXJvID0gMjMgW2RlZmF1bHQgPSAiaGVsJiM5MjswMDBsbyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdHJpbmdXaXRoWmVybygpIHsKICAgICAgICBzdHJpbmdXaXRoWmVyb18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRTdHJpbmdXaXRoWmVybygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwNDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogU3RyaW5nIGRlZmF1bHRzIGNvbnRhaW5pbmcgdGhlIGNoYXJhY3RlciAnJiM5MjswMDAnCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX3dpdGhfemVybyA9IDIzIFtkZWZhdWx0ID0gImhlbCYjOTI7MDAwbG8iXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cmluZ1dpdGhaZXJvIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyaW5nV2l0aFplcm9CeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyaW5nV2l0aFplcm9fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBieXRlc1dpdGhaZXJvXyA9IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuYnl0ZXNEZWZhdWx0VmFsdWUoIndvclwwMDBsZCIpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgYnl0ZXNfd2l0aF96ZXJvID0gMjQgW2RlZmF1bHQgPSAid29yJiM5MjswMDBsZCJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBieXRlc1dpdGhaZXJvIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQnl0ZXNXaXRoWmVybygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGJ5dGVzX3dpdGhfemVybyA9IDI0IFtkZWZhdWx0ID0gIndvciYjOTI7MDAwbGQiXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzV2l0aFplcm8uCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0Qnl0ZXNXaXRoWmVybygpIHsKICAgICAgICByZXR1cm4gYnl0ZXNXaXRoWmVyb187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGJ5dGVzX3dpdGhfemVybyA9IDI0IFtkZWZhdWx0ID0gIndvciYjOTI7MDAwbGQiXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXNXaXRoWmVybyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJ5dGVzV2l0aFplcm8oY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBieXRlc1dpdGhaZXJvXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgYnl0ZXNfd2l0aF96ZXJvID0gMjQgW2RlZmF1bHQgPSAid29yJiM5MjswMDBsZCJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJCeXRlc1dpdGhaZXJvKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBieXRlc1dpdGhaZXJvXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldEJ5dGVzV2l0aFplcm8oKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHN0cmluZ1BpZWNlV2l0aFplcm9fID0gImFiXDAwMGMiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19waWVjZV93aXRoX3plcm8gPSAyNSBbZGVmYXVsdCA9ICJhYiYjOTI7MDAwYyIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyaW5nUGllY2VXaXRoWmVybyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHJpbmdQaWVjZVdpdGhaZXJvKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAxMDAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19waWVjZV93aXRoX3plcm8gPSAyNSBbZGVmYXVsdCA9ICJhYiYjOTI7MDAwYyIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cmluZ1BpZWNlV2l0aFplcm8uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHJpbmdQaWVjZVdpdGhaZXJvKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyaW5nUGllY2VXaXRoWmVyb187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHJpbmdQaWVjZVdpdGhaZXJvXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX3BpZWNlX3dpdGhfemVybyA9IDI1IFtkZWZhdWx0ID0gImFiJiM5MjswMDBjIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cmluZ1BpZWNlV2l0aFplcm8uCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHJpbmdQaWVjZVdpdGhaZXJvQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHJpbmdQaWVjZVdpdGhaZXJvXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgc3RyaW5nUGllY2VXaXRoWmVyb18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX3BpZWNlX3dpdGhfemVybyA9IDI1IFtkZWZhdWx0ID0gImFiJiM5MjswMDBjIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzdHJpbmdQaWVjZVdpdGhaZXJvIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyaW5nUGllY2VXaXRoWmVybygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cmluZ1BpZWNlV2l0aFplcm9fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyaW5nX3BpZWNlX3dpdGhfemVybyA9IDI1IFtkZWZhdWx0ID0gImFiJiM5MjswMDBjIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdHJpbmdQaWVjZVdpdGhaZXJvKCkgewogICAgICAgIHN0cmluZ1BpZWNlV2l0aFplcm9fID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0U3RyaW5nUGllY2VXaXRoWmVybygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cmluZ19waWVjZV93aXRoX3plcm8gPSAyNSBbZGVmYXVsdCA9ICJhYiYjOTI7MDAwYyIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cmluZ1BpZWNlV2l0aFplcm8gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHJpbmdQaWVjZVdpdGhaZXJvQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cmluZ1BpZWNlV2l0aFplcm9fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgY29yZFdpdGhaZXJvXyA9ICIxMlwwMDAzIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjb3JkX3dpdGhfemVybyA9IDI2IFtkZWZhdWx0ID0gIjEyJiM5MjswMDAzIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgY29yZFdpdGhaZXJvIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0NvcmRXaXRoWmVybygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjb3JkX3dpdGhfemVybyA9IDI2IFtkZWZhdWx0ID0gIjEyJiM5MjswMDAzIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvcmRXaXRoWmVyby4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldENvcmRXaXRoWmVybygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGNvcmRXaXRoWmVyb187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBjb3JkV2l0aFplcm9fID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjb3JkX3dpdGhfemVybyA9IDI2IFtkZWZhdWx0ID0gIjEyJiM5MjswMDAzIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBjb3JkV2l0aFplcm8uCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRDb3JkV2l0aFplcm9CeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGNvcmRXaXRoWmVyb187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGNvcmRXaXRoWmVyb18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgY29yZF93aXRoX3plcm8gPSAyNiBbZGVmYXVsdCA9ICIxMiYjOTI7MDAwMyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGNvcmRXaXRoWmVybyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENvcmRXaXRoWmVybygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGNvcmRXaXRoWmVyb18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjb3JkX3dpdGhfemVybyA9IDI2IFtkZWZhdWx0ID0gIjEyJiM5MjswMDAzIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQ29yZFdpdGhaZXJvKCkgewogICAgICAgIGNvcmRXaXRoWmVyb18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRDb3JkV2l0aFplcm8oKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMjAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBjb3JkX3dpdGhfemVybyA9IDI2IFtkZWZhdWx0ID0gIjEyJiM5MjswMDAzIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGNvcmRXaXRoWmVybyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENvcmRXaXRoWmVyb0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBjb3JkV2l0aFplcm9fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgcmVwbGFjZW1lbnRTdHJpbmdfID0gIiR7dW5rbm93bn0iOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHJlcGxhY2VtZW50X3N0cmluZyA9IDI3IFtkZWZhdWx0ID0gIiR7dW5rbm93bn0iXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVwbGFjZW1lbnRTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzUmVwbGFjZW1lbnRTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcmVwbGFjZW1lbnRfc3RyaW5nID0gMjcgW2RlZmF1bHQgPSAiJHt1bmtub3dufSJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVwbGFjZW1lbnRTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBsYWNlbWVudFN0cmluZygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHJlcGxhY2VtZW50U3RyaW5nXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIHJlcGxhY2VtZW50U3RyaW5nXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgcmVwbGFjZW1lbnRfc3RyaW5nID0gMjcgW2RlZmF1bHQgPSAiJHt1bmtub3dufSJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHJlcGxhY2VtZW50U3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0UmVwbGFjZW1lbnRTdHJpbmdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHJlcGxhY2VtZW50U3RyaW5nXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgcmVwbGFjZW1lbnRTdHJpbmdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHJlcGxhY2VtZW50X3N0cmluZyA9IDI3IFtkZWZhdWx0ID0gIiR7dW5rbm93bn0iXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwbGFjZW1lbnRTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBsYWNlbWVudFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHJlcGxhY2VtZW50U3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHJlcGxhY2VtZW50X3N0cmluZyA9IDI3IFtkZWZhdWx0ID0gIiR7dW5rbm93bn0iXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwbGFjZW1lbnRTdHJpbmcoKSB7CiAgICAgICAgcmVwbGFjZW1lbnRTdHJpbmdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0UmVwbGFjZW1lbnRTdHJpbmcoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyByZXBsYWNlbWVudF9zdHJpbmcgPSAyNyBbZGVmYXVsdCA9ICIke3Vua25vd259Il07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciByZXBsYWNlbWVudFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGxhY2VtZW50U3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHJlcGxhY2VtZW50U3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFNwYXJzZUVudW1NZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlNwYXJzZUVudW1NZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTcGFyc2VFbnVtIHNwYXJzZV9lbnVtID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNwYXJzZUVudW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1NwYXJzZUVudW0oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTcGFyc2VFbnVtIHNwYXJzZV9lbnVtID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzcGFyc2VFbnVtLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RTcGFyc2VFbnVtIGdldFNwYXJzZUVudW0oKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuU3BhcnNlRW51bU1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBTcGFyc2VFbnVtTWVzc2FnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5TcGFyc2VFbnVtTWVzc2FnZSkKICAgICAgU3BhcnNlRW51bU1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFNwYXJzZUVudW1NZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFNwYXJzZUVudW1NZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgU3BhcnNlRW51bU1lc3NhZ2UoKSB7CiAgICAgIHNwYXJzZUVudW1fID0gMTIzOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFNwYXJzZUVudW1NZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU3BhcnNlRW51bU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9TcGFyc2VFbnVtTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNQQVJTRV9FTlVNX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBzcGFyc2VFbnVtXyA9IDEyMzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTcGFyc2VFbnVtIHNwYXJzZV9lbnVtID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNwYXJzZUVudW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc1NwYXJzZUVudW0oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTcGFyc2VFbnVtIHNwYXJzZV9lbnVtID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzcGFyc2VFbnVtLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RTcGFyc2VFbnVtIGdldFNwYXJzZUVudW0oKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFNwYXJzZUVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0U3BhcnNlRW51bS5mb3JOdW1iZXIoc3BhcnNlRW51bV8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RTcGFyc2VFbnVtLlNQQVJTRV9BIDogcmVzdWx0OwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgxLCBzcGFyc2VFbnVtXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSgxLCBzcGFyc2VFbnVtXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TcGFyc2VFbnVtTWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TcGFyc2VFbnVtTWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlNwYXJzZUVudW1NZXNzYWdlKSBvYmo7CgogICAgICBpZiAoaGFzU3BhcnNlRW51bSgpICE9IG90aGVyLmhhc1NwYXJzZUVudW0oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzU3BhcnNlRW51bSgpKSB7CiAgICAgICAgaWYgKHNwYXJzZUVudW1fICE9IG90aGVyLnNwYXJzZUVudW1fKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzU3BhcnNlRW51bSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1BBUlNFX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHNwYXJzZUVudW1fOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlNwYXJzZUVudW1NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlNwYXJzZUVudW1NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlNwYXJzZUVudW1NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TcGFyc2VFbnVtTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlNwYXJzZUVudW1NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuU3BhcnNlRW51bU1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5TcGFyc2VFbnVtTWVzc2FnZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlNwYXJzZUVudW1NZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NwYXJzZUVudW1NZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NwYXJzZUVudW1NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlNwYXJzZUVudW1NZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBzcGFyc2VFbnVtXyA9IDEyMzsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU3BhcnNlRW51bU1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TcGFyc2VFbnVtTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlNwYXJzZUVudW1NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlNwYXJzZUVudW1NZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlNwYXJzZUVudW1NZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlNwYXJzZUVudW1NZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlNwYXJzZUVudW1NZXNzYWdlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3BhcnNlRW51bV8gPSBzcGFyc2VFbnVtXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TcGFyc2VFbnVtTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlNwYXJzZUVudW1NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzU3BhcnNlRW51bSgpKSB7CiAgICAgICAgICBzZXRTcGFyc2VFbnVtKG90aGVyLmdldFNwYXJzZUVudW0oKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RTcGFyc2VFbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RTcGFyc2VFbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHNwYXJzZUVudW1fID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBzcGFyc2VFbnVtXyA9IDEyMzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0U3BhcnNlRW51bSBzcGFyc2VfZW51bSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNwYXJzZUVudW0gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNTcGFyc2VFbnVtKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTcGFyc2VFbnVtIHNwYXJzZV9lbnVtID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHNwYXJzZUVudW0uCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RTcGFyc2VFbnVtIGdldFNwYXJzZUVudW0oKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0U3BhcnNlRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RTcGFyc2VFbnVtLmZvck51bWJlcihzcGFyc2VFbnVtXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0U3BhcnNlRW51bS5TUEFSU0VfQSA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RTcGFyc2VFbnVtIHNwYXJzZV9lbnVtID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3BhcnNlRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFNwYXJzZUVudW0ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0U3BhcnNlRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIHNwYXJzZUVudW1fID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0U3BhcnNlRW51bSBzcGFyc2VfZW51bSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclNwYXJzZUVudW0oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHNwYXJzZUVudW1fID0gMTIzOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlNwYXJzZUVudW1NZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5TcGFyc2VFbnVtTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3BhcnNlRW51bU1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TcGFyc2VFbnVtTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TcGFyc2VFbnVtTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFNwYXJzZUVudW1NZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFNwYXJzZUVudW1NZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgU3BhcnNlRW51bU1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxTcGFyc2VFbnVtTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxTcGFyc2VFbnVtTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TcGFyc2VFbnVtTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIE9uZVN0cmluZ09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5PbmVTdHJpbmcpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGF0YSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkYXRhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEYXRhKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkYXRhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkYXRhLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldERhdGEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBkYXRhLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXREYXRhQnl0ZXMoKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUZXN0IFN0cmluZyBhbmQgQnl0ZXM6IHN0cmluZyBpcyBmb3IgdmFsaWQgVVRGLTggc3RyaW5ncwogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuT25lU3RyaW5nfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgT25lU3RyaW5nIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk9uZVN0cmluZykKICAgICAgT25lU3RyaW5nT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBPbmVTdHJpbmcubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgT25lU3RyaW5nKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgT25lU3RyaW5nKCkgewogICAgICBkYXRhXyA9ICIiOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE9uZVN0cmluZygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09uZVN0cmluZ19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09uZVN0cmluZ19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZVN0cmluZy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREFUQV9GSUVMRF9OVU1CRVIgPSAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgZGF0YV8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGF0YSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0RhdGEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRhdGEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldERhdGEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZGF0YV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgZGF0YV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGF0YSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGRhdGEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXREYXRhQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZGF0YV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGRhdGFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEsIGRhdGFfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxLCBkYXRhXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmcpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nKSBvYmo7CgogICAgICBpZiAoaGFzRGF0YSgpICE9IG90aGVyLmhhc0RhdGEoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRGF0YSgpKSB7CiAgICAgICAgaWYgKCFnZXREYXRhKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXREYXRhKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzRGF0YSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgREFUQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RGF0YSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZVN0cmluZyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmcgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZVN0cmluZyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmcgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmcgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRlc3QgU3RyaW5nIGFuZCBCeXRlczogc3RyaW5nIGlzIGZvciB2YWxpZCBVVEYtOCBzdHJpbmdzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5PbmVTdHJpbmd9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5PbmVTdHJpbmcpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmdPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT25lU3RyaW5nX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09uZVN0cmluZ19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZVN0cmluZy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmcuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZVN0cmluZy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgZGF0YV8gPSAiIjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT25lU3RyaW5nX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZVN0cmluZyBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZVN0cmluZyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZVN0cmluZyByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmcodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmcgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZGF0YV8gPSBkYXRhXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZVN0cmluZylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZVN0cmluZyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZVN0cmluZy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0RhdGEoKSkgewogICAgICAgICAgZGF0YV8gPSBvdGhlci5kYXRhXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBkYXRhXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBkYXRhXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkYXRhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0RhdGEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGF0YSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkYXRhLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RGF0YSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGRhdGFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgZGF0YV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGRhdGEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXREYXRhQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBkYXRhXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgZGF0YV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZGF0YSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRhdGEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREYXRhKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZGF0YV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGF0YSgpIHsKICAgICAgICBkYXRhXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldERhdGEoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGRhdGEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREYXRhQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGRhdGFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk9uZVN0cmluZykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuT25lU3RyaW5nKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmcgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVTdHJpbmcoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T25lU3RyaW5nPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE9uZVN0cmluZz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE9uZVN0cmluZyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE9uZVN0cmluZz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPbmVTdHJpbmc+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lU3RyaW5nIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgTW9yZVN0cmluZ09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5Nb3JlU3RyaW5nKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGRhdGEuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0RGF0YUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGRhdGEuCiAgICAgKi8KICAgIGludCBnZXREYXRhQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZGF0YSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0RGF0YShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZGF0YSA9IDE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIGRhdGEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXREYXRhQnl0ZXMoaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTW9yZVN0cmluZ30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE1vcmVTdHJpbmcgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTW9yZVN0cmluZykKICAgICAgTW9yZVN0cmluZ09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgTW9yZVN0cmluZy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBNb3JlU3RyaW5nKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgTW9yZVN0cmluZygpIHsKICAgICAgZGF0YV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE1vcmVTdHJpbmcoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Nb3JlU3RyaW5nX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTW9yZVN0cmluZ19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZVN0cmluZy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERBVEFfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgZGF0YV8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGRhdGEuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldERhdGFMaXN0KCkgewogICAgICByZXR1cm4gZGF0YV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBkYXRhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBkYXRhLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldERhdGFDb3VudCgpIHsKICAgICAgcmV0dXJuIGRhdGFfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZGF0YSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldERhdGEoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBkYXRhXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZGF0YSA9IDE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIGRhdGEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0RGF0YUJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gZGF0YV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxLCBkYXRhXy5nZXRSYXcoaSkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKGRhdGFfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0RGF0YUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVTdHJpbmcgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nKSBvYmo7CgogICAgICBpZiAoIWdldERhdGFMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RGF0YUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoZ2V0RGF0YUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgREFUQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RGF0YUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZVN0cmluZyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVTdHJpbmcgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZVN0cmluZyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZVN0cmluZyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5Nb3JlU3RyaW5nfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTW9yZVN0cmluZykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVTdHJpbmdPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTW9yZVN0cmluZ19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Nb3JlU3RyaW5nX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZVN0cmluZy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBkYXRhXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTW9yZVN0cmluZ19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVTdHJpbmcgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVTdHJpbmcgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVTdHJpbmcgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZVN0cmluZyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVTdHJpbmcgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIGRhdGFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5kYXRhXyA9IGRhdGFfOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZVN0cmluZykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZVN0cmluZyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVTdHJpbmcuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmICghb3RoZXIuZGF0YV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAoZGF0YV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGRhdGFfID0gb3RoZXIuZGF0YV87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZURhdGFJc011dGFibGUoKTsKICAgICAgICAgICAgZGF0YV8uYWRkQWxsKG90aGVyLmRhdGFfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZURhdGFJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGRhdGFfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgZGF0YV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRGF0YUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWRhdGFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBkYXRhXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QoZGF0YV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGRhdGEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldERhdGFMaXN0KCkgewogICAgICAgIGRhdGFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZGF0YV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGRhdGEuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldERhdGFDb3VudCgpIHsKICAgICAgICByZXR1cm4gZGF0YV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZGF0YSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgZGF0YSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXREYXRhKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBkYXRhXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZGF0YSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSBkYXRhIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldERhdGFCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZGF0YV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkYXRhIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGF0YSgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlRGF0YUlzTXV0YWJsZSgpOwogICAgICAgIGRhdGFfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkYXRhIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRGF0YSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZURhdGFJc011dGFibGUoKTsKICAgICAgICBkYXRhXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZGF0YSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbERhdGEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRGF0YUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBkYXRhXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgZGF0YSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRhdGEoKSB7CiAgICAgICAgZGF0YV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIGRhdGEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGREYXRhQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZURhdGFJc011dGFibGUoKTsKICAgICAgICBkYXRhXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5Nb3JlU3RyaW5nKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5Nb3JlU3RyaW5nKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZVN0cmluZygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TW9yZVN0cmluZz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNb3JlU3RyaW5nPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgTW9yZVN0cmluZyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1vcmVTdHJpbmc+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TW9yZVN0cmluZz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlU3RyaW5nIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgT25lQnl0ZXNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuT25lQnl0ZXMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBkYXRhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRhdGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0RhdGEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZGF0YSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGF0YS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldERhdGEoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuT25lQnl0ZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBPbmVCeXRlcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5PbmVCeXRlcykKICAgICAgT25lQnl0ZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIE9uZUJ5dGVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIE9uZUJ5dGVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgT25lQnl0ZXMoKSB7CiAgICAgIGRhdGFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE9uZUJ5dGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT25lQnl0ZXNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbmVCeXRlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lQnl0ZXMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lQnl0ZXMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERBVEFfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBkYXRhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRhdGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEYXRhKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRhdGEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RGF0YSgpIHsKICAgICAgcmV0dXJuIGRhdGFfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMSwgZGF0YV8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplKDEsIGRhdGFfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lQnl0ZXMpIG9iajsKCiAgICAgIGlmIChoYXNEYXRhKCkgIT0gb3RoZXIuaGFzRGF0YSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEYXRhKCkpIHsKICAgICAgICBpZiAoIWdldERhdGEoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldERhdGEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNEYXRhKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEQVRBX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREYXRhKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lQnl0ZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0Lk9uZUJ5dGVzfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuT25lQnl0ZXMpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbmVCeXRlc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbmVCeXRlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgZGF0YV8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09uZUJ5dGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lQnl0ZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcyBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcyByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRhdGFfID0gZGF0YV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9uZUJ5dGVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lQnl0ZXMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0RhdGEoKSkgewogICAgICAgICAgc2V0RGF0YShvdGhlci5nZXREYXRhKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBkYXRhXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGFfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZGF0YSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRhdGEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEYXRhKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZGF0YSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBkYXRhLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldERhdGEoKSB7CiAgICAgICAgcmV0dXJuIGRhdGFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGF0YSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERhdGEoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBkYXRhXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgZGF0YSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRhdGEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGRhdGFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0RGF0YSgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk9uZUJ5dGVzKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5PbmVCeXRlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT25lQnl0ZXMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE9uZUJ5dGVzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE9uZUJ5dGVzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgT25lQnl0ZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPbmVCeXRlcz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPbmVCeXRlcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5PbmVCeXRlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIE1vcmVCeXRlc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5Nb3JlQnl0ZXMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBkYXRhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBkYXRhLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldERhdGFMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIGRhdGEuCiAgICAgKi8KICAgIGludCBnZXREYXRhQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZGF0YSA9IDE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBkYXRhIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldERhdGEoaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuTW9yZUJ5dGVzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTW9yZUJ5dGVzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk1vcmVCeXRlcykKICAgICAgTW9yZUJ5dGVzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBNb3JlQnl0ZXMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgTW9yZUJ5dGVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgTW9yZUJ5dGVzKCkgewogICAgICBkYXRhXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE1vcmVCeXRlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01vcmVCeXRlc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01vcmVCeXRlc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVCeXRlcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEQVRBX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkYXRhXyA9CiAgICAgICAgZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIGRhdGEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZ2V0RGF0YUxpc3QoKSB7CiAgICAgIHJldHVybiBkYXRhXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZGF0YSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZGF0YS4KICAgICAqLwogICAgcHVibGljIGludCBnZXREYXRhQ291bnQoKSB7CiAgICAgIHJldHVybiBkYXRhXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgZGF0YSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0RGF0YShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIGRhdGFfLmdldChpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBmb3IgKGludCBpID0gMDsgaSA8IGRhdGFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoMSwgZGF0YV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkYXRhXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZU5vVGFnKGRhdGFfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0RGF0YUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlQnl0ZXMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzKSBvYmo7CgogICAgICBpZiAoIWdldERhdGFMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RGF0YUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoZ2V0RGF0YUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgREFUQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RGF0YUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVCeXRlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVCeXRlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlQnl0ZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVCeXRlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVCeXRlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlQnl0ZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVCeXRlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0Lk1vcmVCeXRlc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lk1vcmVCeXRlcykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVCeXRlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Nb3JlQnl0ZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTW9yZUJ5dGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVCeXRlcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBkYXRhXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Nb3JlQnl0ZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlQnl0ZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlQnl0ZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlQnl0ZXMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVCeXRlcyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVCeXRlcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgZGF0YV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LmRhdGFfID0gZGF0YV87CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Nb3JlQnl0ZXMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoIW90aGVyLmRhdGFfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKGRhdGFfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBkYXRhXyA9IG90aGVyLmRhdGFfOwogICAgICAgICAgICBkYXRhXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZURhdGFJc011dGFibGUoKTsKICAgICAgICAgICAgZGF0YV8uYWRkQWxsKG90aGVyLmRhdGFfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdiA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlRGF0YUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZGF0YV8uYWRkKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkYXRhXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRGF0YUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIWRhdGFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBkYXRhXyA9IG1ha2VNdXRhYmxlQ29weShkYXRhXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgZGF0YSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBkYXRhLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldERhdGFMaXN0KCkgewogICAgICAgIGRhdGFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gZGF0YV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgZGF0YS4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0RGF0YUNvdW50KCkgewogICAgICAgIHJldHVybiBkYXRhXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGRhdGEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXREYXRhKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBkYXRhXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkYXRhIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGF0YSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVEYXRhSXNNdXRhYmxlKCk7CiAgICAgICAgZGF0YV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGF0YSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZERhdGEoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVEYXRhSXNNdXRhYmxlKCk7CiAgICAgICAgZGF0YV8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgZGF0YSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbERhdGEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlRGF0YUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBkYXRhXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGF0YSgpIHsKICAgICAgICBkYXRhXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5Nb3JlQnl0ZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk1vcmVCeXRlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTW9yZUJ5dGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVCeXRlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1vcmVCeXRlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxNb3JlQnl0ZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBNb3JlQnl0ZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNb3JlQnl0ZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TW9yZUJ5dGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1vcmVCeXRlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIE1hbnlPcHRpb25hbFN0cmluZ09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5NYW55T3B0aW9uYWxTdHJpbmcpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTdHIxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIxLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjJCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3RyMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIzID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyM0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyNCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHI0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTdHI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHI0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHI0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHI0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI1ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjUgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyNSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjVCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjYgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3RyNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyNiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHI2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI2ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyNkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyNyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHI3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTdHI3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI3ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHI3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjcgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHI3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHI3Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI4ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cjgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjggPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyOCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjhCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjkgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3RyOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyOSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHI5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI5ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyOUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTdHIxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIxMC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIxMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTAuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjEwQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxMSA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cjExKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxMSA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjExLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjExKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxMSA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIxMS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMTFCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEyID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3RyMTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEyID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMTIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEyID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjEyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIxMkJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjEzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTdHIxMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIxMy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIxMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjEzQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxNCA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cjE0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxNCA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjE0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjE0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxNCA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIxNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMTRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE1ID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3RyMTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE1ID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMTUuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE1ID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjE1LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIxNUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjE2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTdHIxNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIxNi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIxNigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTYuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjE2Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxNyA9IDE3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cjE3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxNyA9IDE3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjE3LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjE3KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxNyA9IDE3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIxNy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMTdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE4ID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3RyMTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE4ID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMTguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTgoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE4ID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjE4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIxOEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTkgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjE5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTdHIxOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTkgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIxOS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIxOSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTkgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTkuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjE5Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyMCA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cjIwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyMCA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjIwLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjIwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyMCA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIyMC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMjBCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIxID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3RyMjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIxID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMjEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIxID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjIxLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIyMUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjIgPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjIyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTdHIyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjIgPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIyMi4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjIgPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjIuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjIyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyMyA9IDIzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cjIzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyMyA9IDIzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjIzLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjIzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyMyA9IDIzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIyMy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMjNCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI0ID0gMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3RyMjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI0ID0gMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMjQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI0ID0gMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjI0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIyNEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjUgPSAyNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjI1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTdHIyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjUgPSAyNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIyNS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIyNSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjUgPSAyNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjI1Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyNiA9IDI2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cjI2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyNiA9IDI2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjI2LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjI2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyNiA9IDI2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIyNi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMjZCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI3ID0gMjc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3RyMjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI3ID0gMjc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMjcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI3ID0gMjc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjI3LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIyN0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjggPSAyODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjI4IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTdHIyOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjggPSAyODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIyOC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIyOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjggPSAyODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjI4Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyOSA9IDI5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cjI5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyOSA9IDI5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjI5LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjI5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyOSA9IDI5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIyOS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMjlCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMwID0gMzA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIzMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3RyMzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMwID0gMzA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMzAuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMzAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMwID0gMzA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjMwLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIzMEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzEgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjMxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTdHIzMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzEgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIzMS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIzMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzEgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMzEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjMxQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIzMiA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cjMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIzMiA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjMyLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIzMiA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIzMi4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMzJCeXRlcygpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NYW55T3B0aW9uYWxTdHJpbmd9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBNYW55T3B0aW9uYWxTdHJpbmcgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuTWFueU9wdGlvbmFsU3RyaW5nKQogICAgICBNYW55T3B0aW9uYWxTdHJpbmdPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIE1hbnlPcHRpb25hbFN0cmluZy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBNYW55T3B0aW9uYWxTdHJpbmcoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBNYW55T3B0aW9uYWxTdHJpbmcoKSB7CiAgICAgIHN0cjFfID0gIiI7CiAgICAgIHN0cjJfID0gIiI7CiAgICAgIHN0cjNfID0gIiI7CiAgICAgIHN0cjRfID0gIiI7CiAgICAgIHN0cjVfID0gIiI7CiAgICAgIHN0cjZfID0gIiI7CiAgICAgIHN0cjdfID0gIiI7CiAgICAgIHN0cjhfID0gIiI7CiAgICAgIHN0cjlfID0gIiI7CiAgICAgIHN0cjEwXyA9ICIiOwogICAgICBzdHIxMV8gPSAiIjsKICAgICAgc3RyMTJfID0gIiI7CiAgICAgIHN0cjEzXyA9ICIiOwogICAgICBzdHIxNF8gPSAiIjsKICAgICAgc3RyMTVfID0gIiI7CiAgICAgIHN0cjE2XyA9ICIiOwogICAgICBzdHIxN18gPSAiIjsKICAgICAgc3RyMThfID0gIiI7CiAgICAgIHN0cjE5XyA9ICIiOwogICAgICBzdHIyMF8gPSAiIjsKICAgICAgc3RyMjFfID0gIiI7CiAgICAgIHN0cjIyXyA9ICIiOwogICAgICBzdHIyM18gPSAiIjsKICAgICAgc3RyMjRfID0gIiI7CiAgICAgIHN0cjI1XyA9ICIiOwogICAgICBzdHIyNl8gPSAiIjsKICAgICAgc3RyMjdfID0gIiI7CiAgICAgIHN0cjI4XyA9ICIiOwogICAgICBzdHIyOV8gPSAiIjsKICAgICAgc3RyMzBfID0gIiI7CiAgICAgIHN0cjMxXyA9ICIiOwogICAgICBzdHIzMl8gPSAiIjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBNYW55T3B0aW9uYWxTdHJpbmcoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYW55T3B0aW9uYWxTdHJpbmdfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYW55T3B0aW9uYWxTdHJpbmdfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjFfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjFfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIxKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjFfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHIxXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjJfRklFTERfTlVNQkVSID0gMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjJfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIyKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHIyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjNfRklFTERfTlVNQkVSID0gMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjNfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIzID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIzID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjNfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyM0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHIzXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjRfRklFTERfTlVNQkVSID0gNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjRfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHI0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHI0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHI0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHI0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyNEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHI0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjVfRklFTERfTlVNQkVSID0gNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjVfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI1ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHI1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI1ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHI1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHI1KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjUgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHI1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyNUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHI1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjZfRklFTERfTlVNQkVSID0gNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjZfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI2ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHI2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI2ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHI2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHI2KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjZfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjYgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHI2LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyNkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHI2XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjdfRklFTERfTlVNQkVSID0gNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjdfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI3ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHI3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI3ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHI3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHI3KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjcgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHI3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyN0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHI3XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjhfRklFTERfTlVNQkVSID0gODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjhfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI4ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHI4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI4ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHI4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHI4KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjhfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjggPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHI4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyOEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHI4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjlfRklFTERfTlVNQkVSID0gOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjlfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI5ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHI5KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI5ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHI5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHI5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjlfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjkgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHI5LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyOUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHI5XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjEwX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgc3RyMTBfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxMCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIxMCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTAoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjEwXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxMCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjEwQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTBfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHIxMF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFIxMV9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjExXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTEgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjExIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjExID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjExKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjExXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBzdHIxMV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTEgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIxMUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjExXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyMTFfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSMTJfRklFTERfTlVNQkVSID0gMTI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBzdHIxMl8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEyID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIxMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cjEyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjEyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIxMigpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgc3RyMTJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEyID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjEyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMTJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxMl87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIHN0cjEyXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjEzX0ZJRUxEX05VTUJFUiA9IDEzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgc3RyMTNfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxMyA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIxMygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIxMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjEzXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxMyA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIxMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjEzQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTNfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHIxM18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFIxNF9GSUVMRF9OVU1CRVIgPSAxNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjE0XyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTQgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjE0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMTQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE0ID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjE0KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjE0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBzdHIxNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTQgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIxNEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjE0XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyMTRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSMTVfRklFTERfTlVNQkVSID0gMTU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBzdHIxNV8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE1ID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIxNSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cjE1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxNSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjE1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIxNSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgc3RyMTVfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE1ID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjE1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMTVCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxNV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIHN0cjE1XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjE2X0ZJRUxEX05VTUJFUiA9IDE2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgc3RyMTZfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxNiA9IDE2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIxNigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIxNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTYoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjE2XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxNiA9IDE2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIxNi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjE2Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTZfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHIxNl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFIxN19GSUVMRF9OVU1CRVIgPSAxNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjE3XyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTcgPSAxNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjE3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMTcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE3ID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjE3KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjE3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBzdHIxN18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTcgPSAxNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIxN0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjE3XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyMTdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSMThfRklFTERfTlVNQkVSID0gMTg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBzdHIxOF8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE4ID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIxOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cjE4KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxOCA9IDE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjE4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIxOCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgc3RyMThfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE4ID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjE4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMThCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxOF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIHN0cjE4XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjE5X0ZJRUxEX05VTUJFUiA9IDE5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgc3RyMTlfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxOSA9IDE5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIxOSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTkgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIxOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTkoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjE5XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxOSA9IDE5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIxOS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjE5Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTlfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHIxOV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFIyMF9GSUVMRF9OVU1CRVIgPSAyMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjIwXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjAgPSAyMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjIwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIwID0gMjA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjIwKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjIwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBzdHIyMF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjAgPSAyMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIyMEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjIwXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyMjBfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSMjFfRklFTERfTlVNQkVSID0gMjE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBzdHIyMV8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIxID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cjIxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyMSA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjIxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIyMSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgc3RyMjFfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIxID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjIxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyMV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIHN0cjIxXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjIyX0ZJRUxEX05VTUJFUiA9IDIyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgc3RyMjJfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyMiA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIyMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjIgPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjIoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjIyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyMiA9IDIyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjIyQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHIyMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFIyM19GSUVMRF9OVU1CRVIgPSAyMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjIzXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjMgPSAyMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjIzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIzID0gMjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjIzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjIzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBzdHIyM18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjMgPSAyMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIyM0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjIzXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyMjNfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSMjRfRklFTERfTlVNQkVSID0gMjQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBzdHIyNF8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI0ID0gMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIyNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cjI0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDgwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyNCA9IDI0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjI0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIyNCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgc3RyMjRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI0ID0gMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjI0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMjRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyNF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIHN0cjI0XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjI1X0ZJRUxEX05VTUJFUiA9IDI1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgc3RyMjVfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyNSA9IDI1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIyNSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjUgPSAyNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjUoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjI1XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyNSA9IDI1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIyNS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjI1Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjVfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHIyNV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFIyNl9GSUVMRF9OVU1CRVIgPSAyNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjI2XyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjYgPSAyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjI2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAyMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI2ID0gMjY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjI2KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjI2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBzdHIyNl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjYgPSAyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIyNkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjI2XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyMjZfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSMjdfRklFTERfTlVNQkVSID0gMjc7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBzdHIyN18gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI3ID0gMjc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIyNyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cjI3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyNyA9IDI3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjI3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIyNygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgc3RyMjdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI3ID0gMjc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjI3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMjdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyN187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIHN0cjI3XyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjI4X0ZJRUxEX05VTUJFUiA9IDI4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgc3RyMjhfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyOCA9IDI4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIyOCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjggPSAyODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIyOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjgoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjI4XyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyOCA9IDI4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIyOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjI4Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjhfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHIyOF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFIyOV9GSUVMRF9OVU1CRVIgPSAyOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjI5XyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjkgPSAyOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjI5IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDEwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI5ID0gMjk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjI5KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjI5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBzdHIyOV8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjkgPSAyOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIyOUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjI5XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyMjlfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSMzBfRklFTERfTlVNQkVSID0gMzA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBzdHIzMF8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMwID0gMzA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIzMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cjMwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIzMCA9IDMwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjMwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIzMCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIzMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgc3RyMzBfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMwID0gMzA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjMwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0U3RyMzBCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIzMF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIHN0cjMwXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUjMxX0ZJRUxEX05VTUJFUiA9IDMxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgc3RyMzFfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIzMSA9IDMxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMzEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIzMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzEgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIzMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMzEoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMzFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjMxXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIzMSA9IDMxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIzMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjMxQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMzFfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBzdHIzMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFIzMl9GSUVMRF9OVU1CRVIgPSAzMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjMyXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzIgPSAzMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDgwMDAwMDAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMyID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjMyKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjMyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBzdHIzMl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzIgPSAzMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIzMkJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjMyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyMzJfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEsIHN0cjFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDIsIHN0cjJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDMsIHN0cjNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDQsIHN0cjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDUsIHN0cjVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDYsIHN0cjZfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDcsIHN0cjdfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDgsIHN0cjhfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDksIHN0cjlfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEwLCBzdHIxMF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMTEsIHN0cjExXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMiwgc3RyMTJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEzLCBzdHIxM18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMTQsIHN0cjE0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxNSwgc3RyMTVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDE2LCBzdHIxNl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMTcsIHN0cjE3Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxOCwgc3RyMThfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDE5LCBzdHIxOV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjAsIHN0cjIwXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyMSwgc3RyMjFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDIyLCBzdHIyMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjMsIHN0cjIzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyNCwgc3RyMjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDI1LCBzdHIyNV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjYsIHN0cjI2Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyNywgc3RyMjdfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDI4LCBzdHIyOF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjksIHN0cjI5Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAzMCwgc3RyMzBfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDMxLCBzdHIzMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMzIsIHN0cjMyXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMSwgc3RyMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMiwgc3RyMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMywgc3RyM18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoNCwgc3RyNF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoNSwgc3RyNV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoNiwgc3RyNl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoNywgc3RyN18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoOCwgc3RyOF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoOSwgc3RyOV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMTAsIHN0cjEwXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxMSwgc3RyMTFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDEyLCBzdHIxMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMTMsIHN0cjEzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxNCwgc3RyMTRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwNDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDE1LCBzdHIxNV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMTYsIHN0cjE2Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxNywgc3RyMTdfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAyMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDE4LCBzdHIxOF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMTksIHN0cjE5Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyMCwgc3RyMjBfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDIxLCBzdHIyMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMjIsIHN0cjIyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyMywgc3RyMjNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDI0LCBzdHIyNF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMjUsIHN0cjI1Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyNiwgc3RyMjZfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDI3LCBzdHIyN18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMjgsIHN0cjI4Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyOSwgc3RyMjlfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDMwLCBzdHIzMF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMzEsIHN0cjMxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4ODAwMDAwMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgzMiwgc3RyMzJfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcpIG9iajsKCiAgICAgIGlmIChoYXNTdHIxKCkgIT0gb3RoZXIuaGFzU3RyMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTdHIxKCkpIHsKICAgICAgICBpZiAoIWdldFN0cjEoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFN0cjEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyMigpICE9IG90aGVyLmhhc1N0cjIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzU3RyMigpKSB7CiAgICAgICAgaWYgKCFnZXRTdHIyKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIyKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjMoKSAhPSBvdGhlci5oYXNTdHIzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjMoKSkgewogICAgICAgIGlmICghZ2V0U3RyMygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHI0KCkgIT0gb3RoZXIuaGFzU3RyNCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTdHI0KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjQoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFN0cjQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyNSgpICE9IG90aGVyLmhhc1N0cjUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzU3RyNSgpKSB7CiAgICAgICAgaWYgKCFnZXRTdHI1KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHI1KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjYoKSAhPSBvdGhlci5oYXNTdHI2KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjYoKSkgewogICAgICAgIGlmICghZ2V0U3RyNigpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyNigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHI3KCkgIT0gb3RoZXIuaGFzU3RyNygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTdHI3KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjcoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFN0cjcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyOCgpICE9IG90aGVyLmhhc1N0cjgoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzU3RyOCgpKSB7CiAgICAgICAgaWYgKCFnZXRTdHI4KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHI4KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjkoKSAhPSBvdGhlci5oYXNTdHI5KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjkoKSkgewogICAgICAgIGlmICghZ2V0U3RyOSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIxMCgpICE9IG90aGVyLmhhc1N0cjEwKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjEwKCkpIHsKICAgICAgICBpZiAoIWdldFN0cjEwKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIxMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIxMSgpICE9IG90aGVyLmhhc1N0cjExKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjExKCkpIHsKICAgICAgICBpZiAoIWdldFN0cjExKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIxMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIxMigpICE9IG90aGVyLmhhc1N0cjEyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjEyKCkpIHsKICAgICAgICBpZiAoIWdldFN0cjEyKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIxMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIxMygpICE9IG90aGVyLmhhc1N0cjEzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjEzKCkpIHsKICAgICAgICBpZiAoIWdldFN0cjEzKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIxMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIxNCgpICE9IG90aGVyLmhhc1N0cjE0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjE0KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjE0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIxNCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIxNSgpICE9IG90aGVyLmhhc1N0cjE1KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjE1KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjE1KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIxNSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIxNigpICE9IG90aGVyLmhhc1N0cjE2KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjE2KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjE2KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIxNigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIxNygpICE9IG90aGVyLmhhc1N0cjE3KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjE3KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjE3KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIxNygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIxOCgpICE9IG90aGVyLmhhc1N0cjE4KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjE4KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjE4KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIxOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIxOSgpICE9IG90aGVyLmhhc1N0cjE5KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjE5KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjE5KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIxOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyMCgpICE9IG90aGVyLmhhc1N0cjIwKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjIwKCkpIHsKICAgICAgICBpZiAoIWdldFN0cjIwKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIyMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyMSgpICE9IG90aGVyLmhhc1N0cjIxKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjIxKCkpIHsKICAgICAgICBpZiAoIWdldFN0cjIxKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIyMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyMigpICE9IG90aGVyLmhhc1N0cjIyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjIyKCkpIHsKICAgICAgICBpZiAoIWdldFN0cjIyKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIyMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyMygpICE9IG90aGVyLmhhc1N0cjIzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjIzKCkpIHsKICAgICAgICBpZiAoIWdldFN0cjIzKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIyMygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyNCgpICE9IG90aGVyLmhhc1N0cjI0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjI0KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjI0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIyNCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyNSgpICE9IG90aGVyLmhhc1N0cjI1KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjI1KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjI1KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIyNSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyNigpICE9IG90aGVyLmhhc1N0cjI2KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjI2KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjI2KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIyNigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyNygpICE9IG90aGVyLmhhc1N0cjI3KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjI3KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjI3KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIyNygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyOCgpICE9IG90aGVyLmhhc1N0cjI4KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjI4KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjI4KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIyOCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyOSgpICE9IG90aGVyLmhhc1N0cjI5KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjI5KCkpIHsKICAgICAgICBpZiAoIWdldFN0cjI5KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIyOSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIzMCgpICE9IG90aGVyLmhhc1N0cjMwKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjMwKCkpIHsKICAgICAgICBpZiAoIWdldFN0cjMwKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIzMCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIzMSgpICE9IG90aGVyLmhhc1N0cjMxKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjMxKCkpIHsKICAgICAgICBpZiAoIWdldFN0cjMxKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIzMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIzMigpICE9IG90aGVyLmhhc1N0cjMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjMyKCkpIHsKICAgICAgICBpZiAoIWdldFN0cjMyKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRTdHIzMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc1N0cjEoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUjFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cjEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFIyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHIyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyMygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyMygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cjQoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNTdHI1KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFI1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHI1KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyNigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyNigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjcoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUjdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cjcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNTdHI4KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFI4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHI4KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyOSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyOSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjEwKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFIxMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyMTAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIxMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSMTFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cjExKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyMTIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUjEyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHIxMigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjEzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFIxM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyMTMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIxNCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSMTRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cjE0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyMTUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUjE1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHIxNSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjE2KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFIxNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyMTYoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIxNygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSMTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cjE3KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyMTgoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUjE4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHIxOCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjE5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFIxOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyMTkoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyMCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSMjBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cjIwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyMjEoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUjIxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHIyMSgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjIyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFIyMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyMjIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyMygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSMjNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cjIzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyMjQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUjI0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHIyNCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjI1KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFIyNV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyMjUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyNigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSMjZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cjI2KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyMjcoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUjI3X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHIyNygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjI4KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFIyOF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyMjgoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIyOSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSMjlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cjI5KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3RyMzAoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUjMwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHIzMCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjMxKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFIzMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U3RyMzEoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIzMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cjMyKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTWFueU9wdGlvbmFsU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTWFueU9wdGlvbmFsU3RyaW5nIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5NYW55T3B0aW9uYWxTdHJpbmd9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5NYW55T3B0aW9uYWxTdHJpbmcpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmdPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFueU9wdGlvbmFsU3RyaW5nX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hbnlPcHRpb25hbFN0cmluZ19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgc3RyMV8gPSAiIjsKICAgICAgICBzdHIyXyA9ICIiOwogICAgICAgIHN0cjNfID0gIiI7CiAgICAgICAgc3RyNF8gPSAiIjsKICAgICAgICBzdHI1XyA9ICIiOwogICAgICAgIHN0cjZfID0gIiI7CiAgICAgICAgc3RyN18gPSAiIjsKICAgICAgICBzdHI4XyA9ICIiOwogICAgICAgIHN0cjlfID0gIiI7CiAgICAgICAgc3RyMTBfID0gIiI7CiAgICAgICAgc3RyMTFfID0gIiI7CiAgICAgICAgc3RyMTJfID0gIiI7CiAgICAgICAgc3RyMTNfID0gIiI7CiAgICAgICAgc3RyMTRfID0gIiI7CiAgICAgICAgc3RyMTVfID0gIiI7CiAgICAgICAgc3RyMTZfID0gIiI7CiAgICAgICAgc3RyMTdfID0gIiI7CiAgICAgICAgc3RyMThfID0gIiI7CiAgICAgICAgc3RyMTlfID0gIiI7CiAgICAgICAgc3RyMjBfID0gIiI7CiAgICAgICAgc3RyMjFfID0gIiI7CiAgICAgICAgc3RyMjJfID0gIiI7CiAgICAgICAgc3RyMjNfID0gIiI7CiAgICAgICAgc3RyMjRfID0gIiI7CiAgICAgICAgc3RyMjVfID0gIiI7CiAgICAgICAgc3RyMjZfID0gIiI7CiAgICAgICAgc3RyMjdfID0gIiI7CiAgICAgICAgc3RyMjhfID0gIiI7CiAgICAgICAgc3RyMjlfID0gIiI7CiAgICAgICAgc3RyMzBfID0gIiI7CiAgICAgICAgc3RyMzFfID0gIiI7CiAgICAgICAgc3RyMzJfID0gIiI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hbnlPcHRpb25hbFN0cmluZ19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTWFueU9wdGlvbmFsU3RyaW5nKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTWFueU9wdGlvbmFsU3RyaW5nIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cjFfID0gc3RyMV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyMl8gPSBzdHIyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHIzXyA9IHN0cjNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cjRfID0gc3RyNF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyNV8gPSBzdHI1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHI2XyA9IHN0cjZfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cjdfID0gc3RyN187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyOF8gPSBzdHI4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHI5XyA9IHN0cjlfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cjEwXyA9IHN0cjEwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHIxMV8gPSBzdHIxMV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyMTJfID0gc3RyMTJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cjEzXyA9IHN0cjEzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHIxNF8gPSBzdHIxNF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyMTVfID0gc3RyMTVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDA4MDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cjE2XyA9IHN0cjE2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAxMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHIxN18gPSBzdHIxN187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyMThfID0gc3RyMThfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDQwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cjE5XyA9IHN0cjE5XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHIyMF8gPSBzdHIyMF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyMjFfID0gc3RyMjFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cjIyXyA9IHN0cjIyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHIyM18gPSBzdHIyM187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyMjRfID0gc3RyMjRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAxMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cjI1XyA9IHN0cjI1XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHIyNl8gPSBzdHIyNl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyMjdfID0gc3RyMjdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cjI4XyA9IHN0cjI4XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgxMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHIyOV8gPSBzdHIyOV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyMzBfID0gc3RyMzBfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cjMxXyA9IHN0cjMxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHIzMl8gPSBzdHIzMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk1hbnlPcHRpb25hbFN0cmluZykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNTdHIxKCkpIHsKICAgICAgICAgIHN0cjFfID0gb3RoZXIuc3RyMV87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1N0cjIoKSkgewogICAgICAgICAgc3RyMl8gPSBvdGhlci5zdHIyXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyMygpKSB7CiAgICAgICAgICBzdHIzXyA9IG90aGVyLnN0cjNfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdHI0KCkpIHsKICAgICAgICAgIHN0cjRfID0gb3RoZXIuc3RyNF87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1N0cjUoKSkgewogICAgICAgICAgc3RyNV8gPSBvdGhlci5zdHI1XzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyNigpKSB7CiAgICAgICAgICBzdHI2XyA9IG90aGVyLnN0cjZfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdHI3KCkpIHsKICAgICAgICAgIHN0cjdfID0gb3RoZXIuc3RyN187CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1N0cjgoKSkgewogICAgICAgICAgc3RyOF8gPSBvdGhlci5zdHI4XzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyOSgpKSB7CiAgICAgICAgICBzdHI5XyA9IG90aGVyLnN0cjlfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdHIxMCgpKSB7CiAgICAgICAgICBzdHIxMF8gPSBvdGhlci5zdHIxMF87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1N0cjExKCkpIHsKICAgICAgICAgIHN0cjExXyA9IG90aGVyLnN0cjExXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyMTIoKSkgewogICAgICAgICAgc3RyMTJfID0gb3RoZXIuc3RyMTJfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdHIxMygpKSB7CiAgICAgICAgICBzdHIxM18gPSBvdGhlci5zdHIxM187CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1N0cjE0KCkpIHsKICAgICAgICAgIHN0cjE0XyA9IG90aGVyLnN0cjE0XzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyMTUoKSkgewogICAgICAgICAgc3RyMTVfID0gb3RoZXIuc3RyMTVfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdHIxNigpKSB7CiAgICAgICAgICBzdHIxNl8gPSBvdGhlci5zdHIxNl87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1N0cjE3KCkpIHsKICAgICAgICAgIHN0cjE3XyA9IG90aGVyLnN0cjE3XzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyMTgoKSkgewogICAgICAgICAgc3RyMThfID0gb3RoZXIuc3RyMThfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdHIxOSgpKSB7CiAgICAgICAgICBzdHIxOV8gPSBvdGhlci5zdHIxOV87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1N0cjIwKCkpIHsKICAgICAgICAgIHN0cjIwXyA9IG90aGVyLnN0cjIwXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyMjEoKSkgewogICAgICAgICAgc3RyMjFfID0gb3RoZXIuc3RyMjFfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdHIyMigpKSB7CiAgICAgICAgICBzdHIyMl8gPSBvdGhlci5zdHIyMl87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1N0cjIzKCkpIHsKICAgICAgICAgIHN0cjIzXyA9IG90aGVyLnN0cjIzXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyMjQoKSkgewogICAgICAgICAgc3RyMjRfID0gb3RoZXIuc3RyMjRfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdHIyNSgpKSB7CiAgICAgICAgICBzdHIyNV8gPSBvdGhlci5zdHIyNV87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1N0cjI2KCkpIHsKICAgICAgICAgIHN0cjI2XyA9IG90aGVyLnN0cjI2XzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyMjcoKSkgewogICAgICAgICAgc3RyMjdfID0gb3RoZXIuc3RyMjdfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdHIyOCgpKSB7CiAgICAgICAgICBzdHIyOF8gPSBvdGhlci5zdHIyOF87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1N0cjI5KCkpIHsKICAgICAgICAgIHN0cjI5XyA9IG90aGVyLnN0cjI5XzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyMzAoKSkgewogICAgICAgICAgc3RyMzBfID0gb3RoZXIuc3RyMzBfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdHIzMSgpKSB7CiAgICAgICAgICBzdHIzMV8gPSBvdGhlci5zdHIzMV87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1N0cjMyKCkpIHsKICAgICAgICAgIHN0cjMyXyA9IG90aGVyLnN0cjMyXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBzdHIxXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgc3RyMl8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIHN0cjNfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgICBzdHI0XyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MjogewogICAgICAgICAgICAgICAgc3RyNV8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MgogICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgIHN0cjZfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICBjYXNlIDU4OiB7CiAgICAgICAgICAgICAgICBzdHI3XyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU4CiAgICAgICAgICAgICAgY2FzZSA2NjogewogICAgICAgICAgICAgICAgc3RyOF8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NgogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIHN0cjlfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgICBjYXNlIDgyOiB7CiAgICAgICAgICAgICAgICBzdHIxMF8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICAgIHN0cjExXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDkwCiAgICAgICAgICAgICAgY2FzZSA5ODogewogICAgICAgICAgICAgICAgc3RyMTJfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTgKICAgICAgICAgICAgICBjYXNlIDEwNjogewogICAgICAgICAgICAgICAgc3RyMTNfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA2CiAgICAgICAgICAgICAgY2FzZSAxMTQ6IHsKICAgICAgICAgICAgICAgIHN0cjE0XyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExNAogICAgICAgICAgICAgIGNhc2UgMTIyOiB7CiAgICAgICAgICAgICAgICBzdHIxNV8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjIKICAgICAgICAgICAgICBjYXNlIDEzMDogewogICAgICAgICAgICAgICAgc3RyMTZfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTMwCiAgICAgICAgICAgICAgY2FzZSAxMzg6IHsKICAgICAgICAgICAgICAgIHN0cjE3XyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEzOAogICAgICAgICAgICAgIGNhc2UgMTQ2OiB7CiAgICAgICAgICAgICAgICBzdHIxOF8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNDYKICAgICAgICAgICAgICBjYXNlIDE1NDogewogICAgICAgICAgICAgICAgc3RyMTlfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU0CiAgICAgICAgICAgICAgY2FzZSAxNjI6IHsKICAgICAgICAgICAgICAgIHN0cjIwXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MgogICAgICAgICAgICAgIGNhc2UgMTcwOiB7CiAgICAgICAgICAgICAgICBzdHIyMV8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNzAKICAgICAgICAgICAgICBjYXNlIDE3ODogewogICAgICAgICAgICAgICAgc3RyMjJfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTc4CiAgICAgICAgICAgICAgY2FzZSAxODY6IHsKICAgICAgICAgICAgICAgIHN0cjIzXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4NgogICAgICAgICAgICAgIGNhc2UgMTk0OiB7CiAgICAgICAgICAgICAgICBzdHIyNF8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOTQKICAgICAgICAgICAgICBjYXNlIDIwMjogewogICAgICAgICAgICAgICAgc3RyMjVfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjAyCiAgICAgICAgICAgICAgY2FzZSAyMTA6IHsKICAgICAgICAgICAgICAgIHN0cjI2XyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxMAogICAgICAgICAgICAgIGNhc2UgMjE4OiB7CiAgICAgICAgICAgICAgICBzdHIyN18gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMTgKICAgICAgICAgICAgICBjYXNlIDIyNjogewogICAgICAgICAgICAgICAgc3RyMjhfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjI2CiAgICAgICAgICAgICAgY2FzZSAyMzQ6IHsKICAgICAgICAgICAgICAgIHN0cjI5XyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIzNAogICAgICAgICAgICAgIGNhc2UgMjQyOiB7CiAgICAgICAgICAgICAgICBzdHIzMF8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNDIKICAgICAgICAgICAgICBjYXNlIDI1MDogewogICAgICAgICAgICAgICAgc3RyMzFfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjUwCiAgICAgICAgICAgICAgY2FzZSAyNTg6IHsKICAgICAgICAgICAgICAgIHN0cjMyXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI1OAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMV8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgc3RyMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIHN0cjFfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0U3RyMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIHN0cjFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzdHIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjEoKSB7CiAgICAgICAgc3RyMV8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRTdHIxKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBzdHIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjJfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIyKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIyXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFN0cjJCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIyXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cjIoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdHIyKCkgewogICAgICAgIHN0cjJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0U3RyMigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igc3RyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cjJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBzdHIzXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzdHIzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjNfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgc3RyM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIzQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIzXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgc3RyM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIzKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIzID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyMygpIHsKICAgICAgICBzdHIzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjMoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIzID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyNF8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI0ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHI0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgc3RyNC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHI0XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIHN0cjRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI0ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHI0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0U3RyNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyNF87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIHN0cjRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjQgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzdHI0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjQoKSB7CiAgICAgICAgc3RyNF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRTdHI0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBzdHI0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyNEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHI0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjVfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyNSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI1ID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHI1KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHI1XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyNSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyNS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFN0cjVCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHI1XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI1ID0gNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cjUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHI1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjUgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdHI1KCkgewogICAgICAgIHN0cjVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0U3RyNSgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjUgPSA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igc3RyNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cjVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyNV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBzdHI2XyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjYgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHI2IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cjYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzdHI2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyNigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjZfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgc3RyNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjYgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHI2Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHI2XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgc3RyNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHI2KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI2ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyNigpIHsKICAgICAgICBzdHI2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjYoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI2ID0gNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHI2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyN18gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI3ID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHI3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjcgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgc3RyNy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHI3XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIHN0cjdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI3ID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHI3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0U3RyN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyN187CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIHN0cjdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjcgPSA3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzdHI3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyNyA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjcoKSB7CiAgICAgICAgc3RyN18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRTdHI3KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyNyA9IDc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBzdHI3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyN0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHI3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IHN0cjhfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyOCA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyOCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI4ID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHI4KCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHI4XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyOCA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyOC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFN0cjhCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHI4XyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI4ID0gODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cjgoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHI4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjggPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdHI4KCkgewogICAgICAgIHN0cjhfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0U3RyOCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjggPSA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igc3RyOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cjhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyOF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBzdHI5XyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjkgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHI5IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cjkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzdHI5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyOSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjlfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgc3RyOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjkgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHI5Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHI5XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgc3RyOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHN0cjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHI5KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI5ID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyOSgpIHsKICAgICAgICBzdHI5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjkoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHI5ID0gOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHI5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMTBfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjEwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIxMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEwID0gMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIxMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIxMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIxMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjEwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEwID0gMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjEwKCkgewogICAgICAgIHN0cjEwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjEwKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjEwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMTBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMTBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMTFfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjExLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIxMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjExID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIxMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIxMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIxMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjExXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjExID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjExKCkgewogICAgICAgIHN0cjExXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjExKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjExIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMTFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMTFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMTJfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMTIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjEyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIxMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEyID0gMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIxMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIxMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIxMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjEyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEyID0gMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjEyKCkgewogICAgICAgIHN0cjEyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjEyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjEyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMTJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMTJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMTNfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjEzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIxM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEzID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIxM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIxM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIxMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjEzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEzID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjEzKCkgewogICAgICAgIHN0cjEzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjEzKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjEzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMTNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMTRfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjE0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIxNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE0ID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIxNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIxNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIxNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjE0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE0ID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjE0KCkgewogICAgICAgIHN0cjE0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjE0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjE0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMTRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMTRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMTVfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMTUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjE1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIxNV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE1ID0gMTU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIxNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIxNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIxNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjE1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE1ID0gMTU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjE1KCkgewogICAgICAgIHN0cjE1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjE1KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjE1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMTVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMTZfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMTYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDgwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjE2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIxNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE2ID0gMTY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIxNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIxNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMTYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIxNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjE2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE2ID0gMTY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjE2KCkgewogICAgICAgIHN0cjE2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjE2KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDgwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjE2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMTZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMTdfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjE3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIxN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE3ID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIxN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIxN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMTcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIxNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjE3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE3ID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjE3KCkgewogICAgICAgIHN0cjE3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjE3KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjE3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMTdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMTdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMThfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTggPSAxODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMTgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTggPSAxODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjE4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIxOF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE4ID0gMTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIxOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMThfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIxOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTggPSAxODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMTggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIxOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjE4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE4ID0gMTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjE4KCkgewogICAgICAgIHN0cjE4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjE4KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTggPSAxODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjE4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMThCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMThfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMTlfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMTkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMTkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjE5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMTkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIxOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE5ID0gMTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIxOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMTlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIxOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMTkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIxOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjE5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjE5ID0gMTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjE5KCkgewogICAgICAgIHN0cjE5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjE5KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwNDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjE5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMTlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMTlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMjBfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwODAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjIwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIyMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIwID0gMjA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIyMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIyMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMjAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIyMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjIwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIwID0gMjA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjIwKCkgewogICAgICAgIHN0cjIwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjIwKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwODAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjIwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMjBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMjBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMjFfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjIxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIyMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIxID0gMjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIyMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIyMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIyMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIxID0gMjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjIxKCkgewogICAgICAgIHN0cjIxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjIxKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMjFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMjJfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAyMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjIyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIyMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIyID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIyMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIyMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMjIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIyMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIyID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjIyKCkgewogICAgICAgIHN0cjIyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjIyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAyMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMjJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMjNfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjIzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyM187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIyM18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIzID0gMjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIyM0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjNfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIyM18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIyMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjIzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIzID0gMjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjIzKCkgewogICAgICAgIHN0cjIzXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjIzKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA0MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjIzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMjNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMjRfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjI0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyNF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIyNF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI0ID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIyNEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIyNF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIyNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjI0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI0ID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjI0KCkgewogICAgICAgIHN0cjI0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjI0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjI0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMjRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMjVfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjI1LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyNV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIyNV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI1ID0gMjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIyNUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIyNV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMjUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIyNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjI1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI1ID0gMjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjI1KCkgewogICAgICAgIHN0cjI1XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjI1KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDEwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjI1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMjVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMjVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMjZfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDIwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjI2LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjYoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyNl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIyNl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI2ID0gMjY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIyNkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjZfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIyNl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMjYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIyNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjI2XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI2ID0gMjY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjI2KCkgewogICAgICAgIHN0cjI2XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjI2KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDIwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjI2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMjZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMjZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMjdfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjI3LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyN187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIyN18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI3ID0gMjc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIyN0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIyN18gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMjcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIyNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjI3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI3ID0gMjc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjI3KCkgewogICAgICAgIHN0cjI3XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjI3KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjI3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMjdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMjdfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMjhfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjggPSAyODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjggPSAyODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjI4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjgoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyOF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIyOF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI4ID0gMjg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIyOEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjhfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIyOF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjggPSAyODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMjggdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIyOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjI4XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI4ID0gMjg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjI4KCkgewogICAgICAgIHN0cjI4XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjI4KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjggPSAyODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjI4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMjhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMjhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMjlfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMjkgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMjkoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjI5LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMjkoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyOV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIyOV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI5ID0gMjk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIyOUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMjlfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIyOV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMjkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIyOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjI5XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjI5ID0gMjk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjI5KCkgewogICAgICAgIHN0cjI5XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjI5KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjI5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMjlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMjlfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMzBfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMzAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMzAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjMwLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMzAoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIzMF87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIzMF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMwID0gMzA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIzMEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMzBfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIzMF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIzMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjMwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMwID0gMzA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjMwKCkgewogICAgICAgIHN0cjMwXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjMwKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MjAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjMwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMzBCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMzFfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMzEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMzEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4NDAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjMxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMzEoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIzMV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIzMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMxID0gMzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIzMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMzFfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIzMV8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMzEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIzMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjMxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMxID0gMzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjMxKCkgewogICAgICAgIHN0cjMxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjMxKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4NDAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjMxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMzFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMzFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMzJfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMzIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4ODAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMzIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIzMl87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBzdHIzMl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMyID0gMzI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRTdHIzMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMzJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBzdHIzMl8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdHIzMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjMyID0gMzI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjMyKCkgewogICAgICAgIHN0cjMyXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjMyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIHN0cjMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMzJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgc3RyMzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk1hbnlPcHRpb25hbFN0cmluZykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuTWFueU9wdGlvbmFsU3RyaW5nKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5NYW55T3B0aW9uYWxTdHJpbmcoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTWFueU9wdGlvbmFsU3RyaW5nIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TWFueU9wdGlvbmFsU3RyaW5nPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE1hbnlPcHRpb25hbFN0cmluZz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIE1hbnlPcHRpb25hbFN0cmluZyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE1hbnlPcHRpb25hbFN0cmluZz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxNYW55T3B0aW9uYWxTdHJpbmc+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uTWFueU9wdGlvbmFsU3RyaW5nIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgSW50MzJNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkludDMyTWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGF0YSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRGF0YSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkYXRhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkYXRhLgogICAgICovCiAgICBpbnQgZ2V0RGF0YSgpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRlc3QgaW50MzIsIHVpbnQzMiwgaW50NjQsIHVpbnQ2NCwgYW5kIGJvb2wgYXJlIGFsbCBjb21wYXRpYmxlCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5JbnQzMk1lc3NhZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBJbnQzMk1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuSW50MzJNZXNzYWdlKQogICAgICBJbnQzMk1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEludDMyTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBJbnQzMk1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBJbnQzMk1lc3NhZ2UoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgSW50MzJNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfSW50MzJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfSW50MzJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMk1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEQVRBX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBkYXRhXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGF0YSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0RhdGEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZGF0YSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGF0YS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXREYXRhKCkgewogICAgICByZXR1cm4gZGF0YV87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBkYXRhXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgZGF0YV8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSkgb2JqOwoKICAgICAgaWYgKGhhc0RhdGEoKSAhPSBvdGhlci5oYXNEYXRhKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0RhdGEoKSkgewogICAgICAgIGlmIChnZXREYXRhKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RGF0YSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzRGF0YSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgREFUQV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RGF0YSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMk1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0IGludDMyLCB1aW50MzIsIGludDY0LCB1aW50NjQsIGFuZCBib29sIGFyZSBhbGwgY29tcGF0aWJsZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuSW50MzJNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuSW50MzJNZXNzYWdlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDMyTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbnQzMk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMk1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMk1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGRhdGFfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfSW50MzJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMk1lc3NhZ2UodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMk1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZGF0YV8gPSBkYXRhXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0RhdGEoKSkgewogICAgICAgICAgc2V0RGF0YShvdGhlci5nZXREYXRhKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIGRhdGFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBkYXRhXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGF0YSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0RhdGEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRhdGEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RGF0YSgpIHsKICAgICAgICByZXR1cm4gZGF0YV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkYXRhIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGF0YShpbnQgdmFsdWUpIHsKCiAgICAgICAgZGF0YV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEYXRhKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBkYXRhXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuSW50MzJNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5JbnQzMk1lc3NhZ2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMk1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxJbnQzMk1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8SW50MzJNZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgSW50MzJNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8SW50MzJNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEludDMyTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMk1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBVaW50MzJNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlVpbnQzMk1lc3NhZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgZGF0YSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkYXRhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEYXRhKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBkYXRhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkYXRhLgogICAgICovCiAgICBpbnQgZ2V0RGF0YSgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5VaW50MzJNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVWludDMyTWVzc2FnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5VaW50MzJNZXNzYWdlKQogICAgICBVaW50MzJNZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBVaW50MzJNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFVpbnQzMk1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBVaW50MzJNZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFVpbnQzMk1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9VaW50MzJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVWludDMyTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50MzJNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEQVRBX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBkYXRhXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBkYXRhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRhdGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEYXRhKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBkYXRhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkYXRhLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldERhdGEoKSB7CiAgICAgIHJldHVybiBkYXRhXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigxLCBkYXRhXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKDEsIGRhdGFfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQzMk1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQzMk1lc3NhZ2UpIG9iajsKCiAgICAgIGlmIChoYXNEYXRhKCkgIT0gb3RoZXIuaGFzRGF0YSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEYXRhKCkpIHsKICAgICAgICBpZiAoZ2V0RGF0YSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldERhdGEoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0RhdGEoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERBVEFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldERhdGEoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50MzJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50MzJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50MzJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQzMk1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50MzJNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50MzJNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQzMk1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQzMk1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVWludDMyTWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlVpbnQzMk1lc3NhZ2UpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50MzJNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1VpbnQzMk1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVWludDMyTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQzMk1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgZGF0YV8gPSAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9VaW50MzJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQzMk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQzMk1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQzMk1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50MzJNZXNzYWdlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kYXRhXyA9IGRhdGFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50MzJNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQzMk1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50MzJNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0RhdGEoKSkgewogICAgICAgICAgc2V0RGF0YShvdGhlci5nZXREYXRhKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIGRhdGFfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgZGF0YV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkYXRhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRGF0YSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRhdGEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RGF0YSgpIHsKICAgICAgICByZXR1cm4gZGF0YV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZGF0YSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldERhdGEoaW50IHZhbHVlKSB7CgogICAgICAgIGRhdGFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgZGF0YSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRhdGEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGRhdGFfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5VaW50MzJNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5VaW50MzJNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50MzJNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDMyTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50MzJNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VWludDMyTWVzc2FnZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxVaW50MzJNZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVWludDMyTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFVpbnQzMk1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VWludDMyTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50MzJNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgSW50NjRNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkludDY0TWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGF0YSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRGF0YSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBkYXRhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkYXRhLgogICAgICovCiAgICBsb25nIGdldERhdGEoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuSW50NjRNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgSW50NjRNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkludDY0TWVzc2FnZSkKICAgICAgSW50NjRNZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBJbnQ2NE1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgSW50NjRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgSW50NjRNZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEludDY0TWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDY0TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDY0TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0TWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREFUQV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBsb25nIGRhdGFfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGF0YSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0RhdGEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgZGF0YSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGF0YS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0RGF0YSgpIHsKICAgICAgcmV0dXJuIGRhdGFfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMSwgZGF0YV8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplKDEsIGRhdGFfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0TWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2UpIG9iajsKCiAgICAgIGlmIChoYXNEYXRhKCkgIT0gb3RoZXIuaGFzRGF0YSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEYXRhKCkpIHsKICAgICAgICBpZiAoZ2V0RGF0YSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldERhdGEoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0RhdGEoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERBVEFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldERhdGEoKSk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0TWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuSW50NjRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuSW50NjRNZXNzYWdlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDY0TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbnQ2NE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGRhdGFfID0gMEw7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDY0TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0TWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRNZXNzYWdlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRNZXNzYWdlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRhdGFfID0gZGF0YV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0TWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNEYXRhKCkpIHsKICAgICAgICAgIHNldERhdGEob3RoZXIuZ2V0RGF0YSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBkYXRhXyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBsb25nIGRhdGFfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkYXRhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRGF0YSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZGF0YS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0RGF0YSgpIHsKICAgICAgICByZXR1cm4gZGF0YV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkYXRhIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RGF0YShsb25nIHZhbHVlKSB7CgogICAgICAgIGRhdGFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGF0YSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgZGF0YV8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5JbnQ2NE1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkludDY0TWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEludDY0TWVzc2FnZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxJbnQ2NE1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBJbnQ2NE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxJbnQ2NE1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8SW50NjRNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFVpbnQ2NE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVWludDY0TWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBkYXRhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRhdGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0RhdGEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRhdGEuCiAgICAgKi8KICAgIGxvbmcgZ2V0RGF0YSgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5VaW50NjRNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVWludDY0TWVzc2FnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5VaW50NjRNZXNzYWdlKQogICAgICBVaW50NjRNZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBVaW50NjRNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFVpbnQ2NE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBVaW50NjRNZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFVpbnQ2NE1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9VaW50NjRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVWludDY0TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDY0TWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50NjRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEQVRBX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGxvbmcgZGF0YV8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGF0YSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0RhdGEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRhdGEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldERhdGEoKSB7CiAgICAgIHJldHVybiBkYXRhXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCgxLCBkYXRhXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplKDEsIGRhdGFfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQ2NE1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDY0TWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQ2NE1lc3NhZ2UpIG9iajsKCiAgICAgIGlmIChoYXNEYXRhKCkgIT0gb3RoZXIuaGFzRGF0YSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNEYXRhKCkpIHsKICAgICAgICBpZiAoZ2V0RGF0YSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldERhdGEoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0RhdGEoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIERBVEFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldERhdGEoKSk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDY0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQ2NE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDY0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDY0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQ2NE1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQ2NE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50NjRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDY0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDY0TWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50NjRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQ2NE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQ2NE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50NjRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlVpbnQ2NE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5VaW50NjRNZXNzYWdlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDY0TWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9VaW50NjRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1VpbnQ2NE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50NjRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQ2NE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQ2NE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGRhdGFfID0gMEw7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1VpbnQ2NE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50NjRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDY0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50NjRNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDY0TWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDY0TWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50NjRNZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQ2NE1lc3NhZ2UodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50NjRNZXNzYWdlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmRhdGFfID0gZGF0YV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQ2NE1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDY0TWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlVpbnQ2NE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50NjRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzRGF0YSgpKSB7CiAgICAgICAgICBzZXREYXRhKG90aGVyLmdldERhdGEoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgZGF0YV8gPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGxvbmcgZGF0YV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDY0IGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkYXRhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRGF0YSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGRhdGEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldERhdGEoKSB7CiAgICAgICAgcmV0dXJuIGRhdGFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50NjQgZGF0YSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRhdGEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREYXRhKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZGF0YV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQ2NCBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRGF0YSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgZGF0YV8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5VaW50NjRNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5VaW50NjRNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50NjRNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVWludDY0TWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50NjRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VWludDY0TWVzc2FnZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxVaW50NjRNZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVWludDY0TWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFVpbnQ2NE1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VWludDY0TWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5VaW50NjRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgQm9vbE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuQm9vbE1lc3NhZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGF0YSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRGF0YSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRhdGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGRhdGEuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0RGF0YSgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5Cb29sTWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJvb2xNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkJvb2xNZXNzYWdlKQogICAgICBCb29sTWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgQm9vbE1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgQm9vbE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBCb29sTWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBCb29sTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Jvb2xNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQm9vbE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEQVRBX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGJvb2xlYW4gZGF0YV8gPSBmYWxzZTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkYXRhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGRhdGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNEYXRhKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGF0YSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZGF0YS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZ2V0RGF0YSgpIHsKICAgICAgcmV0dXJuIGRhdGFfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgxLCBkYXRhXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSgxLCBkYXRhXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sTWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sTWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlKSBvYmo7CgogICAgICBpZiAoaGFzRGF0YSgpICE9IG90aGVyLmhhc0RhdGEoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRGF0YSgpKSB7CiAgICAgICAgaWYgKGdldERhdGEoKQogICAgICAgICAgICAhPSBvdGhlci5nZXREYXRhKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNEYXRhKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEQVRBX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKAogICAgICAgICAgICBnZXREYXRhKCkpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQm9vbE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5Cb29sTWVzc2FnZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Jvb2xNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Jvb2xNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBkYXRhXyA9IGZhbHNlOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Cb29sTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5kYXRhXyA9IGRhdGFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sTWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sTWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNEYXRhKCkpIHsKICAgICAgICAgIHNldERhdGEob3RoZXIuZ2V0RGF0YSgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBkYXRhXyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGJvb2xlYW4gZGF0YV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBkYXRhID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZGF0YSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0RhdGEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIGRhdGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZGF0YS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0RGF0YSgpIHsKICAgICAgICByZXR1cm4gZGF0YV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGF0YSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGRhdGEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXREYXRhKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZGF0YV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgZGF0YSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckRhdGEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGRhdGFfID0gZmFsc2U7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQm9vbE1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkJvb2xNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Qm9vbE1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Qm9vbE1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCb29sTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJvb2xNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJvb2xNZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE9uZW9mT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vSW50IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb29JbnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZm9vX2ludCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vSW50LgogICAgICovCiAgICBpbnQgZ2V0Rm9vSW50KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29TdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0Zvb1N0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vU3RyaW5nLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZvb1N0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZvb1N0cmluZy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0Rm9vU3RyaW5nQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRm9vTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29NZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRGb29NZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0Rm9vTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+Z3JvdXAgRm9vR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb2dyb3VwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb29Hcm91cCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5ncm91cCBGb29Hcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb2dyb3VwLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCBnZXRGb29Hcm91cCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5ncm91cCBGb29Hcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXBPckJ1aWxkZXIgZ2V0Rm9vR3JvdXBPckJ1aWxkZXIoKTsKCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29DYXNlIGdldEZvb0Nhc2UoKTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBUZXN0IG9uZW9mcy4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RPbmVvZiBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YpCiAgICAgIFRlc3RPbmVvZk9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE9uZW9mLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RPbmVvZihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RPbmVvZigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0T25lb2YoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2ZfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2ZfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBGb29Hcm91cE9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZi5Gb29Hcm91cCkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzQSgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICAgKi8KICAgICAgaW50IGdldEEoKTsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNCKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICAgKi8KICAgICAgamF2YS5sYW5nLlN0cmluZyBnZXRCKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYi4KICAgICAgICovCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0QkJ5dGVzKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZi5Gb29Hcm91cH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGb29Hcm91cCBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mLkZvb0dyb3VwKQogICAgICAgIEZvb0dyb3VwT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgRm9vR3JvdXAubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBGb29Hcm91cChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIEZvb0dyb3VwKCkgewogICAgICAgIGJfID0gIiI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgRm9vR3JvdXAoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZl9Gb29Hcm91cF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2ZfRm9vR3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBX0ZJRUxEX05VTUJFUiA9IDU7CiAgICAgIHByaXZhdGUgaW50IGFfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgIHJldHVybiBhXzsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQl9GSUVMRF9OVU1CRVIgPSA2OwogICAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGJfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNCKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0QigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBiXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBiLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRCQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBiXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDUsIGFfKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDYsIGJfKTsKICAgICAgICB9CiAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNSwgYV8pOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoNiwgYl8pOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXApIG9iajsKCiAgICAgICAgaWYgKGhhc0EoKSAhPSBvdGhlci5oYXNBKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzQSgpKSB7CiAgICAgICAgICBpZiAoZ2V0QSgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmIChoYXNCKCkgIT0gb3RoZXIuaGFzQigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc0IoKSkgewogICAgICAgICAgaWYgKCFnZXRCKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QSgpOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzQigpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEIoKS5oYXNoQ29kZSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YuRm9vR3JvdXB9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZi5Gb29Hcm91cCkKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZl9Gb29Hcm91cF9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mX0Zvb0dyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBhXyA9IDA7CiAgICAgICAgICBiXyA9ICIiOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2ZfRm9vR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LmFfID0gYV87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5iXyA9IGJfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXApIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXApb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAgb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzQSgpKSB7CiAgICAgICAgICAgIHNldEEob3RoZXIuZ2V0QSgpKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChvdGhlci5oYXNCKCkpIHsKICAgICAgICAgICAgYl8gPSBvdGhlci5iXzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgNDA6IHsKICAgICAgICAgICAgICAgICAgYV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA0MAogICAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgICBiXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCBhXyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDU7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA1OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldEEoKSB7CiAgICAgICAgICByZXR1cm4gYV87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA1OzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGEgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRBKGludCB2YWx1ZSkgewoKICAgICAgICAgIGFfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gNTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQSgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIGFfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgYl8gPSAiIjsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDY7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYiBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzQigpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSA2OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEIoKSB7CiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGJfOwogICAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgICAgYl8gPSBzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gNjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGIuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgICBnZXRCQnl0ZXMoKSB7CiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGJfOwogICAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgICAgYl8gPSBiOwogICAgICAgICAgICByZXR1cm4gYjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gNjs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBiIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QigKICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICAgIGJfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDY7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckIoKSB7CiAgICAgICAgICBiXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldEIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gNjs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgYiB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJCeXRlcygKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgICAgYl8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mLkZvb0dyb3VwKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mLkZvb0dyb3VwKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvb0dyb3VwPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Rm9vR3JvdXA+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRm9vR3JvdXAgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb29Hcm91cD4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvb0dyb3VwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgZm9vQ2FzZV8gPSAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgZm9vXzsKICAgIHB1YmxpYyBlbnVtIEZvb0Nhc2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkludGVybmFsT25lT2ZFbnVtIHsKICAgICAgRk9PX0lOVCgxKSwKICAgICAgRk9PX1NUUklORygyKSwKICAgICAgRk9PX01FU1NBR0UoMyksCiAgICAgIEZPT0dST1VQKDQpLAogICAgICBGT09fTk9UX1NFVCgwKTsKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CiAgICAgIHByaXZhdGUgRm9vQ2FzZShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtYmVyIG9mIHRoZSBlbnVtIHRvIGxvb2sgZm9yLgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtYmVyLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIEZvb0Nhc2UgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBGb29DYXNlIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDE6IHJldHVybiBGT09fSU5UOwogICAgICAgICAgY2FzZSAyOiByZXR1cm4gRk9PX1NUUklORzsKICAgICAgICAgIGNhc2UgMzogcmV0dXJuIEZPT19NRVNTQUdFOwogICAgICAgICAgY2FzZSA0OiByZXR1cm4gRk9PR1JPVVA7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBGT09fTk9UX1NFVDsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgRm9vQ2FzZQogICAgZ2V0Rm9vQ2FzZSgpIHsKICAgICAgcmV0dXJuIEZvb0Nhc2UuZm9yTnVtYmVyKAogICAgICAgICAgZm9vQ2FzZV8pOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19JTlRfRklFTERfTlVNQkVSID0gMTsKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZm9vX2ludCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29JbnQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29JbnQoKSB7CiAgICAgIHJldHVybiBmb29DYXNlXyA9PSAxOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBmb29faW50ID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29JbnQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Rm9vSW50KCkgewogICAgICBpZiAoZm9vQ2FzZV8gPT0gMSkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIGZvb187CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX1NUUklOR19GSUVMRF9OVU1CRVIgPSAyOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29TdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29TdHJpbmcoKSB7CiAgICAgIHJldHVybiBmb29DYXNlXyA9PSAyOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vU3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGb29TdHJpbmcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChmb29DYXNlXyA9PSAyKSB7CiAgICAgICAgcmVmID0gZm9vXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkgJiYgKGZvb0Nhc2VfID09IDIpKSB7CiAgICAgICAgICBmb29fID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBmb29TdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGb29TdHJpbmdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICByZWYgPSBmb29fOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGlmIChmb29DYXNlXyA9PSAyKSB7CiAgICAgICAgICBmb29fID0gYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDM7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb01lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBmb29DYXNlXyA9PSAzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29NZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0Rm9vTWVzc2FnZSgpIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDMpIHsKICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcykgZm9vXzsKICAgICAgfQogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldEZvb01lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMpIGZvb187CiAgICAgIH0KICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT0dST1VQX0ZJRUxEX05VTUJFUiA9IDQ7CiAgICAvKioKICAgICAqIDxjb2RlPmdyb3VwIEZvb0dyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29ncm91cCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb0dyb3VwKCkgewogICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gNDsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Z3JvdXAgRm9vR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29ncm91cC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwIGdldEZvb0dyb3VwKCkgewogICAgICBpZiAoZm9vQ2FzZV8gPT0gNCkgewogICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwKSBmb29fOwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Z3JvdXAgRm9vR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cE9yQnVpbGRlciBnZXRGb29Hcm91cE9yQnVpbGRlcigpIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDQpIHsKICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCkgZm9vXzsKICAgICAgfQogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoZm9vQ2FzZV8gPT0gMSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKAogICAgICAgICAgICAxLCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIGZvb18pKTsKICAgICAgfQogICAgICBpZiAoZm9vQ2FzZV8gPT0gMikgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMiwgZm9vXyk7CiAgICAgIH0KICAgICAgaWYgKGZvb0Nhc2VfID09IDMpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDMsIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcykgZm9vXyk7CiAgICAgIH0KICAgICAgaWYgKGZvb0Nhc2VfID09IDQpIHsKICAgICAgICBvdXRwdXQud3JpdGVHcm91cCg0LCAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXApIGZvb18pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoZm9vQ2FzZV8gPT0gMSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoCiAgICAgICAgICAgICAgMSwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSBmb29fKSk7CiAgICAgIH0KICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDIsIGZvb18pOwogICAgICB9CiAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcykgZm9vXyk7CiAgICAgIH0KICAgICAgaWYgKGZvb0Nhc2VfID09IDQpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlR3JvdXBTaXplKDQsIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCkgZm9vXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mKSBvYmo7CgogICAgICBpZiAoIWdldEZvb0Nhc2UoKS5lcXVhbHMob3RoZXIuZ2V0Rm9vQ2FzZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBzd2l0Y2ggKGZvb0Nhc2VfKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgaWYgKGdldEZvb0ludCgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0Rm9vSW50KCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgIGlmICghZ2V0Rm9vU3RyaW5nKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZvb1N0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgaWYgKCFnZXRGb29NZXNzYWdlKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZvb01lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIGlmICghZ2V0Rm9vR3JvdXAoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Rm9vR3JvdXAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgc3dpdGNoIChmb29DYXNlXykgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZPT19JTlRfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Rm9vSW50KCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGT09fU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZvb1N0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDM6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGT09fTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGb29NZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZPT0dST1VQX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZvb0dyb3VwKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUZXN0IG9uZW9mcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2ZfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoZm9vTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZvb01lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBpZiAoZm9vR3JvdXBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmb29Hcm91cEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZiBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBidWlsZFBhcnRpYWxPbmVvZnMocmVzdWx0KTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxPbmVvZnMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YgcmVzdWx0KSB7CiAgICAgICAgcmVzdWx0LmZvb0Nhc2VfID0gZm9vQ2FzZV87CiAgICAgICAgcmVzdWx0LmZvb18gPSB0aGlzLmZvb187CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDMgJiYKICAgICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJlc3VsdC5mb29fID0gZm9vTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChmb29DYXNlXyA9PSA0ICYmCiAgICAgICAgICAgIGZvb0dyb3VwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVzdWx0LmZvb18gPSBmb29Hcm91cEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBzd2l0Y2ggKG90aGVyLmdldEZvb0Nhc2UoKSkgewogICAgICAgICAgY2FzZSBGT09fSU5UOiB7CiAgICAgICAgICAgIHNldEZvb0ludChvdGhlci5nZXRGb29JbnQoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGT09fU1RSSU5HOiB7CiAgICAgICAgICAgIGZvb0Nhc2VfID0gMjsKICAgICAgICAgICAgZm9vXyA9IG90aGVyLmZvb187CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRk9PX01FU1NBR0U6IHsKICAgICAgICAgICAgbWVyZ2VGb29NZXNzYWdlKG90aGVyLmdldEZvb01lc3NhZ2UoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGT09HUk9VUDogewogICAgICAgICAgICBtZXJnZUZvb0dyb3VwKG90aGVyLmdldEZvb0dyb3VwKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRk9PX05PVF9TRVQ6IHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgZm9vXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZm9vQ2FzZV8gPSAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGZvb0Nhc2VfID0gMjsKICAgICAgICAgICAgICAgIGZvb18gPSBiczsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldEZvb01lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgZm9vQ2FzZV8gPSAzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNTogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZEdyb3VwKDQsCiAgICAgICAgICAgICAgICAgICAgZ2V0Rm9vR3JvdXBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgZm9vQ2FzZV8gPSA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM1CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgZm9vQ2FzZV8gPSAwOwogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgZm9vXzsKICAgICAgcHVibGljIEZvb0Nhc2UKICAgICAgICAgIGdldEZvb0Nhc2UoKSB7CiAgICAgICAgcmV0dXJuIEZvb0Nhc2UuZm9yTnVtYmVyKAogICAgICAgICAgICBmb29DYXNlXyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vKCkgewogICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBmb29faW50ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vSW50IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb0ludCgpIHsKICAgICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgZm9vX2ludCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmb29JbnQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZvb0ludCgpIHsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMSkgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgZm9vXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb29JbnQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29JbnQoaW50IHZhbHVlKSB7CgogICAgICAgIGZvb0Nhc2VfID0gMTsKICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb29JbnQoKSB7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDEpIHsKICAgICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29TdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmb29fc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZvb1N0cmluZy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Rm9vU3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICAgIHJlZiA9IGZvb187CiAgICAgICAgfQogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgICBmb29fID0gczsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZvb1N0cmluZy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0Rm9vU3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMikgewogICAgICAgICAgcmVmID0gZm9vXzsKICAgICAgICB9CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSAyKSB7CiAgICAgICAgICAgIGZvb18gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZvb1N0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvb1N0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGZvb0Nhc2VfID0gMjsKICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmb29fc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vU3RyaW5nKCkgewogICAgICAgIGlmIChmb29DYXNlXyA9PSAyKSB7CiAgICAgICAgICBmb29DYXNlXyA9IDA7CiAgICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgZm9vU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vU3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGZvb0Nhc2VfID0gMjsKICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gZm9vTWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb01lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29NZXNzYWdlKCkgewogICAgICAgIHJldHVybiBmb29DYXNlXyA9PSAzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZvb01lc3NhZ2UuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRGb29NZXNzYWdlKCkgewogICAgICAgIGlmIChmb29NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDMpIHsKICAgICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcykgZm9vXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDMpIHsKICAgICAgICAgICAgcmV0dXJuIGZvb01lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29NZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKGZvb01lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZvb18gPSB2YWx1ZTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb29NZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGZvb0Nhc2VfID0gMzsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZvb01lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmb29fID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDM7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRm9vTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChmb29NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDMgJiYKICAgICAgICAgICAgICBmb29fICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGZvb18gPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5uZXdCdWlsZGVyKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcykgZm9vXykKICAgICAgICAgICAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9vXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgICAgIGZvb01lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDM7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vTWVzc2FnZSgpIHsKICAgICAgICBpZiAoZm9vTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMykgewogICAgICAgICAgICBmb29DYXNlXyA9IDA7CiAgICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRGb29NZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0Rm9vTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0Rm9vTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoKGZvb0Nhc2VfID09IDMpICYmIChmb29NZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICAgIHJldHVybiBmb29NZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMykgewogICAgICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzKSBmb29fOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZvb01lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZvb01lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIShmb29DYXNlXyA9PSAzKSkgewogICAgICAgICAgICBmb29fID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBmb29NZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMpIGZvb18sCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZm9vQ2FzZV8gPSAzOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmb29NZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cE9yQnVpbGRlcj4gZm9vR3JvdXBCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZvb0dyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb2dyb3VwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vR3JvdXAoKSB7CiAgICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZvb0dyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmb29ncm91cC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwIGdldEZvb0dyb3VwKCkgewogICAgICAgIGlmIChmb29Hcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSA0KSB7CiAgICAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXApIGZvb187CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSA0KSB7CiAgICAgICAgICAgIHJldHVybiBmb29Hcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZvb0dyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vR3JvdXAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAgdmFsdWUpIHsKICAgICAgICBpZiAoZm9vR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZvb18gPSB2YWx1ZTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb29Hcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZvb0dyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vR3JvdXAoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmb29Hcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZvb18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb29Hcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZvb0dyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGb29Hcm91cChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cCB2YWx1ZSkgewogICAgICAgIGlmIChmb29Hcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSA0ICYmCiAgICAgICAgICAgICAgZm9vXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBmb29fID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAubmV3QnVpbGRlcigocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXApIGZvb18pCiAgICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvb18gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gNCkgewogICAgICAgICAgICBmb29Hcm91cEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb29Hcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZvb0dyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb29Hcm91cCgpIHsKICAgICAgICBpZiAoZm9vR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gNCkgewogICAgICAgICAgICBmb29DYXNlXyA9IDA7CiAgICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDQpIHsKICAgICAgICAgICAgZm9vQ2FzZV8gPSAwOwogICAgICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIGZvb0dyb3VwQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZvb0dyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwLkJ1aWxkZXIgZ2V0Rm9vR3JvdXBCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRGb29Hcm91cEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Z3JvdXAgRm9vR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cE9yQnVpbGRlciBnZXRGb29Hcm91cE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoKGZvb0Nhc2VfID09IDQpICYmIChmb29Hcm91cEJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgICByZXR1cm4gZm9vR3JvdXBCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSA0KSB7CiAgICAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXApIGZvb187CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ncm91cCBGb29Hcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZi5Gb29Hcm91cE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGb29Hcm91cEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoZm9vR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIShmb29DYXNlXyA9PSA0KSkgewogICAgICAgICAgICBmb29fID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBmb29Hcm91cEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YuRm9vR3JvdXAsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mLkZvb0dyb3VwKSBmb29fLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGZvb0Nhc2VfID0gNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZm9vR3JvdXBCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZiBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RPbmVvZj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0T25lb2Y+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0T25lb2YgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0T25lb2Y+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE9uZW9mPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vSW50IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb29JbnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vX2ludCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vSW50LgogICAgICovCiAgICBpbnQgZ2V0Rm9vSW50KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29TdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0Zvb1N0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vU3RyaW5nLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZvb1N0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZvb1N0cmluZy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0Rm9vU3RyaW5nQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRm9vTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29NZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRGb29NZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0Rm9vTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRm9vR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb2dyb3VwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb29Hcm91cCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGb29Hcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb2dyb3VwLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAgZ2V0Rm9vR3JvdXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRm9vR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cE9yQnVpbGRlciBnZXRGb29Hcm91cE9yQnVpbGRlcigpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlKQogICAgICBUZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlKCkgewogICAgICBmb29TdHJpbmdfID0gIiI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGVfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBGb29Hcm91cE9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXApCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc0EoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIGludCBnZXRBKCk7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzQigpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYi4KICAgICAgICovCiAgICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0QigpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGIuCiAgICAgICAqLwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldEJCeXRlcygpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEZvb0dyb3VwIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwKQogICAgICAgIEZvb0dyb3VwT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgRm9vR3JvdXAubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBGb29Hcm91cChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIEZvb0dyb3VwKCkgewogICAgICAgIGJfID0gIiI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgRm9vR3JvdXAoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGVfRm9vR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZV9Gb29Hcm91cF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQV9GSUVMRF9OVU1CRVIgPSA1OwogICAgICBwcml2YXRlIGludCBhXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0QSgpIHsKICAgICAgICByZXR1cm4gYV87CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJfRklFTERfTlVNQkVSID0gNjsKICAgICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBiXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBiXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgYl8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0QkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBiXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig1LCBhXyk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCA2LCBiXyk7CiAgICAgICAgfQogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDUsIGFfKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDYsIGJfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwKSBvYmo7CgogICAgICAgIGlmIChoYXNBKCkgIT0gb3RoZXIuaGFzQSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgICAgaWYgKGdldEEoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEEoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzQigpICE9IG90aGVyLmhhc0IoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNCKCkpIHsKICAgICAgICAgIGlmICghZ2V0QigpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRCKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzQSgpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBBX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEEoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc0IoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQl9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCKCkuaGFzaENvZGUoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXB9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXApCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXBPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZV9Gb29Hcm91cF9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZV9Gb29Hcm91cF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgYV8gPSAwOwogICAgICAgICAgYl8gPSAiIjsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZV9Gb29Hcm91cF9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cCBidWlsZCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cCByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5hXyA9IGFfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQuYl8gPSBiXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cCkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXApb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChvdGhlci5oYXNBKCkpIHsKICAgICAgICAgICAgc2V0QShvdGhlci5nZXRBKCkpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKG90aGVyLmhhc0IoKSkgewogICAgICAgICAgICBiXyA9IG90aGVyLmJfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA0MDogewogICAgICAgICAgICAgICAgICBhXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDQwCiAgICAgICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgICAgIGJfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgNTAKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgaW50IGFfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gNTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDU7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0QSgpIHsKICAgICAgICAgIHJldHVybiBhXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDU7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYSB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEEoaW50IHZhbHVlKSB7CgogICAgICAgICAgYV8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA1OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgYV8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBiXyA9ICIiOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gNjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNCKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDY7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGIuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0QigpIHsKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYl87CiAgICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgICBiXyA9IHM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSA2OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYi4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICAgIGdldEJCeXRlcygpIHsKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYl87CiAgICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgICBiXyA9IGI7CiAgICAgICAgICAgIHJldHVybiBiOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSA2OzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGIgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRCKAogICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgICAgYl8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gNjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQigpIHsKICAgICAgICAgIGJfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0QigpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSA2OzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBiIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QkJ5dGVzKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgICBiXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cCkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb29Hcm91cD4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZvb0dyb3VwPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEZvb0dyb3VwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Rm9vR3JvdXA+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb29Hcm91cD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX0lOVF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgZm9vSW50XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vSW50IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vSW50KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb0ludC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGb29JbnQoKSB7CiAgICAgIHJldHVybiBmb29JbnRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19TVFJJTkdfRklFTERfTlVNQkVSID0gMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGZvb1N0cmluZ18gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vU3RyaW5nKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmb29fc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29TdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZvb1N0cmluZygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBmb29TdHJpbmdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIGZvb1N0cmluZ18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZvb1N0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZvb1N0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGZvb1N0cmluZ187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGZvb1N0cmluZ18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBmb29NZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29NZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29NZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0Rm9vTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIGZvb01lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZvb01lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRGb29NZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gZm9vTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZm9vTWVzc2FnZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PR1JPVVBfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwIGZvb0dyb3VwXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRm9vR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb2dyb3VwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vR3JvdXAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRm9vR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29ncm91cC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cCBnZXRGb29Hcm91cCgpIHsKICAgICAgcmV0dXJuIGZvb0dyb3VwXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZm9vR3JvdXBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGb29Hcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cE9yQnVpbGRlciBnZXRGb29Hcm91cE9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGZvb0dyb3VwXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZm9vR3JvdXBfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgZm9vSW50Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyLCBmb29TdHJpbmdfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDMsIGdldEZvb01lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlR3JvdXAoNCwgZ2V0Rm9vR3JvdXAoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgZm9vSW50Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyLCBmb29TdHJpbmdfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgZ2V0Rm9vTWVzc2FnZSgpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlR3JvdXBTaXplKDQsIGdldEZvb0dyb3VwKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSkgb2JqOwoKICAgICAgaWYgKGhhc0Zvb0ludCgpICE9IG90aGVyLmhhc0Zvb0ludCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGb29JbnQoKSkgewogICAgICAgIGlmIChnZXRGb29JbnQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGb29JbnQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGb29TdHJpbmcoKSAhPSBvdGhlci5oYXNGb29TdHJpbmcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRm9vU3RyaW5nKCkpIHsKICAgICAgICBpZiAoIWdldEZvb1N0cmluZygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Rm9vU3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0Zvb01lc3NhZ2UoKSAhPSBvdGhlci5oYXNGb29NZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0Zvb01lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0Rm9vTWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Rm9vTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGb29Hcm91cCgpICE9IG90aGVyLmhhc0Zvb0dyb3VwKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0Zvb0dyb3VwKCkpIHsKICAgICAgICBpZiAoIWdldEZvb0dyb3VwKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGb29Hcm91cCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0Zvb0ludCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX0lOVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Rm9vSW50KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0Zvb1N0cmluZygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Rm9vU3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRm9vTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZvb01lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNGb29Hcm91cCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PR1JPVVBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZvb0dyb3VwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRGb29NZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRGb29Hcm91cEZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgZm9vSW50XyA9IDA7CiAgICAgICAgZm9vU3RyaW5nXyA9ICIiOwogICAgICAgIGZvb01lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAoZm9vTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZvb01lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmb29NZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBmb29Hcm91cF8gPSBudWxsOwogICAgICAgIGlmIChmb29Hcm91cEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZvb0dyb3VwQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgZm9vR3JvdXBCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5mb29JbnRfID0gZm9vSW50XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5mb29TdHJpbmdfID0gZm9vU3RyaW5nXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5mb29NZXNzYWdlXyA9IGZvb01lc3NhZ2VCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBmb29NZXNzYWdlXwogICAgICAgICAgICAgIDogZm9vTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZm9vR3JvdXBfID0gZm9vR3JvdXBCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBmb29Hcm91cF8KICAgICAgICAgICAgICA6IGZvb0dyb3VwQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNGb29JbnQoKSkgewogICAgICAgICAgc2V0Rm9vSW50KG90aGVyLmdldEZvb0ludCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0Zvb1N0cmluZygpKSB7CiAgICAgICAgICBmb29TdHJpbmdfID0gb3RoZXIuZm9vU3RyaW5nXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRm9vTWVzc2FnZSgpKSB7CiAgICAgICAgICBtZXJnZUZvb01lc3NhZ2Uob3RoZXIuZ2V0Rm9vTWVzc2FnZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0Zvb0dyb3VwKCkpIHsKICAgICAgICAgIG1lcmdlRm9vR3JvdXAob3RoZXIuZ2V0Rm9vR3JvdXAoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgZm9vSW50XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBmb29TdHJpbmdfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRGb29NZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzU6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRHcm91cCg0LAogICAgICAgICAgICAgICAgICAgIGdldEZvb0dyb3VwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNQogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBmb29JbnRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29JbnQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29JbnQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb29faW50ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZvb0ludC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGb29JbnQoKSB7CiAgICAgICAgcmV0dXJuIGZvb0ludF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb29JbnQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29JbnQoaW50IHZhbHVlKSB7CgogICAgICAgIGZvb0ludF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb29JbnQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGZvb0ludF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgZm9vU3RyaW5nXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29TdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vU3RyaW5nKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZm9vU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Rm9vU3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZm9vU3RyaW5nXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIGZvb1N0cmluZ18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZvb1N0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldEZvb1N0cmluZ0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gZm9vU3RyaW5nXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgZm9vU3RyaW5nXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBmb29fc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZm9vU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZm9vU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb29TdHJpbmcoKSB7CiAgICAgICAgZm9vU3RyaW5nXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldEZvb1N0cmluZygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgZm9vU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vU3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGZvb1N0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZm9vTWVzc2FnZV87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gZm9vTWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb01lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vTWVzc2FnZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZm9vTWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRGb29NZXNzYWdlKCkgewogICAgICAgIGlmIChmb29NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZvb01lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZvb01lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZm9vTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvb01lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAoZm9vTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZm9vTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvb01lc3NhZ2UoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmb29NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZm9vTWVzc2FnZV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRm9vTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChmb29NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApICYmCiAgICAgICAgICAgIGZvb01lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgZm9vTWVzc2FnZV8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0Rm9vTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9vTWVzc2FnZV8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChmb29NZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vTWVzc2FnZSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgZm9vTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChmb29NZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGZvb01lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRGb29NZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZvb01lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRGb29NZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChmb29NZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZvb01lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBmb29NZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZvb01lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZvb01lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZvb01lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmb29NZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRGb29NZXNzYWdlKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmb29NZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmb29NZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwIGZvb0dyb3VwXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwT3JCdWlsZGVyPiBmb29Hcm91cEJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRm9vR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vZ3JvdXAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vR3JvdXAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGb29Hcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZm9vZ3JvdXAuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwIGdldEZvb0dyb3VwKCkgewogICAgICAgIGlmIChmb29Hcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBmb29Hcm91cF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZvb0dyb3VwXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGZvb0dyb3VwQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgRm9vR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29Hcm91cChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAgdmFsdWUpIHsKICAgICAgICBpZiAoZm9vR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZvb0dyb3VwXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb29Hcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZvb0dyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vR3JvdXAoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZm9vR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmb29Hcm91cF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZm9vR3JvdXBCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGb29Hcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRm9vR3JvdXAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwIHZhbHVlKSB7CiAgICAgICAgaWYgKGZvb0dyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApICYmCiAgICAgICAgICAgIGZvb0dyb3VwXyAhPSBudWxsICYmCiAgICAgICAgICAgIGZvb0dyb3VwXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0Rm9vR3JvdXBCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvb0dyb3VwXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb29Hcm91cEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChmb29Hcm91cF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGb29Hcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vR3JvdXAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGZvb0dyb3VwXyA9IG51bGw7CiAgICAgICAgaWYgKGZvb0dyb3VwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZm9vR3JvdXBCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBmb29Hcm91cEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZvb0dyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cC5CdWlsZGVyIGdldEZvb0dyb3VwQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldEZvb0dyb3VwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBGb29Hcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXBPckJ1aWxkZXIgZ2V0Rm9vR3JvdXBPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZvb0dyb3VwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGZvb0dyb3VwQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gZm9vR3JvdXBfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZvb0dyb3VwXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIEZvb0dyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0dyb3VwT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZvb0dyb3VwRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmb29Hcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZvb0dyb3VwQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXAsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZS5Gb29Hcm91cC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUuRm9vR3JvdXBPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRGb29Hcm91cCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgZm9vR3JvdXBfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZvb0dyb3VwQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RPbmVvZjJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vSW50IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb29JbnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZm9vX2ludCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vSW50LgogICAgICovCiAgICBpbnQgZ2V0Rm9vSW50KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29TdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0Zvb1N0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vU3RyaW5nLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEZvb1N0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZvb1N0cmluZy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0Rm9vU3RyaW5nQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmb29fY29yZCA9IDMgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29Db3JkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb29Db3JkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmb29fY29yZCA9IDMgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vQ29yZC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGb29Db3JkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmb29fY29yZCA9IDMgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZvb0NvcmQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZvb0NvcmRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmdfcGllY2UgPSA0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29TdHJpbmdQaWVjZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRm9vU3RyaW5nUGllY2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmdfcGllY2UgPSA0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0Rm9vU3RyaW5nUGllY2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmdfcGllY2UgPSA0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZvb1N0cmluZ1BpZWNlLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGb29TdHJpbmdQaWVjZUJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBmb29fYnl0ZXMgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0Zvb0J5dGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGZvb19ieXRlcyA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vQnl0ZXMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGb29CeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bSBmb29fZW51bSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29FbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb29FbnVtKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZEVudW0gZm9vX2VudW0gPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb0VudW0uCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIGdldEZvb0VudW0oKTsKCiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgZm9vX21lc3NhZ2UgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRm9vTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIGZvb19tZXNzYWdlID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29NZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBnZXRGb29NZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgZm9vX21lc3NhZ2UgPSA3OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0Rm9vTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+Z3JvdXAgRm9vR3JvdXAgPSA4IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb2dyb3VwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb29Hcm91cCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5ncm91cCBGb29Hcm91cCA9IDggeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb2dyb3VwLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAgZ2V0Rm9vR3JvdXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+Z3JvdXAgRm9vR3JvdXAgPSA4IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cE9yQnVpbGRlciBnZXRGb29Hcm91cE9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBmb29fbGF6eV9tZXNzYWdlID0gMTEgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb0xhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb29MYXp5TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIGZvb19sYXp5X21lc3NhZ2UgPSAxMSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb0xhenlNZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBnZXRGb29MYXp5TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIGZvb19sYXp5X21lc3NhZ2UgPSAxMSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0Rm9vTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGZvb19ieXRlc19jb3JkID0gMzAgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29CeXRlc0NvcmQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0Zvb0J5dGVzQ29yZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBmb29fYnl0ZXNfY29yZCA9IDMwIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb0J5dGVzQ29yZC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZvb0J5dGVzQ29yZCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgYmFyX2ludCA9IDEyIFtkZWZhdWx0ID0gNV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJJbnQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0JhckludCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBiYXJfaW50ID0gMTIgW2RlZmF1bHQgPSA1XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXJJbnQuCiAgICAgKi8KICAgIGludCBnZXRCYXJJbnQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nID0gMTMgW2RlZmF1bHQgPSAiU1RSSU5HIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0JhclN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX3N0cmluZyA9IDEzIFtkZWZhdWx0ID0gIlNUUklORyJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJhclN0cmluZy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRCYXJTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmcgPSAxMyBbZGVmYXVsdCA9ICJTVFJJTkciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYmFyU3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRCYXJTdHJpbmdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGJhcl9jb3JkID0gMTQgW2RlZmF1bHQgPSAiQ09SRCIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJDb3JkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNCYXJDb3JkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBiYXJfY29yZCA9IDE0IFtkZWZhdWx0ID0gIkNPUkQiLCBjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJhckNvcmQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0QmFyQ29yZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX2NvcmQgPSAxNCBbZGVmYXVsdCA9ICJDT1JEIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYmFyQ29yZC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0QmFyQ29yZEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX3N0cmluZ19waWVjZSA9IDE1IFtkZWZhdWx0ID0gIlNQSUVDRSIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJhclN0cmluZ1BpZWNlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNCYXJTdHJpbmdQaWVjZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX3N0cmluZ19waWVjZSA9IDE1IFtkZWZhdWx0ID0gIlNQSUVDRSIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXJTdHJpbmdQaWVjZS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRCYXJTdHJpbmdQaWVjZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX3N0cmluZ19waWVjZSA9IDE1IFtkZWZhdWx0ID0gIlNQSUVDRSIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYmFyU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEJhclN0cmluZ1BpZWNlQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGJhcl9ieXRlcyA9IDE2IFtkZWZhdWx0ID0gIkJZVEVTIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQmFyQnl0ZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgYmFyX2J5dGVzID0gMTYgW2RlZmF1bHQgPSAiQllURVMiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXJCeXRlcy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEJhckJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIGJhcl9lbnVtID0gMTcgW2RlZmF1bHQgPSBCQVJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmFyRW51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQmFyRW51bSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIGJhcl9lbnVtID0gMTcgW2RlZmF1bHQgPSBCQVJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJhckVudW0uCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIGdldEJhckVudW0oKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIwIFtkZWZhdWx0ID0gIiJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX3N0cmluZ193aXRoX2VtcHR5X2RlZmF1bHQgPSAyMCBbZGVmYXVsdCA9ICIiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXJTdHJpbmdXaXRoRW1wdHlEZWZhdWx0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEJhclN0cmluZ1dpdGhFbXB0eURlZmF1bHQoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmdfd2l0aF9lbXB0eV9kZWZhdWx0ID0gMjAgW2RlZmF1bHQgPSAiIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGJhclN0cmluZ1dpdGhFbXB0eURlZmF1bHQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEJhclN0cmluZ1dpdGhFbXB0eURlZmF1bHRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGJhcl9jb3JkX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIxIFtkZWZhdWx0ID0gIiIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJDb3JkV2l0aEVtcHR5RGVmYXVsdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQmFyQ29yZFdpdGhFbXB0eURlZmF1bHQoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGJhcl9jb3JkX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIxIFtkZWZhdWx0ID0gIiIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYmFyQ29yZFdpdGhFbXB0eURlZmF1bHQuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0QmFyQ29yZFdpdGhFbXB0eURlZmF1bHQoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGJhcl9jb3JkX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIxIFtkZWZhdWx0ID0gIiIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGJhckNvcmRXaXRoRW1wdHlEZWZhdWx0LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRCYXJDb3JkV2l0aEVtcHR5RGVmYXVsdEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX3N0cmluZ19waWVjZV93aXRoX2VtcHR5X2RlZmF1bHQgPSAyMiBbZGVmYXVsdCA9ICIiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJTdHJpbmdQaWVjZVdpdGhFbXB0eURlZmF1bHQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0JhclN0cmluZ1BpZWNlV2l0aEVtcHR5RGVmYXVsdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX3N0cmluZ19waWVjZV93aXRoX2VtcHR5X2RlZmF1bHQgPSAyMiBbZGVmYXVsdCA9ICIiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYmFyU3RyaW5nUGllY2VXaXRoRW1wdHlEZWZhdWx0LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEJhclN0cmluZ1BpZWNlV2l0aEVtcHR5RGVmYXVsdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX3N0cmluZ19waWVjZV93aXRoX2VtcHR5X2RlZmF1bHQgPSAyMiBbZGVmYXVsdCA9ICIiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGJhclN0cmluZ1BpZWNlV2l0aEVtcHR5RGVmYXVsdC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0QmFyU3RyaW5nUGllY2VXaXRoRW1wdHlEZWZhdWx0Qnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGJhcl9ieXRlc193aXRoX2VtcHR5X2RlZmF1bHQgPSAyMyBbZGVmYXVsdCA9ICIiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJhckJ5dGVzV2l0aEVtcHR5RGVmYXVsdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQmFyQnl0ZXNXaXRoRW1wdHlEZWZhdWx0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGJhcl9ieXRlc193aXRoX2VtcHR5X2RlZmF1bHQgPSAyMyBbZGVmYXVsdCA9ICIiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXJCeXRlc1dpdGhFbXB0eURlZmF1bHQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRCYXJCeXRlc1dpdGhFbXB0eURlZmF1bHQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJhel9pbnQgPSAxODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJhekludCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQmF6SW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJhel9pbnQgPSAxODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXpJbnQuCiAgICAgKi8KICAgIGludCBnZXRCYXpJbnQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiYXpfc3RyaW5nID0gMTkgW2RlZmF1bHQgPSAiQkFaIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXpTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0JhelN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYmF6X3N0cmluZyA9IDE5IFtkZWZhdWx0ID0gIkJBWiJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJhelN0cmluZy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRCYXpTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGJhel9zdHJpbmcgPSAxOSBbZGVmYXVsdCA9ICJCQVoiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYmF6U3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRCYXpTdHJpbmdCeXRlcygpOwoKICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29DYXNlIGdldEZvb0Nhc2UoKTsKCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuQmFyQ2FzZSBnZXRCYXJDYXNlKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjJ9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0T25lb2YyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIpCiAgICAgIFRlc3RPbmVvZjJPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RPbmVvZjIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdE9uZW9mMihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RPbmVvZjIoKSB7CiAgICAgIGJhelN0cmluZ18gPSAiQkFaIjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0T25lb2YyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mMl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZjJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bX0KICAgICAqLwogICAgcHVibGljIGVudW0gTmVzdGVkRW51bQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgRk9PKDEpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QkFSID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBCQVIoMiksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVogPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEJBWigzKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSX1ZBTFVFID0gMjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBWiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFaX1ZBTFVFID0gMzsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIEZPTzsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIEJBUjsKICAgICAgICAgIGNhc2UgMzogcmV0dXJuIEJBWjsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPE5lc3RlZEVudW0+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBOZXN0ZWRFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIE5lc3RlZEVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIE5lc3RlZEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgTmVzdGVkRW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBOZXN0ZWRFbnVtIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgTmVzdGVkRW51bShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bSkKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIEZvb0dyb3VwT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5Gb29Hcm91cCkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzQSgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBhLgogICAgICAgKi8KICAgICAgaW50IGdldEEoKTsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzQigpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGIuCiAgICAgICAqLwogICAgICBqYXZhLmxhbmcuU3RyaW5nIGdldEIoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYi4KICAgICAgICovCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0QkJ5dGVzKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuRm9vR3JvdXB9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRm9vR3JvdXAgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuRm9vR3JvdXApCiAgICAgICAgRm9vR3JvdXBPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBGb29Hcm91cC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIEZvb0dyb3VwKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgRm9vR3JvdXAoKSB7CiAgICAgICAgYl8gPSAiIjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBGb29Hcm91cCgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mMl9Gb29Hcm91cF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2YyX0Zvb0dyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBX0ZJRUxEX05VTUJFUiA9IDk7CiAgICAgIHByaXZhdGUgaW50IGFfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgIHJldHVybiBhXzsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQl9GSUVMRF9OVU1CRVIgPSAxMDsKICAgICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBiXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0IoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0QigpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGJfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBiXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0QkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBiXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig5LCBhXyk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMCwgYl8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg5LCBhXyk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxMCwgYl8pOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXApKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXApIG9iajsKCiAgICAgICAgaWYgKGhhc0EoKSAhPSBvdGhlci5oYXNBKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzQSgpKSB7CiAgICAgICAgICBpZiAoZ2V0QSgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmIChoYXNCKCkgIT0gb3RoZXIuaGFzQigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc0IoKSkgewogICAgICAgICAgaWYgKCFnZXRCKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEIoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QSgpOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzQigpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEIoKS5oYXNoQ29kZSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5Gb29Hcm91cH0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5Gb29Hcm91cCkKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cE9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2YyX0Zvb0dyb3VwX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2YyX0Zvb0dyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cC5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBhXyA9IDA7CiAgICAgICAgICBiXyA9ICIiOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2YyX0Zvb0dyb3VwX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwIGJ1aWxkKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LmFfID0gYV87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5iXyA9IGJfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cClvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAgb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc0EoKSkgewogICAgICAgICAgICBzZXRBKG90aGVyLmdldEEoKSk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAob3RoZXIuaGFzQigpKSB7CiAgICAgICAgICAgIGJfID0gb3RoZXIuYl87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDcyOiB7CiAgICAgICAgICAgICAgICAgIGFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgNzIKICAgICAgICAgICAgICAgIGNhc2UgODI6IHsKICAgICAgICAgICAgICAgICAgYl8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBpbnQgYV8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSA5OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gOTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgICAgcmV0dXJuIGFfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gOTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBhIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QShpbnQgdmFsdWUpIHsKCiAgICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDk7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBhXyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGJfID0gIiI7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGIgPSAxMDs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNCKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDEwOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBiLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEIoKSB7CiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGJfOwogICAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgICAgYl8gPSBzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gMTA7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBiLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgICAgZ2V0QkJ5dGVzKCkgewogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBiXzsKICAgICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICAgIGJfID0gYjsKICAgICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYiA9IDEwOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGIgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRCKAogICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgICAgYl8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gMTA7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckIoKSB7CiAgICAgICAgICBiXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldEIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiID0gMTA7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGIgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRCQnl0ZXMoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICAgIGJfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuRm9vR3JvdXApCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLkZvb0dyb3VwKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvb0dyb3VwPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Rm9vR3JvdXA+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRm9vR3JvdXAgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb29Hcm91cD4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvb0dyb3VwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG1vb19pbnQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtb29JbnQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNNb29JbnQoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG1vb19pbnQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbW9vSW50LgogICAgICAgKi8KICAgICAgbG9uZyBnZXRNb29JbnQoKTsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBjb3JnZV9pbnQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgY29yZ2VJbnQuCiAgICAgICAqLwogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0Q29yZ2VJbnRMaXN0KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBjb3JnZV9pbnQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgY29yZ2VJbnQuCiAgICAgICAqLwogICAgICBpbnQgZ2V0Q29yZ2VJbnRDb3VudCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgY29yZ2VfaW50ID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3JnZUludCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBpbnQgZ2V0Q29yZ2VJbnQoaW50IGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZE1lc3NhZ2UgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSkKICAgICAgICBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBOZXN0ZWRNZXNzYWdlKCkgewogICAgICAgIGNvcmdlSW50XyA9IGVtcHR5SW50TGlzdCgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZjJfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2YyX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNT09fSU5UX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgbG9uZyBtb29JbnRfID0gMEw7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBtb29faW50ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbW9vSW50IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzTW9vSW50KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgbW9vX2ludCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBtb29JbnQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE1vb0ludCgpIHsKICAgICAgICByZXR1cm4gbW9vSW50XzsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ09SR0VfSU5UX0ZJRUxEX05VTUJFUiA9IDI7CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBjb3JnZUludF8gPQogICAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBjb3JnZV9pbnQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgY29yZ2VJbnQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldENvcmdlSW50TGlzdCgpIHsKICAgICAgICByZXR1cm4gY29yZ2VJbnRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBjb3JnZV9pbnQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgY29yZ2VJbnQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldENvcmdlSW50Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIGNvcmdlSW50Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGNvcmdlX2ludCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgY29yZ2VJbnQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRDb3JnZUludChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gY29yZ2VJbnRfLmdldEludChpbmRleCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgxLCBtb29JbnRfKTsKICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBjb3JnZUludF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIGNvcmdlSW50Xy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSgxLCBtb29JbnRfKTsKICAgICAgICB9CiAgICAgICAgewogICAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgY29yZ2VJbnRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGNvcmdlSW50Xy5nZXRJbnQoaSkpOwogICAgICAgICAgfQogICAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICAgIHNpemUgKz0gMSAqIGdldENvcmdlSW50TGlzdCgpLnNpemUoKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UpKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICAgIGlmIChoYXNNb29JbnQoKSAhPSBvdGhlci5oYXNNb29JbnQoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNNb29JbnQoKSkgewogICAgICAgICAgaWYgKGdldE1vb0ludCgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0TW9vSW50KCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRDb3JnZUludExpc3QoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldENvcmdlSW50TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzTW9vSW50KCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1PT19JTlRfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgICBnZXRNb29JbnQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChnZXRDb3JnZUludENvdW50KCkgPiAwKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBDT1JHRV9JTlRfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Q29yZ2VJbnRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2YyX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZjJfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgbW9vSW50XyA9IDBMOwogICAgICAgICAgY29yZ2VJbnRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZjJfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQubW9vSW50XyA9IG1vb0ludF87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICAgIGNvcmdlSW50Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIHJlc3VsdC5jb3JnZUludF8gPSBjb3JnZUludF87CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2Upb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzTW9vSW50KCkpIHsKICAgICAgICAgICAgc2V0TW9vSW50KG90aGVyLmdldE1vb0ludCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICghb3RoZXIuY29yZ2VJbnRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAoY29yZ2VJbnRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGNvcmdlSW50XyA9IG90aGVyLmNvcmdlSW50XzsKICAgICAgICAgICAgICBjb3JnZUludF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVDb3JnZUludElzTXV0YWJsZSgpOwogICAgICAgICAgICAgIGNvcmdlSW50Xy5hZGRBbGwob3RoZXIuY29yZ2VJbnRfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgICBtb29JbnRfID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBlbnN1cmVDb3JnZUludElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBjb3JnZUludF8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgICBlbnN1cmVDb3JnZUludElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgY29yZ2VJbnRfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBsb25nIG1vb0ludF8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG1vb19pbnQgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG1vb0ludCBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc01vb0ludCgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgbW9vX2ludCA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIG1vb0ludC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGxvbmcgZ2V0TW9vSW50KCkgewogICAgICAgICAgcmV0dXJuIG1vb0ludF87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG1vb19pbnQgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG1vb0ludCB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE1vb0ludChsb25nIHZhbHVlKSB7CgogICAgICAgICAgbW9vSW50XyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgbW9vX2ludCA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1vb0ludCgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIG1vb0ludF8gPSAwTDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBjb3JnZUludF8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBwcml2YXRlIHZvaWQgZW5zdXJlQ29yZ2VJbnRJc011dGFibGUoKSB7CiAgICAgICAgICBpZiAoIWNvcmdlSW50Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgICBjb3JnZUludF8gPSBtYWtlTXV0YWJsZUNvcHkoY29yZ2VJbnRfKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgY29yZ2VfaW50ID0gMjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgY29yZ2VJbnQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgICBnZXRDb3JnZUludExpc3QoKSB7CiAgICAgICAgICBjb3JnZUludF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmV0dXJuIGNvcmdlSW50XzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgY29yZ2VfaW50ID0gMjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgY29yZ2VJbnQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGludCBnZXRDb3JnZUludENvdW50KCkgewogICAgICAgICAgcmV0dXJuIGNvcmdlSW50Xy5zaXplKCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGNvcmdlX2ludCA9IDI7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgICAqIEByZXR1cm4gVGhlIGNvcmdlSW50IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgaW50IGdldENvcmdlSW50KGludCBpbmRleCkgewogICAgICAgICAgcmV0dXJuIGNvcmdlSW50Xy5nZXRJbnQoaW5kZXgpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBjb3JnZV9pbnQgPSAyOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBjb3JnZUludCB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldENvcmdlSW50KAogICAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICAgIGVuc3VyZUNvcmdlSW50SXNNdXRhYmxlKCk7CiAgICAgICAgICBjb3JnZUludF8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBjb3JnZV9pbnQgPSAyOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGNvcmdlSW50IHRvIGFkZC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQ29yZ2VJbnQoaW50IHZhbHVlKSB7CgogICAgICAgICAgZW5zdXJlQ29yZ2VJbnRJc011dGFibGUoKTsKICAgICAgICAgIGNvcmdlSW50Xy5hZGRJbnQodmFsdWUpOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgY29yZ2VfaW50ID0gMjs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgY29yZ2VJbnQgdG8gYWRkLgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxDb3JnZUludCgKICAgICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgICBlbnN1cmVDb3JnZUludElzTXV0YWJsZSgpOwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgIHZhbHVlcywgY29yZ2VJbnRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIGNvcmdlX2ludCA9IDI7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckNvcmdlSW50KCkgewogICAgICAgICAgY29yZ2VJbnRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkTWVzc2FnZT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBOZXN0ZWRNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHJpdmF0ZSBpbnQgZm9vQ2FzZV8gPSAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgZm9vXzsKICAgIHB1YmxpYyBlbnVtIEZvb0Nhc2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkludGVybmFsT25lT2ZFbnVtIHsKICAgICAgRk9PX0lOVCgxKSwKICAgICAgRk9PX1NUUklORygyKSwKICAgICAgRk9PX0NPUkQoMyksCiAgICAgIEZPT19TVFJJTkdfUElFQ0UoNCksCiAgICAgIEZPT19CWVRFUyg1KSwKICAgICAgRk9PX0VOVU0oNiksCiAgICAgIEZPT19NRVNTQUdFKDcpLAogICAgICBGT09HUk9VUCg4KSwKICAgICAgRk9PX0xBWllfTUVTU0FHRSgxMSksCiAgICAgIEZPT19CWVRFU19DT1JEKDMwKSwKICAgICAgRk9PX05PVF9TRVQoMCk7CiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwogICAgICBwcml2YXRlIEZvb0Nhc2UoaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWJlciBvZiB0aGUgZW51bSB0byBsb29rIGZvci4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWJlci4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBGb29DYXNlIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgRm9vQ2FzZSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAxOiByZXR1cm4gRk9PX0lOVDsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIEZPT19TVFJJTkc7CiAgICAgICAgICBjYXNlIDM6IHJldHVybiBGT09fQ09SRDsKICAgICAgICAgIGNhc2UgNDogcmV0dXJuIEZPT19TVFJJTkdfUElFQ0U7CiAgICAgICAgICBjYXNlIDU6IHJldHVybiBGT09fQllURVM7CiAgICAgICAgICBjYXNlIDY6IHJldHVybiBGT09fRU5VTTsKICAgICAgICAgIGNhc2UgNzogcmV0dXJuIEZPT19NRVNTQUdFOwogICAgICAgICAgY2FzZSA4OiByZXR1cm4gRk9PR1JPVVA7CiAgICAgICAgICBjYXNlIDExOiByZXR1cm4gRk9PX0xBWllfTUVTU0FHRTsKICAgICAgICAgIGNhc2UgMzA6IHJldHVybiBGT09fQllURVNfQ09SRDsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIEZPT19OT1RfU0VUOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB0aGlzLnZhbHVlOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBGb29DYXNlCiAgICBnZXRGb29DYXNlKCkgewogICAgICByZXR1cm4gRm9vQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICBmb29DYXNlXyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYmFyQ2FzZV8gPSAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgYmFyXzsKICAgIHB1YmxpYyBlbnVtIEJhckNhc2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkludGVybmFsT25lT2ZFbnVtIHsKICAgICAgQkFSX0lOVCgxMiksCiAgICAgIEJBUl9TVFJJTkcoMTMpLAogICAgICBCQVJfQ09SRCgxNCksCiAgICAgIEJBUl9TVFJJTkdfUElFQ0UoMTUpLAogICAgICBCQVJfQllURVMoMTYpLAogICAgICBCQVJfRU5VTSgxNyksCiAgICAgIEJBUl9TVFJJTkdfV0lUSF9FTVBUWV9ERUZBVUxUKDIwKSwKICAgICAgQkFSX0NPUkRfV0lUSF9FTVBUWV9ERUZBVUxUKDIxKSwKICAgICAgQkFSX1NUUklOR19QSUVDRV9XSVRIX0VNUFRZX0RFRkFVTFQoMjIpLAogICAgICBCQVJfQllURVNfV0lUSF9FTVBUWV9ERUZBVUxUKDIzKSwKICAgICAgQkFSX05PVF9TRVQoMCk7CiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwogICAgICBwcml2YXRlIEJhckNhc2UoaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWJlciBvZiB0aGUgZW51bSB0byBsb29rIGZvci4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWJlci4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBCYXJDYXNlIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgQmFyQ2FzZSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAxMjogcmV0dXJuIEJBUl9JTlQ7CiAgICAgICAgICBjYXNlIDEzOiByZXR1cm4gQkFSX1NUUklORzsKICAgICAgICAgIGNhc2UgMTQ6IHJldHVybiBCQVJfQ09SRDsKICAgICAgICAgIGNhc2UgMTU6IHJldHVybiBCQVJfU1RSSU5HX1BJRUNFOwogICAgICAgICAgY2FzZSAxNjogcmV0dXJuIEJBUl9CWVRFUzsKICAgICAgICAgIGNhc2UgMTc6IHJldHVybiBCQVJfRU5VTTsKICAgICAgICAgIGNhc2UgMjA6IHJldHVybiBCQVJfU1RSSU5HX1dJVEhfRU1QVFlfREVGQVVMVDsKICAgICAgICAgIGNhc2UgMjE6IHJldHVybiBCQVJfQ09SRF9XSVRIX0VNUFRZX0RFRkFVTFQ7CiAgICAgICAgICBjYXNlIDIyOiByZXR1cm4gQkFSX1NUUklOR19QSUVDRV9XSVRIX0VNUFRZX0RFRkFVTFQ7CiAgICAgICAgICBjYXNlIDIzOiByZXR1cm4gQkFSX0JZVEVTX1dJVEhfRU1QVFlfREVGQVVMVDsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIEJBUl9OT1RfU0VUOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB0aGlzLnZhbHVlOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBCYXJDYXNlCiAgICBnZXRCYXJDYXNlKCkgewogICAgICByZXR1cm4gQmFyQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICBiYXJDYXNlXyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX0lOVF9GSUVMRF9OVU1CRVIgPSAxOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBmb29faW50ID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb0ludCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb0ludCgpIHsKICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDE7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb0ludC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGb29JbnQoKSB7CiAgICAgIGlmIChmb29DYXNlXyA9PSAxKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgZm9vXzsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDI7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmb29fc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb1N0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb1N0cmluZygpIHsKICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDI7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmb29fc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29TdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZvb1N0cmluZygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICByZWYgPSBmb29fOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSAmJiAoZm9vQ2FzZV8gPT0gMikpIHsKICAgICAgICAgIGZvb18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZvb1N0cmluZy4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZvb1N0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAoZm9vQ2FzZV8gPT0gMikgewogICAgICAgIHJlZiA9IGZvb187CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICAgIGZvb18gPSBiOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX0NPUkRfRklFTERfTlVNQkVSID0gMzsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZvb19jb3JkID0gMyBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb0NvcmQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29Db3JkKCkgewogICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gMzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZvb19jb3JkID0gMyBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29Db3JkLgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGb29Db3JkKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAoZm9vQ2FzZV8gPT0gMykgewogICAgICAgIHJlZiA9IGZvb187CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpICYmIChmb29DYXNlXyA9PSAzKSkgewogICAgICAgICAgZm9vXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmb29fY29yZCA9IDMgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZvb0NvcmQuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGb29Db3JkQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgcmVmID0gZm9vXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMykgewogICAgICAgICAgZm9vXyA9IGI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fU1RSSU5HX1BJRUNFX0ZJRUxEX05VTUJFUiA9IDQ7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmb29fc3RyaW5nX3BpZWNlID0gNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vU3RyaW5nUGllY2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29TdHJpbmdQaWVjZSgpIHsKICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDQ7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmb29fc3RyaW5nX3BpZWNlID0gNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb1N0cmluZ1BpZWNlLgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGb29TdHJpbmdQaWVjZSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgaWYgKGZvb0Nhc2VfID09IDQpIHsKICAgICAgICByZWYgPSBmb29fOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSAmJiAoZm9vQ2FzZV8gPT0gNCkpIHsKICAgICAgICAgIGZvb18gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZ19waWVjZSA9IDQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZm9vU3RyaW5nUGllY2UuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRGb29TdHJpbmdQaWVjZUJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAoZm9vQ2FzZV8gPT0gNCkgewogICAgICAgIHJlZiA9IGZvb187CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDQpIHsKICAgICAgICAgIGZvb18gPSBiOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX0JZVEVTX0ZJRUxEX05VTUJFUiA9IDU7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGZvb19ieXRlcyA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29CeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb0J5dGVzKCkgewogICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gNTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgZm9vX2J5dGVzID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29CeXRlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRGb29CeXRlcygpIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDUpIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgZm9vXzsKICAgICAgfQogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19FTlVNX0ZJRUxEX05VTUJFUiA9IDY7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZEVudW0gZm9vX2VudW0gPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vRW51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb0VudW0oKSB7CiAgICAgIHJldHVybiBmb29DYXNlXyA9PSA2OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIGZvb19lbnVtID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29FbnVtLgogICAgICovCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZEVudW0gZ2V0Rm9vRW51bSgpIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDYpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkRW51bS5mb3JOdW1iZXIoCiAgICAgICAgICAgIChqYXZhLmxhbmcuSW50ZWdlcikgZm9vXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZEVudW0uRk9PIDogcmVzdWx0OwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkRW51bS5GT087CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX01FU1NBR0VfRklFTERfTlVNQkVSID0gNzsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29NZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDc7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgZm9vX21lc3NhZ2UgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb01lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBnZXRGb29NZXNzYWdlKCkgewogICAgICBpZiAoZm9vQ2FzZV8gPT0gNykgewogICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlKSBmb29fOwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0Rm9vTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDcpIHsKICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSkgZm9vXzsKICAgICAgfQogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PR1JPVVBfRklFTERfTlVNQkVSID0gODsKICAgIC8qKgogICAgICogPGNvZGU+Z3JvdXAgRm9vR3JvdXAgPSA4IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb2dyb3VwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vR3JvdXAoKSB7CiAgICAgIHJldHVybiBmb29DYXNlXyA9PSA4OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5ncm91cCBGb29Hcm91cCA9IDggeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb2dyb3VwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwIGdldEZvb0dyb3VwKCkgewogICAgICBpZiAoZm9vQ2FzZV8gPT0gOCkgewogICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCkgZm9vXzsKICAgICAgfQogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5ncm91cCBGb29Hcm91cCA9IDggeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cE9yQnVpbGRlciBnZXRGb29Hcm91cE9yQnVpbGRlcigpIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDgpIHsKICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXApIGZvb187CiAgICAgIH0KICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDExOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIGZvb19sYXp5X21lc3NhZ2UgPSAxMSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vTGF6eU1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29MYXp5TWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDExOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIGZvb19sYXp5X21lc3NhZ2UgPSAxMSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb0xhenlNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgZ2V0Rm9vTGF6eU1lc3NhZ2UoKSB7CiAgICAgIGlmIChmb29DYXNlXyA9PSAxMSkgewogICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlKSBmb29fOwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBmb29fbGF6eV9tZXNzYWdlID0gMTEgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRGb29MYXp5TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDExKSB7CiAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UpIGZvb187CiAgICAgIH0KICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19CWVRFU19DT1JEX0ZJRUxEX05VTUJFUiA9IDMwOwogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBmb29fYnl0ZXNfY29yZCA9IDMwIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vQnl0ZXNDb3JkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vQnl0ZXNDb3JkKCkgewogICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gMzA7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGZvb19ieXRlc19jb3JkID0gMzAgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vQnl0ZXNDb3JkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZvb0J5dGVzQ29yZCgpIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDMwKSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIGZvb187CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVJfSU5UX0ZJRUxEX05VTUJFUiA9IDEyOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBiYXJfaW50ID0gMTIgW2RlZmF1bHQgPSA1XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJhckludCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0JhckludCgpIHsKICAgICAgcmV0dXJuIGJhckNhc2VfID09IDEyOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBiYXJfaW50ID0gMTIgW2RlZmF1bHQgPSA1XTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXJJbnQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0QmFySW50KCkgewogICAgICBpZiAoYmFyQ2FzZV8gPT0gMTIpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSBiYXJfOwogICAgICB9CiAgICAgIHJldHVybiA1OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9TVFJJTkdfRklFTERfTlVNQkVSID0gMTM7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nID0gMTMgW2RlZmF1bHQgPSAiU1RSSU5HIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNCYXJTdHJpbmcoKSB7CiAgICAgIHJldHVybiBiYXJDYXNlXyA9PSAxMzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmcgPSAxMyBbZGVmYXVsdCA9ICJTVFJJTkciXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXJTdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEJhclN0cmluZygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiU1RSSU5HIjsKICAgICAgaWYgKGJhckNhc2VfID09IDEzKSB7CiAgICAgICAgcmVmID0gYmFyXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkgJiYgKGJhckNhc2VfID09IDEzKSkgewogICAgICAgICAgYmFyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nID0gMTMgW2RlZmF1bHQgPSAiU1RSSU5HIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGJhclN0cmluZy4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEJhclN0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICJTVFJJTkciOwogICAgICBpZiAoYmFyQ2FzZV8gPT0gMTMpIHsKICAgICAgICByZWYgPSBiYXJfOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGlmIChiYXJDYXNlXyA9PSAxMykgewogICAgICAgICAgYmFyXyA9IGI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVJfQ09SRF9GSUVMRF9OVU1CRVIgPSAxNDsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGJhcl9jb3JkID0gMTQgW2RlZmF1bHQgPSAiQ09SRCIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJDb3JkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzQmFyQ29yZCgpIHsKICAgICAgcmV0dXJuIGJhckNhc2VfID09IDE0OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX2NvcmQgPSAxNCBbZGVmYXVsdCA9ICJDT1JEIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXJDb3JkLgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRCYXJDb3JkKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICJDT1JEIjsKICAgICAgaWYgKGJhckNhc2VfID09IDE0KSB7CiAgICAgICAgcmVmID0gYmFyXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkgJiYgKGJhckNhc2VfID09IDE0KSkgewogICAgICAgICAgYmFyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBiYXJfY29yZCA9IDE0IFtkZWZhdWx0ID0gIkNPUkQiLCBjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBiYXJDb3JkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0QmFyQ29yZEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICJDT1JEIjsKICAgICAgaWYgKGJhckNhc2VfID09IDE0KSB7CiAgICAgICAgcmVmID0gYmFyXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBpZiAoYmFyQ2FzZV8gPT0gMTQpIHsKICAgICAgICAgIGJhcl8gPSBiOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSX1NUUklOR19QSUVDRV9GSUVMRF9OVU1CRVIgPSAxNTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmdfcGllY2UgPSAxNSBbZGVmYXVsdCA9ICJTUElFQ0UiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJTdHJpbmdQaWVjZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc0JhclN0cmluZ1BpZWNlKCkgewogICAgICByZXR1cm4gYmFyQ2FzZV8gPT0gMTU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3BpZWNlID0gMTUgW2RlZmF1bHQgPSAiU1BJRUNFIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJhclN0cmluZ1BpZWNlLgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRCYXJTdHJpbmdQaWVjZSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiU1BJRUNFIjsKICAgICAgaWYgKGJhckNhc2VfID09IDE1KSB7CiAgICAgICAgcmVmID0gYmFyXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkgJiYgKGJhckNhc2VfID09IDE1KSkgewogICAgICAgICAgYmFyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3BpZWNlID0gMTUgW2RlZmF1bHQgPSAiU1BJRUNFIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBiYXJTdHJpbmdQaWVjZS4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEJhclN0cmluZ1BpZWNlQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIlNQSUVDRSI7CiAgICAgIGlmIChiYXJDYXNlXyA9PSAxNSkgewogICAgICAgIHJlZiA9IGJhcl87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDE1KSB7CiAgICAgICAgICBiYXJfID0gYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9CWVRFU19GSUVMRF9OVU1CRVIgPSAxNjsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgYmFyX2J5dGVzID0gMTYgW2RlZmF1bHQgPSAiQllURVMiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJhckJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQmFyQnl0ZXMoKSB7CiAgICAgIHJldHVybiBiYXJDYXNlXyA9PSAxNjsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgYmFyX2J5dGVzID0gMTYgW2RlZmF1bHQgPSAiQllURVMiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXJCeXRlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRCYXJCeXRlcygpIHsKICAgICAgaWYgKGJhckNhc2VfID09IDE2KSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIGJhcl87CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuYnl0ZXNEZWZhdWx0VmFsdWUoIkJZVEVTIik7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSX0VOVU1fRklFTERfTlVNQkVSID0gMTc7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZEVudW0gYmFyX2VudW0gPSAxNyBbZGVmYXVsdCA9IEJBUl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJFbnVtIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzQmFyRW51bSgpIHsKICAgICAgcmV0dXJuIGJhckNhc2VfID09IDE3OwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIGJhcl9lbnVtID0gMTcgW2RlZmF1bHQgPSBCQVJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJhckVudW0uCiAgICAgKi8KICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkRW51bSBnZXRCYXJFbnVtKCkgewogICAgICBpZiAoYmFyQ2FzZV8gPT0gMTcpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkRW51bS5mb3JOdW1iZXIoCiAgICAgICAgICAgIChqYXZhLmxhbmcuSW50ZWdlcikgYmFyXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZEVudW0uQkFSIDogcmVzdWx0OwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkRW51bS5CQVI7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSX1NUUklOR19XSVRIX0VNUFRZX0RFRkFVTFRfRklFTERfTlVNQkVSID0gMjA7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIwIFtkZWZhdWx0ID0gIiJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc0JhclN0cmluZ1dpdGhFbXB0eURlZmF1bHQoKSB7CiAgICAgIHJldHVybiBiYXJDYXNlXyA9PSAyMDsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmdfd2l0aF9lbXB0eV9kZWZhdWx0ID0gMjAgW2RlZmF1bHQgPSAiIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0QmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgaWYgKGJhckNhc2VfID09IDIwKSB7CiAgICAgICAgcmVmID0gYmFyXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkgJiYgKGJhckNhc2VfID09IDIwKSkgewogICAgICAgICAgYmFyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIwIFtkZWZhdWx0ID0gIiJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBiYXJTdHJpbmdXaXRoRW1wdHlEZWZhdWx0LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0QmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAoYmFyQ2FzZV8gPT0gMjApIHsKICAgICAgICByZWYgPSBiYXJfOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGlmIChiYXJDYXNlXyA9PSAyMCkgewogICAgICAgICAgYmFyXyA9IGI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVJfQ09SRF9XSVRIX0VNUFRZX0RFRkFVTFRfRklFTERfTlVNQkVSID0gMjE7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBiYXJfY29yZF93aXRoX2VtcHR5X2RlZmF1bHQgPSAyMSBbZGVmYXVsdCA9ICIiLCBjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmFyQ29yZFdpdGhFbXB0eURlZmF1bHQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNCYXJDb3JkV2l0aEVtcHR5RGVmYXVsdCgpIHsKICAgICAgcmV0dXJuIGJhckNhc2VfID09IDIxOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX2NvcmRfd2l0aF9lbXB0eV9kZWZhdWx0ID0gMjEgW2RlZmF1bHQgPSAiIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXJDb3JkV2l0aEVtcHR5RGVmYXVsdC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0QmFyQ29yZFdpdGhFbXB0eURlZmF1bHQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChiYXJDYXNlXyA9PSAyMSkgewogICAgICAgIHJlZiA9IGJhcl87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpICYmIChiYXJDYXNlXyA9PSAyMSkpIHsKICAgICAgICAgIGJhcl8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX2NvcmRfd2l0aF9lbXB0eV9kZWZhdWx0ID0gMjEgW2RlZmF1bHQgPSAiIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYmFyQ29yZFdpdGhFbXB0eURlZmF1bHQuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRCYXJDb3JkV2l0aEVtcHR5RGVmYXVsdEJ5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAoYmFyQ2FzZV8gPT0gMjEpIHsKICAgICAgICByZWYgPSBiYXJfOwogICAgICB9CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIGlmIChiYXJDYXNlXyA9PSAyMSkgewogICAgICAgICAgYmFyXyA9IGI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVJfU1RSSU5HX1BJRUNFX1dJVEhfRU1QVFlfREVGQVVMVF9GSUVMRF9OVU1CRVIgPSAyMjsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmdfcGllY2Vfd2l0aF9lbXB0eV9kZWZhdWx0ID0gMjIgW2RlZmF1bHQgPSAiIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmFyU3RyaW5nUGllY2VXaXRoRW1wdHlEZWZhdWx0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzQmFyU3RyaW5nUGllY2VXaXRoRW1wdHlEZWZhdWx0KCkgewogICAgICByZXR1cm4gYmFyQ2FzZV8gPT0gMjI7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3BpZWNlX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIyIFtkZWZhdWx0ID0gIiIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXJTdHJpbmdQaWVjZVdpdGhFbXB0eURlZmF1bHQuCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEJhclN0cmluZ1BpZWNlV2l0aEVtcHR5RGVmYXVsdCgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgaWYgKGJhckNhc2VfID09IDIyKSB7CiAgICAgICAgcmVmID0gYmFyXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkgJiYgKGJhckNhc2VfID09IDIyKSkgewogICAgICAgICAgYmFyXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3BpZWNlX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIyIFtkZWZhdWx0ID0gIiIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYmFyU3RyaW5nUGllY2VXaXRoRW1wdHlEZWZhdWx0LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0QmFyU3RyaW5nUGllY2VXaXRoRW1wdHlEZWZhdWx0Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChiYXJDYXNlXyA9PSAyMikgewogICAgICAgIHJlZiA9IGJhcl87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDIyKSB7CiAgICAgICAgICBiYXJfID0gYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9CWVRFU19XSVRIX0VNUFRZX0RFRkFVTFRfRklFTERfTlVNQkVSID0gMjM7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIGJhcl9ieXRlc193aXRoX2VtcHR5X2RlZmF1bHQgPSAyMyBbZGVmYXVsdCA9ICIiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJhckJ5dGVzV2l0aEVtcHR5RGVmYXVsdCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0JhckJ5dGVzV2l0aEVtcHR5RGVmYXVsdCgpIHsKICAgICAgcmV0dXJuIGJhckNhc2VfID09IDIzOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5ieXRlcyBiYXJfYnl0ZXNfd2l0aF9lbXB0eV9kZWZhdWx0ID0gMjMgW2RlZmF1bHQgPSAiIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYmFyQnl0ZXNXaXRoRW1wdHlEZWZhdWx0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEJhckJ5dGVzV2l0aEVtcHR5RGVmYXVsdCgpIHsKICAgICAgaWYgKGJhckNhc2VfID09IDIzKSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIGJhcl87CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuYnl0ZXNEZWZhdWx0VmFsdWUoIiIpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBWl9JTlRfRklFTERfTlVNQkVSID0gMTg7CiAgICBwcml2YXRlIGludCBiYXpJbnRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYmF6X2ludCA9IDE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmF6SW50IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQmF6SW50KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJhel9pbnQgPSAxODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBiYXpJbnQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0QmF6SW50KCkgewogICAgICByZXR1cm4gYmF6SW50XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVpfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDE5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgYmF6U3RyaW5nXyA9ICJCQVoiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYmF6X3N0cmluZyA9IDE5IFtkZWZhdWx0ID0gIkJBWiJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmF6U3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQmF6U3RyaW5nKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiYXpfc3RyaW5nID0gMTkgW2RlZmF1bHQgPSAiQkFaIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYmF6U3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRCYXpTdHJpbmcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYmF6U3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBiYXpTdHJpbmdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGJhel9zdHJpbmcgPSAxOSBbZGVmYXVsdCA9ICJCQVoiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYmF6U3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0QmF6U3RyaW5nQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYmF6U3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgYmF6U3RyaW5nXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDEpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigKICAgICAgICAgICAgMSwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSBmb29fKSk7CiAgICAgIH0KICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDIsIGZvb18pOwogICAgICB9CiAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAzLCBmb29fKTsKICAgICAgfQogICAgICBpZiAoZm9vQ2FzZV8gPT0gNCkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNCwgZm9vXyk7CiAgICAgIH0KICAgICAgaWYgKGZvb0Nhc2VfID09IDUpIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcygKICAgICAgICAgICAgNSwgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgZm9vXyk7CiAgICAgIH0KICAgICAgaWYgKGZvb0Nhc2VfID09IDYpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDYsICgoamF2YS5sYW5nLkludGVnZXIpIGZvb18pKTsKICAgICAgfQogICAgICBpZiAoZm9vQ2FzZV8gPT0gNykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNywgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlKSBmb29fKTsKICAgICAgfQogICAgICBpZiAoZm9vQ2FzZV8gPT0gOCkgewogICAgICAgIG91dHB1dC53cml0ZUdyb3VwKDgsIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXApIGZvb18pOwogICAgICB9CiAgICAgIGlmIChmb29DYXNlXyA9PSAxMSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTEsIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSkgZm9vXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDEyKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoCiAgICAgICAgICAgIDEyLCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIGJhcl8pKTsKICAgICAgfQogICAgICBpZiAoYmFyQ2FzZV8gPT0gMTMpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEzLCBiYXJfKTsKICAgICAgfQogICAgICBpZiAoYmFyQ2FzZV8gPT0gMTQpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDE0LCBiYXJfKTsKICAgICAgfQogICAgICBpZiAoYmFyQ2FzZV8gPT0gMTUpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDE1LCBiYXJfKTsKICAgICAgfQogICAgICBpZiAoYmFyQ2FzZV8gPT0gMTYpIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcygKICAgICAgICAgICAgMTYsIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIGJhcl8pOwogICAgICB9CiAgICAgIGlmIChiYXJDYXNlXyA9PSAxNykgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTcsICgoamF2YS5sYW5nLkludGVnZXIpIGJhcl8pKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxOCwgYmF6SW50Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxOSwgYmF6U3RyaW5nXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDIwKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyMCwgYmFyXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDIxKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyMSwgYmFyXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDIyKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyMiwgYmFyXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDIzKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoCiAgICAgICAgICAgIDIzLCAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSBiYXJfKTsKICAgICAgfQogICAgICBpZiAoZm9vQ2FzZV8gPT0gMzApIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcygKICAgICAgICAgICAgMzAsIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIGZvb18pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoZm9vQ2FzZV8gPT0gMSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoCiAgICAgICAgICAgICAgMSwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSBmb29fKSk7CiAgICAgIH0KICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDIsIGZvb18pOwogICAgICB9CiAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgzLCBmb29fKTsKICAgICAgfQogICAgICBpZiAoZm9vQ2FzZV8gPT0gNCkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoNCwgZm9vXyk7CiAgICAgIH0KICAgICAgaWYgKGZvb0Nhc2VfID09IDUpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplKAogICAgICAgICAgICAgIDUsIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIGZvb18pOwogICAgICB9CiAgICAgIGlmIChmb29DYXNlXyA9PSA2KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDYsICgoamF2YS5sYW5nLkludGVnZXIpIGZvb18pKTsKICAgICAgfQogICAgICBpZiAoZm9vQ2FzZV8gPT0gNykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg3LCAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UpIGZvb18pOwogICAgICB9CiAgICAgIGlmIChmb29DYXNlXyA9PSA4KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUdyb3VwU2l6ZSg4LCAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwKSBmb29fKTsKICAgICAgfQogICAgICBpZiAoZm9vQ2FzZV8gPT0gMTEpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEsIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSkgZm9vXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDEyKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgKICAgICAgICAgICAgICAxMiwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSBiYXJfKSk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDEzKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxMywgYmFyXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDE0KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxNCwgYmFyXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDE1KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxNSwgYmFyXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDE2KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgKICAgICAgICAgICAgICAxNiwgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgYmFyXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDE3KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDE3LCAoKGphdmEubGFuZy5JbnRlZ2VyKSBiYXJfKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxOCwgYmF6SW50Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxOSwgYmF6U3RyaW5nXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDIwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyMCwgYmFyXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDIxKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyMSwgYmFyXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDIyKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyMiwgYmFyXyk7CiAgICAgIH0KICAgICAgaWYgKGJhckNhc2VfID09IDIzKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgKICAgICAgICAgICAgICAyMywgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgYmFyXyk7CiAgICAgIH0KICAgICAgaWYgKGZvb0Nhc2VfID09IDMwKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgKICAgICAgICAgICAgICAzMCwgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgZm9vXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyKSBvYmo7CgogICAgICBpZiAoaGFzQmF6SW50KCkgIT0gb3RoZXIuaGFzQmF6SW50KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0JhekludCgpKSB7CiAgICAgICAgaWYgKGdldEJhekludCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEJhekludCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0JhelN0cmluZygpICE9IG90aGVyLmhhc0JhelN0cmluZygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNCYXpTdHJpbmcoKSkgewogICAgICAgIGlmICghZ2V0QmF6U3RyaW5nKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRCYXpTdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldEZvb0Nhc2UoKS5lcXVhbHMob3RoZXIuZ2V0Rm9vQ2FzZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBzd2l0Y2ggKGZvb0Nhc2VfKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgaWYgKGdldEZvb0ludCgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0Rm9vSW50KCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgIGlmICghZ2V0Rm9vU3RyaW5nKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZvb1N0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgaWYgKCFnZXRGb29Db3JkKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZvb0NvcmQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNDoKICAgICAgICAgIGlmICghZ2V0Rm9vU3RyaW5nUGllY2UoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Rm9vU3RyaW5nUGllY2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNToKICAgICAgICAgIGlmICghZ2V0Rm9vQnl0ZXMoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Rm9vQnl0ZXMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNjoKICAgICAgICAgIGlmICghZ2V0Rm9vRW51bSgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGb29FbnVtKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDc6CiAgICAgICAgICBpZiAoIWdldEZvb01lc3NhZ2UoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Rm9vTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA4OgogICAgICAgICAgaWYgKCFnZXRGb29Hcm91cCgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGb29Hcm91cCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMToKICAgICAgICAgIGlmICghZ2V0Rm9vTGF6eU1lc3NhZ2UoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0Rm9vTGF6eU1lc3NhZ2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMzA6CiAgICAgICAgICBpZiAoIWdldEZvb0J5dGVzQ29yZCgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGb29CeXRlc0NvcmQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGlmICghZ2V0QmFyQ2FzZSgpLmVxdWFscyhvdGhlci5nZXRCYXJDYXNlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHN3aXRjaCAoYmFyQ2FzZV8pIHsKICAgICAgICBjYXNlIDEyOgogICAgICAgICAgaWYgKGdldEJhckludCgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0QmFySW50KCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTM6CiAgICAgICAgICBpZiAoIWdldEJhclN0cmluZygpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRCYXJTdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTQ6CiAgICAgICAgICBpZiAoIWdldEJhckNvcmQoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0QmFyQ29yZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxNToKICAgICAgICAgIGlmICghZ2V0QmFyU3RyaW5nUGllY2UoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0QmFyU3RyaW5nUGllY2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTY6CiAgICAgICAgICBpZiAoIWdldEJhckJ5dGVzKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEJhckJ5dGVzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE3OgogICAgICAgICAgaWYgKCFnZXRCYXJFbnVtKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEJhckVudW0oKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjA6CiAgICAgICAgICBpZiAoIWdldEJhclN0cmluZ1dpdGhFbXB0eURlZmF1bHQoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0QmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAyMToKICAgICAgICAgIGlmICghZ2V0QmFyQ29yZFdpdGhFbXB0eURlZmF1bHQoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0QmFyQ29yZFdpdGhFbXB0eURlZmF1bHQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjI6CiAgICAgICAgICBpZiAoIWdldEJhclN0cmluZ1BpZWNlV2l0aEVtcHR5RGVmYXVsdCgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRCYXJTdHJpbmdQaWVjZVdpdGhFbXB0eURlZmF1bHQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjM6CiAgICAgICAgICBpZiAoIWdldEJhckJ5dGVzV2l0aEVtcHR5RGVmYXVsdCgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRCYXJCeXRlc1dpdGhFbXB0eURlZmF1bHQoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0JhekludCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkFaX0lOVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QmF6SW50KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0JhelN0cmluZygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkFaX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QmF6U3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBzd2l0Y2ggKGZvb0Nhc2VfKSB7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX0lOVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGb29JbnQoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZPT19TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Rm9vU3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMzoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZPT19DT1JEX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZvb0NvcmQoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA0OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX1NUUklOR19QSUVDRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGb29TdHJpbmdQaWVjZSgpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDU6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGT09fQllURVNfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Rm9vQnl0ZXMoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA2OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Rm9vRW51bSgpLmdldE51bWJlcigpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA3OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Rm9vTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDg6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGT09HUk9VUF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGb29Hcm91cCgpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDExOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX0xBWllfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGb29MYXp5TWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDMwOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX0JZVEVTX0NPUkRfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Rm9vQnl0ZXNDb3JkKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIHN3aXRjaCAoYmFyQ2FzZV8pIHsKICAgICAgICBjYXNlIDEyOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkFSX0lOVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCYXJJbnQoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTM6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCQVJfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEJhclN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE0OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkFSX0NPUkRfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QmFyQ29yZCgpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE1OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkFSX1NUUklOR19QSUVDRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCYXJTdHJpbmdQaWVjZSgpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE2OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkFSX0JZVEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEJhckJ5dGVzKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTc6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCQVJfRU5VTV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCYXJFbnVtKCkuZ2V0TnVtYmVyKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDIwOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkFSX1NUUklOR19XSVRIX0VNUFRZX0RFRkFVTFRfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdCgpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDIxOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQkFSX0NPUkRfV0lUSF9FTVBUWV9ERUZBVUxUX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEJhckNvcmRXaXRoRW1wdHlEZWZhdWx0KCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjI6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBCQVJfU1RSSU5HX1BJRUNFX1dJVEhfRU1QVFlfREVGQVVMVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCYXJTdHJpbmdQaWVjZVdpdGhFbXB0eURlZmF1bHQoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAyMzoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEJBUl9CWVRFU19XSVRIX0VNUFRZX0RFRkFVTFRfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QmFyQnl0ZXNXaXRoRW1wdHlEZWZhdWx0KCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMiBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMiBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mMl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2YyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoZm9vTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZvb01lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBpZiAoZm9vR3JvdXBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmb29Hcm91cEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGlmIChmb29MYXp5TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZvb0xhenlNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYmF6SW50XyA9IDA7CiAgICAgICAgYmF6U3RyaW5nXyA9ICJCQVoiOwogICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICBiYXJDYXNlXyA9IDA7CiAgICAgICAgYmFyXyA9IG51bGw7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZjJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMiBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBidWlsZFBhcnRpYWxPbmVvZnMocmVzdWx0KTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmJhekludF8gPSBiYXpJbnRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmJhelN0cmluZ18gPSBiYXpTdHJpbmdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsT25lb2ZzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMiByZXN1bHQpIHsKICAgICAgICByZXN1bHQuZm9vQ2FzZV8gPSBmb29DYXNlXzsKICAgICAgICByZXN1bHQuZm9vXyA9IHRoaXMuZm9vXzsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gNyAmJgogICAgICAgICAgICBmb29NZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVzdWx0LmZvb18gPSBmb29NZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDggJiYKICAgICAgICAgICAgZm9vR3JvdXBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXN1bHQuZm9vXyA9IGZvb0dyb3VwQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDExICYmCiAgICAgICAgICAgIGZvb0xhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVzdWx0LmZvb18gPSBmb29MYXp5TWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iYXJDYXNlXyA9IGJhckNhc2VfOwogICAgICAgIHJlc3VsdC5iYXJfID0gdGhpcy5iYXJfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0JhekludCgpKSB7CiAgICAgICAgICBzZXRCYXpJbnQob3RoZXIuZ2V0QmF6SW50KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzQmF6U3RyaW5nKCkpIHsKICAgICAgICAgIGJhelN0cmluZ18gPSBvdGhlci5iYXpTdHJpbmdfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHN3aXRjaCAob3RoZXIuZ2V0Rm9vQ2FzZSgpKSB7CiAgICAgICAgICBjYXNlIEZPT19JTlQ6IHsKICAgICAgICAgICAgc2V0Rm9vSW50KG90aGVyLmdldEZvb0ludCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZPT19TVFJJTkc6IHsKICAgICAgICAgICAgZm9vQ2FzZV8gPSAyOwogICAgICAgICAgICBmb29fID0gb3RoZXIuZm9vXzsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGT09fQ09SRDogewogICAgICAgICAgICBmb29DYXNlXyA9IDM7CiAgICAgICAgICAgIGZvb18gPSBvdGhlci5mb29fOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZPT19TVFJJTkdfUElFQ0U6IHsKICAgICAgICAgICAgZm9vQ2FzZV8gPSA0OwogICAgICAgICAgICBmb29fID0gb3RoZXIuZm9vXzsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGT09fQllURVM6IHsKICAgICAgICAgICAgc2V0Rm9vQnl0ZXMob3RoZXIuZ2V0Rm9vQnl0ZXMoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGT09fRU5VTTogewogICAgICAgICAgICBzZXRGb29FbnVtKG90aGVyLmdldEZvb0VudW0oKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGT09fTUVTU0FHRTogewogICAgICAgICAgICBtZXJnZUZvb01lc3NhZ2Uob3RoZXIuZ2V0Rm9vTWVzc2FnZSgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZPT0dST1VQOiB7CiAgICAgICAgICAgIG1lcmdlRm9vR3JvdXAob3RoZXIuZ2V0Rm9vR3JvdXAoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGT09fTEFaWV9NRVNTQUdFOiB7CiAgICAgICAgICAgIG1lcmdlRm9vTGF6eU1lc3NhZ2Uob3RoZXIuZ2V0Rm9vTGF6eU1lc3NhZ2UoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBGT09fQllURVNfQ09SRDogewogICAgICAgICAgICBzZXRGb29CeXRlc0NvcmQob3RoZXIuZ2V0Rm9vQnl0ZXNDb3JkKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRk9PX05PVF9TRVQ6IHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHN3aXRjaCAob3RoZXIuZ2V0QmFyQ2FzZSgpKSB7CiAgICAgICAgICBjYXNlIEJBUl9JTlQ6IHsKICAgICAgICAgICAgc2V0QmFySW50KG90aGVyLmdldEJhckludCgpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEJBUl9TVFJJTkc6IHsKICAgICAgICAgICAgYmFyQ2FzZV8gPSAxMzsKICAgICAgICAgICAgYmFyXyA9IG90aGVyLmJhcl87CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgQkFSX0NPUkQ6IHsKICAgICAgICAgICAgYmFyQ2FzZV8gPSAxNDsKICAgICAgICAgICAgYmFyXyA9IG90aGVyLmJhcl87CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgQkFSX1NUUklOR19QSUVDRTogewogICAgICAgICAgICBiYXJDYXNlXyA9IDE1OwogICAgICAgICAgICBiYXJfID0gb3RoZXIuYmFyXzsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBCQVJfQllURVM6IHsKICAgICAgICAgICAgc2V0QmFyQnl0ZXMob3RoZXIuZ2V0QmFyQnl0ZXMoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBCQVJfRU5VTTogewogICAgICAgICAgICBzZXRCYXJFbnVtKG90aGVyLmdldEJhckVudW0oKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBCQVJfU1RSSU5HX1dJVEhfRU1QVFlfREVGQVVMVDogewogICAgICAgICAgICBiYXJDYXNlXyA9IDIwOwogICAgICAgICAgICBiYXJfID0gb3RoZXIuYmFyXzsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBCQVJfQ09SRF9XSVRIX0VNUFRZX0RFRkFVTFQ6IHsKICAgICAgICAgICAgYmFyQ2FzZV8gPSAyMTsKICAgICAgICAgICAgYmFyXyA9IG90aGVyLmJhcl87CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgQkFSX1NUUklOR19QSUVDRV9XSVRIX0VNUFRZX0RFRkFVTFQ6IHsKICAgICAgICAgICAgYmFyQ2FzZV8gPSAyMjsKICAgICAgICAgICAgYmFyXyA9IG90aGVyLmJhcl87CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgQkFSX0JZVEVTX1dJVEhfRU1QVFlfREVGQVVMVDogewogICAgICAgICAgICBzZXRCYXJCeXRlc1dpdGhFbXB0eURlZmF1bHQob3RoZXIuZ2V0QmFyQnl0ZXNXaXRoRW1wdHlEZWZhdWx0KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgQkFSX05PVF9TRVQ6IHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgZm9vXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZm9vQ2FzZV8gPSAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGZvb0Nhc2VfID0gMjsKICAgICAgICAgICAgICAgIGZvb18gPSBiczsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZm9vQ2FzZV8gPSAzOwogICAgICAgICAgICAgICAgZm9vXyA9IGJzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBmb29DYXNlXyA9IDQ7CiAgICAgICAgICAgICAgICBmb29fID0gYnM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgICBjYXNlIDQyOiB7CiAgICAgICAgICAgICAgICBmb29fID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBmb29DYXNlXyA9IDU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBjYXNlIDQ4OiB7CiAgICAgICAgICAgICAgICBpbnQgcmF3VmFsdWUgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZEVudW0gdmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRFbnVtLmZvck51bWJlcihyYXdWYWx1ZSk7CiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg2LCByYXdWYWx1ZSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBmb29DYXNlXyA9IDY7CiAgICAgICAgICAgICAgICAgIGZvb18gPSByYXdWYWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OAogICAgICAgICAgICAgIGNhc2UgNTg6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldEZvb01lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgZm9vQ2FzZV8gPSA3OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU4CiAgICAgICAgICAgICAgY2FzZSA2NzogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZEdyb3VwKDgsCiAgICAgICAgICAgICAgICAgICAgZ2V0Rm9vR3JvdXBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgZm9vQ2FzZV8gPSA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY3CiAgICAgICAgICAgICAgY2FzZSA5MDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0Rm9vTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgZm9vQ2FzZV8gPSAxMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICAgIGNhc2UgOTY6IHsKICAgICAgICAgICAgICAgIGJhcl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJhckNhc2VfID0gMTI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTYKICAgICAgICAgICAgICBjYXNlIDEwNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiYXJDYXNlXyA9IDEzOwogICAgICAgICAgICAgICAgYmFyXyA9IGJzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNgogICAgICAgICAgICAgIGNhc2UgMTE0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJhckNhc2VfID0gMTQ7CiAgICAgICAgICAgICAgICBiYXJfID0gYnM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTE0CiAgICAgICAgICAgICAgY2FzZSAxMjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYmFyQ2FzZV8gPSAxNTsKICAgICAgICAgICAgICAgIGJhcl8gPSBiczsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMjIKICAgICAgICAgICAgICBjYXNlIDEzMDogewogICAgICAgICAgICAgICAgYmFyXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYmFyQ2FzZV8gPSAxNjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzAKICAgICAgICAgICAgICBjYXNlIDEzNjogewogICAgICAgICAgICAgICAgaW50IHJhd1ZhbHVlID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIHZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkRW51bS5mb3JOdW1iZXIocmF3VmFsdWUpOwogICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMTcsIHJhd1ZhbHVlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGJhckNhc2VfID0gMTc7CiAgICAgICAgICAgICAgICAgIGJhcl8gPSByYXdWYWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzYKICAgICAgICAgICAgICBjYXNlIDE0NDogewogICAgICAgICAgICAgICAgYmF6SW50XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0NAogICAgICAgICAgICAgIGNhc2UgMTU0OiB7CiAgICAgICAgICAgICAgICBiYXpTdHJpbmdfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU0CiAgICAgICAgICAgICAgY2FzZSAxNjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYmFyQ2FzZV8gPSAyMDsKICAgICAgICAgICAgICAgIGJhcl8gPSBiczsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjIKICAgICAgICAgICAgICBjYXNlIDE3MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiYXJDYXNlXyA9IDIxOwogICAgICAgICAgICAgICAgYmFyXyA9IGJzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE3MAogICAgICAgICAgICAgIGNhc2UgMTc4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJhckNhc2VfID0gMjI7CiAgICAgICAgICAgICAgICBiYXJfID0gYnM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTc4CiAgICAgICAgICAgICAgY2FzZSAxODY6IHsKICAgICAgICAgICAgICAgIGJhcl8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJhckNhc2VfID0gMjM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTg2CiAgICAgICAgICAgICAgY2FzZSAyNDI6IHsKICAgICAgICAgICAgICAgIGZvb18gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGZvb0Nhc2VfID0gMzA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgZm9vQ2FzZV8gPSAwOwogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgZm9vXzsKICAgICAgcHVibGljIEZvb0Nhc2UKICAgICAgICAgIGdldEZvb0Nhc2UoKSB7CiAgICAgICAgcmV0dXJuIEZvb0Nhc2UuZm9yTnVtYmVyKAogICAgICAgICAgICBmb29DYXNlXyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vKCkgewogICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYmFyQ2FzZV8gPSAwOwogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgYmFyXzsKICAgICAgcHVibGljIEJhckNhc2UKICAgICAgICAgIGdldEJhckNhc2UoKSB7CiAgICAgICAgcmV0dXJuIEJhckNhc2UuZm9yTnVtYmVyKAogICAgICAgICAgICBiYXJDYXNlXyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQmFyKCkgewogICAgICAgIGJhckNhc2VfID0gMDsKICAgICAgICBiYXJfID0gbnVsbDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBmb29faW50ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vSW50IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb0ludCgpIHsKICAgICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgZm9vX2ludCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmb29JbnQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldEZvb0ludCgpIHsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMSkgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuSW50ZWdlcikgZm9vXzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb29JbnQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29JbnQoaW50IHZhbHVlKSB7CgogICAgICAgIGZvb0Nhc2VfID0gMTsKICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb29JbnQoKSB7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDEpIHsKICAgICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29TdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29TdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmb29fc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZvb1N0cmluZy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Rm9vU3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICAgIHJlZiA9IGZvb187CiAgICAgICAgfQogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgICBmb29fID0gczsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZvb1N0cmluZy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0Rm9vU3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMikgewogICAgICAgICAgcmVmID0gZm9vXzsKICAgICAgICB9CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSAyKSB7CiAgICAgICAgICAgIGZvb18gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZvb1N0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvb1N0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGZvb0Nhc2VfID0gMjsKICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmb29fc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vU3RyaW5nKCkgewogICAgICAgIGlmIChmb29DYXNlXyA9PSAyKSB7CiAgICAgICAgICBmb29DYXNlXyA9IDA7CiAgICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgZm9vU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vU3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGZvb0Nhc2VfID0gMjsKICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX2NvcmQgPSAzIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29Db3JkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vQ29yZCgpIHsKICAgICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gMzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZvb19jb3JkID0gMyBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZvb0NvcmQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZvb0NvcmQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMykgewogICAgICAgICAgcmVmID0gZm9vXzsKICAgICAgICB9CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMykgewogICAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICAgIGZvb18gPSBzOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX2NvcmQgPSAzIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGZvb0NvcmQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldEZvb0NvcmRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgICByZWYgPSBmb29fOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDMpIHsKICAgICAgICAgICAgZm9vXyA9IGI7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmb29fY29yZCA9IDMgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZvb0NvcmQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29Db3JkKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZm9vQ2FzZV8gPSAzOwogICAgICAgIGZvb18gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZvb19jb3JkID0gMyBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vQ29yZCgpIHsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMykgewogICAgICAgICAgZm9vQ2FzZV8gPSAwOwogICAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmb29fY29yZCA9IDMgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBmb29Db3JkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vQ29yZEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBmb29DYXNlXyA9IDM7CiAgICAgICAgZm9vXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmdfcGllY2UgPSA0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb1N0cmluZ1BpZWNlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vU3RyaW5nUGllY2UoKSB7CiAgICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmb29fc3RyaW5nX3BpZWNlID0gNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZm9vU3RyaW5nUGllY2UuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZvb1N0cmluZ1BpZWNlKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDQpIHsKICAgICAgICAgIHJlZiA9IGZvb187CiAgICAgICAgfQogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDQpIHsKICAgICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgICBmb29fID0gczsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmdfcGllY2UgPSA0IFtjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZm9vU3RyaW5nUGllY2UuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldEZvb1N0cmluZ1BpZWNlQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gNCkgewogICAgICAgICAgcmVmID0gZm9vXzsKICAgICAgICB9CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSA0KSB7CiAgICAgICAgICAgIGZvb18gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZ19waWVjZSA9IDQgW2N0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZm9vU3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29TdHJpbmdQaWVjZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGZvb0Nhc2VfID0gNDsKICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmb29fc3RyaW5nX3BpZWNlID0gNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb29TdHJpbmdQaWVjZSgpIHsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gNCkgewogICAgICAgICAgZm9vQ2FzZV8gPSAwOwogICAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmb29fc3RyaW5nX3BpZWNlID0gNCBbY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgZm9vU3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29TdHJpbmdQaWVjZUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBmb29DYXNlXyA9IDQ7CiAgICAgICAgZm9vXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgZm9vX2J5dGVzID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vQnl0ZXMoKSB7CiAgICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIGZvb19ieXRlcyA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmb29CeXRlcy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0Rm9vQnl0ZXMoKSB7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDUpIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSBmb29fOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBmb29fYnl0ZXMgPSA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb29CeXRlcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvb0J5dGVzKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZm9vQ2FzZV8gPSA1OwogICAgICAgIGZvb18gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgZm9vX2J5dGVzID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vQnl0ZXMoKSB7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDUpIHsKICAgICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bSBmb29fZW51bSA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb0VudW0gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29FbnVtKCkgewogICAgICAgIHJldHVybiBmb29DYXNlXyA9PSA2OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIGZvb19lbnVtID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZvb0VudW0uCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkRW51bSBnZXRGb29FbnVtKCkgewogICAgICAgIGlmIChmb29DYXNlXyA9PSA2KSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkRW51bS5mb3JOdW1iZXIoCiAgICAgICAgICAgICAgKGphdmEubGFuZy5JbnRlZ2VyKSBmb29fKTsKICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRFbnVtLkZPTyA6IHJlc3VsdDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRFbnVtLkZPTzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bSBmb29fZW51bSA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZvb0VudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29FbnVtKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDY7CiAgICAgICAgZm9vXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIGZvb19lbnVtID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vRW51bSgpIHsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gNikgewogICAgICAgICAgZm9vQ2FzZV8gPSAwOwogICAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gZm9vTWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb01lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29NZXNzYWdlKCkgewogICAgICAgIHJldHVybiBmb29DYXNlXyA9PSA3OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIGZvb19tZXNzYWdlID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZvb01lc3NhZ2UuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBnZXRGb29NZXNzYWdlKCkgewogICAgICAgIGlmIChmb29NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDcpIHsKICAgICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSkgZm9vXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDcpIHsKICAgICAgICAgICAgcmV0dXJuIGZvb01lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIGZvb19tZXNzYWdlID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29NZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZvb01lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZvb18gPSB2YWx1ZTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb29NZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGZvb0Nhc2VfID0gNzsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZvb01lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmb29fID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDc7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgZm9vX21lc3NhZ2UgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRm9vTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChmb29NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDcgJiYKICAgICAgICAgICAgICBmb29fICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGZvb18gPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSkgZm9vXykKICAgICAgICAgICAgICAgIC5tZXJnZUZyb20odmFsdWUpLmJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9vXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSA3KSB7CiAgICAgICAgICAgIGZvb01lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDc7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgZm9vX21lc3NhZ2UgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vTWVzc2FnZSgpIHsKICAgICAgICBpZiAoZm9vTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSA3KSB7CiAgICAgICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gNykgewogICAgICAgICAgICBmb29DYXNlXyA9IDA7CiAgICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIGZvb19tZXNzYWdlID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRGb29NZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0Rm9vTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0Rm9vTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoKGZvb0Nhc2VfID09IDcpICYmIChmb29NZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICAgIHJldHVybiBmb29NZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gNykgewogICAgICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlKSBmb29fOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZvb01lc3NhZ2VGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGZvb01lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIShmb29DYXNlXyA9PSA3KSkgewogICAgICAgICAgICBmb29fID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBmb29NZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UpIGZvb18sCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZm9vQ2FzZV8gPSA3OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmb29NZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cE9yQnVpbGRlcj4gZm9vR3JvdXBCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZvb0dyb3VwID0gOCB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb2dyb3VwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vR3JvdXAoKSB7CiAgICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZvb0dyb3VwID0gOCB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmb29ncm91cC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCBnZXRGb29Hcm91cCgpIHsKICAgICAgICBpZiAoZm9vR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gOCkgewogICAgICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCkgZm9vXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSA4KSB7CiAgICAgICAgICAgIHJldHVybiBmb29Hcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ncm91cCBGb29Hcm91cCA9IDggeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvb0dyb3VwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCB2YWx1ZSkgewogICAgICAgIGlmIChmb29Hcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZm9vXyA9IHZhbHVlOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvb0dyb3VwQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGZvb0Nhc2VfID0gODsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Z3JvdXAgRm9vR3JvdXAgPSA4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29Hcm91cCgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmb29Hcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZvb18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb29Hcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDg7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZvb0dyb3VwID0gOCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGb29Hcm91cChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAgdmFsdWUpIHsKICAgICAgICBpZiAoZm9vR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gOCAmJgogICAgICAgICAgICAgIGZvb18gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGZvb18gPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAubmV3QnVpbGRlcigocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwKSBmb29fKQogICAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDgpIHsKICAgICAgICAgICAgZm9vR3JvdXBCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9vR3JvdXBCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9vQ2FzZV8gPSA4OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ncm91cCBGb29Hcm91cCA9IDggeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vR3JvdXAoKSB7CiAgICAgICAgaWYgKGZvb0dyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDgpIHsKICAgICAgICAgICAgZm9vQ2FzZV8gPSAwOwogICAgICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSA4KSB7CiAgICAgICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICBmb29Hcm91cEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ncm91cCBGb29Hcm91cCA9IDggeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAuQnVpbGRlciBnZXRGb29Hcm91cEJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZvb0dyb3VwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ncm91cCBGb29Hcm91cCA9IDggeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cE9yQnVpbGRlciBnZXRGb29Hcm91cE9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoKGZvb0Nhc2VfID09IDgpICYmIChmb29Hcm91cEJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgICByZXR1cm4gZm9vR3JvdXBCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSA4KSB7CiAgICAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwKSBmb29fOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmdyb3VwIEZvb0dyb3VwID0gOCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZvb0dyb3VwRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmb29Hcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghKGZvb0Nhc2VfID09IDgpKSB7CiAgICAgICAgICAgIGZvb18gPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBmb29Hcm91cEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuRm9vR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLkZvb0dyb3VwT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5Gb29Hcm91cCkgZm9vXywKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZvb0dyb3VwQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgZm9vX2xhenlfbWVzc2FnZSA9IDExIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb0xhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDExOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIGZvb19sYXp5X21lc3NhZ2UgPSAxMSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZm9vTGF6eU1lc3NhZ2UuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBnZXRGb29MYXp5TWVzc2FnZSgpIHsKICAgICAgICBpZiAoZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMTEpIHsKICAgICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSkgZm9vXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDExKSB7CiAgICAgICAgICAgIHJldHVybiBmb29MYXp5TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgZm9vX2xhenlfbWVzc2FnZSA9IDExIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vTGF6eU1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAoZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGZvb18gPSB2YWx1ZTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb29MYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDExOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIGZvb19sYXp5X21lc3NhZ2UgPSAxMSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvb0xhenlNZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmb29fID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgZm9vQ2FzZV8gPSAxMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBmb29fbGF6eV9tZXNzYWdlID0gMTEgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZvb0xhenlNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZvb0xhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDExICYmCiAgICAgICAgICAgICAgZm9vXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBmb29fID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UpIGZvb18pCiAgICAgICAgICAgICAgICAubWVyZ2VGcm9tKHZhbHVlKS5idWlsZFBhcnRpYWwoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvb18gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMTEpIHsKICAgICAgICAgICAgZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9vQ2FzZV8gPSAxMTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSBmb29fbGF6eV9tZXNzYWdlID0gMTEgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZvb0xhenlNZXNzYWdlKCkgewogICAgICAgIGlmIChmb29MYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSAxMSkgewogICAgICAgICAgICBmb29DYXNlXyA9IDA7CiAgICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDExKSB7CiAgICAgICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICBmb29MYXp5TWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIGZvb19sYXp5X21lc3NhZ2UgPSAxMSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldEZvb0xhenlNZXNzYWdlQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0Rm9vTGF6eU1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UgZm9vX2xhenlfbWVzc2FnZSA9IDExIFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0Rm9vTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKChmb29DYXNlXyA9PSAxMSkgJiYgKGZvb0xhenlNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkpIHsKICAgICAgICAgIHJldHVybiBmb29MYXp5TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDExKSB7CiAgICAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UpIGZvb187CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlIGZvb19sYXp5X21lc3NhZ2UgPSAxMSBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGb29MYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAoZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIShmb29DYXNlXyA9PSAxMSkpIHsKICAgICAgICAgICAgZm9vXyA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgICAgfQogICAgICAgICAgZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkTWVzc2FnZSkgZm9vXywKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDExOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmb29MYXp5TWVzc2FnZUJ1aWxkZXJfOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgZm9vX2J5dGVzX2NvcmQgPSAzMCBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vQnl0ZXNDb3JkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb0J5dGVzQ29yZCgpIHsKICAgICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gMzA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIGZvb19ieXRlc19jb3JkID0gMzAgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmb29CeXRlc0NvcmQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEZvb0J5dGVzQ29yZCgpIHsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMzApIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSBmb29fOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBmb29fYnl0ZXNfY29yZCA9IDMwIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb29CeXRlc0NvcmQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29CeXRlc0NvcmQoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBmb29DYXNlXyA9IDMwOwogICAgICAgIGZvb18gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgZm9vX2J5dGVzX2NvcmQgPSAzMCBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vQnl0ZXNDb3JkKCkgewogICAgICAgIGlmIChmb29DYXNlXyA9PSAzMCkgewogICAgICAgICAgZm9vQ2FzZV8gPSAwOwogICAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBiYXJfaW50ID0gMTIgW2RlZmF1bHQgPSA1XTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmFySW50IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0JhckludCgpIHsKICAgICAgICByZXR1cm4gYmFyQ2FzZV8gPT0gMTI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGJhcl9pbnQgPSAxMiBbZGVmYXVsdCA9IDVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYmFySW50LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRCYXJJbnQoKSB7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDEyKSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSBiYXJfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gNTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgYmFyX2ludCA9IDEyIFtkZWZhdWx0ID0gNV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJhckludCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJhckludChpbnQgdmFsdWUpIHsKCiAgICAgICAgYmFyQ2FzZV8gPSAxMjsKICAgICAgICBiYXJfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGJhcl9pbnQgPSAxMiBbZGVmYXVsdCA9IDVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJCYXJJbnQoKSB7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDEyKSB7CiAgICAgICAgICBiYXJDYXNlXyA9IDA7CiAgICAgICAgICBiYXJfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nID0gMTMgW2RlZmF1bHQgPSAiU1RSSU5HIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJhclN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0JhclN0cmluZygpIHsKICAgICAgICByZXR1cm4gYmFyQ2FzZV8gPT0gMTM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nID0gMTMgW2RlZmF1bHQgPSAiU1RSSU5HIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBiYXJTdHJpbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEJhclN0cmluZygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICJTVFJJTkciOwogICAgICAgIGlmIChiYXJDYXNlXyA9PSAxMykgewogICAgICAgICAgcmVmID0gYmFyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYmFyQ2FzZV8gPT0gMTMpIHsKICAgICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgICBiYXJfID0gczsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmcgPSAxMyBbZGVmYXVsdCA9ICJTVFJJTkciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBiYXJTdHJpbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldEJhclN0cmluZ0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIlNUUklORyI7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDEzKSB7CiAgICAgICAgICByZWYgPSBiYXJfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKGJhckNhc2VfID09IDEzKSB7CiAgICAgICAgICAgIGJhcl8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX3N0cmluZyA9IDEzIFtkZWZhdWx0ID0gIlNUUklORyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBiYXJTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRCYXJTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBiYXJDYXNlXyA9IDEzOwogICAgICAgIGJhcl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmcgPSAxMyBbZGVmYXVsdCA9ICJTVFJJTkciXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQmFyU3RyaW5nKCkgewogICAgICAgIGlmIChiYXJDYXNlXyA9PSAxMykgewogICAgICAgICAgYmFyQ2FzZV8gPSAwOwogICAgICAgICAgYmFyXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nID0gMTMgW2RlZmF1bHQgPSAiU1RSSU5HIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBiYXJTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRCYXJTdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgYmFyQ2FzZV8gPSAxMzsKICAgICAgICBiYXJfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX2NvcmQgPSAxNCBbZGVmYXVsdCA9ICJDT1JEIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmFyQ29yZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0JhckNvcmQoKSB7CiAgICAgICAgcmV0dXJuIGJhckNhc2VfID09IDE0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX2NvcmQgPSAxNCBbZGVmYXVsdCA9ICJDT1JEIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJhckNvcmQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEJhckNvcmQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiQ09SRCI7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDE0KSB7CiAgICAgICAgICByZWYgPSBiYXJfOwogICAgICAgIH0KICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChiYXJDYXNlXyA9PSAxNCkgewogICAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICAgIGJhcl8gPSBzOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX2NvcmQgPSAxNCBbZGVmYXVsdCA9ICJDT1JEIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBiYXJDb3JkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRCYXJDb3JkQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiQ09SRCI7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDE0KSB7CiAgICAgICAgICByZWYgPSBiYXJfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKGJhckNhc2VfID09IDE0KSB7CiAgICAgICAgICAgIGJhcl8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX2NvcmQgPSAxNCBbZGVmYXVsdCA9ICJDT1JEIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYmFyQ29yZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJhckNvcmQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBiYXJDYXNlXyA9IDE0OwogICAgICAgIGJhcl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGJhcl9jb3JkID0gMTQgW2RlZmF1bHQgPSAiQ09SRCIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJhckNvcmQoKSB7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDE0KSB7CiAgICAgICAgICBiYXJDYXNlXyA9IDA7CiAgICAgICAgICBiYXJfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGJhcl9jb3JkID0gMTQgW2RlZmF1bHQgPSAiQ09SRCIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBiYXJDb3JkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmFyQ29yZEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBiYXJDYXNlXyA9IDE0OwogICAgICAgIGJhcl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3BpZWNlID0gMTUgW2RlZmF1bHQgPSAiU1BJRUNFIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJTdHJpbmdQaWVjZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0JhclN0cmluZ1BpZWNlKCkgewogICAgICAgIHJldHVybiBiYXJDYXNlXyA9PSAxNTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmdfcGllY2UgPSAxNSBbZGVmYXVsdCA9ICJTUElFQ0UiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBiYXJTdHJpbmdQaWVjZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0QmFyU3RyaW5nUGllY2UoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiU1BJRUNFIjsKICAgICAgICBpZiAoYmFyQ2FzZV8gPT0gMTUpIHsKICAgICAgICAgIHJlZiA9IGJhcl87CiAgICAgICAgfQogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJhckNhc2VfID09IDE1KSB7CiAgICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgICAgYmFyXyA9IHM7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3BpZWNlID0gMTUgW2RlZmF1bHQgPSAiU1BJRUNFIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGJhclN0cmluZ1BpZWNlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRCYXJTdHJpbmdQaWVjZUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIlNQSUVDRSI7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDE1KSB7CiAgICAgICAgICByZWYgPSBiYXJfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKGJhckNhc2VfID09IDE1KSB7CiAgICAgICAgICAgIGJhcl8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX3N0cmluZ19waWVjZSA9IDE1IFtkZWZhdWx0ID0gIlNQSUVDRSIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYmFyU3RyaW5nUGllY2UgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRCYXJTdHJpbmdQaWVjZSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGJhckNhc2VfID0gMTU7CiAgICAgICAgYmFyXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX3N0cmluZ19waWVjZSA9IDE1IFtkZWZhdWx0ID0gIlNQSUVDRSIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQmFyU3RyaW5nUGllY2UoKSB7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDE1KSB7CiAgICAgICAgICBiYXJDYXNlXyA9IDA7CiAgICAgICAgICBiYXJfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmdfcGllY2UgPSAxNSBbZGVmYXVsdCA9ICJTUElFQ0UiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBiYXJTdHJpbmdQaWVjZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJhclN0cmluZ1BpZWNlQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGJhckNhc2VfID0gMTU7CiAgICAgICAgYmFyXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgYmFyX2J5dGVzID0gMTYgW2RlZmF1bHQgPSAiQllURVMiXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmFyQnl0ZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzQmFyQnl0ZXMoKSB7CiAgICAgICAgcmV0dXJuIGJhckNhc2VfID09IDE2OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBiYXJfYnl0ZXMgPSAxNiBbZGVmYXVsdCA9ICJCWVRFUyJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYmFyQnl0ZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldEJhckJ5dGVzKCkgewogICAgICAgIGlmIChiYXJDYXNlXyA9PSAxNikgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIGJhcl87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmJ5dGVzRGVmYXVsdFZhbHVlKCJCWVRFUyIpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBiYXJfYnl0ZXMgPSAxNiBbZGVmYXVsdCA9ICJCWVRFUyJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBiYXJCeXRlcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJhckJ5dGVzKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgYmFyQ2FzZV8gPSAxNjsKICAgICAgICBiYXJfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIGJhcl9ieXRlcyA9IDE2IFtkZWZhdWx0ID0gIkJZVEVTIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJhckJ5dGVzKCkgewogICAgICAgIGlmIChiYXJDYXNlXyA9PSAxNikgewogICAgICAgICAgYmFyQ2FzZV8gPSAwOwogICAgICAgICAgYmFyXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIGJhcl9lbnVtID0gMTcgW2RlZmF1bHQgPSBCQVJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJFbnVtIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQmFyRW51bSgpIHsKICAgICAgICByZXR1cm4gYmFyQ2FzZV8gPT0gMTc7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZEVudW0gYmFyX2VudW0gPSAxNyBbZGVmYXVsdCA9IEJBUl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBiYXJFbnVtLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZEVudW0gZ2V0QmFyRW51bSgpIHsKICAgICAgICBpZiAoYmFyQ2FzZV8gPT0gMTcpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMi5OZXN0ZWRFbnVtLmZvck51bWJlcigKICAgICAgICAgICAgICAoamF2YS5sYW5nLkludGVnZXIpIGJhcl8pOwogICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZEVudW0uQkFSIDogcmVzdWx0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyLk5lc3RlZEVudW0uQkFSOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtIGJhcl9lbnVtID0gMTcgW2RlZmF1bHQgPSBCQVJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBiYXJFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmFyRW51bShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RPbmVvZjIuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYmFyQ2FzZV8gPSAxNzsKICAgICAgICBiYXJfID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZEVudW0gYmFyX2VudW0gPSAxNyBbZGVmYXVsdCA9IEJBUl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJhckVudW0oKSB7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDE3KSB7CiAgICAgICAgICBiYXJDYXNlXyA9IDA7CiAgICAgICAgICBiYXJfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIwIFtkZWZhdWx0ID0gIiJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJTdHJpbmdXaXRoRW1wdHlEZWZhdWx0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdCgpIHsKICAgICAgICByZXR1cm4gYmFyQ2FzZV8gPT0gMjA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIwIFtkZWZhdWx0ID0gIiJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0QmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICAgIGlmIChiYXJDYXNlXyA9PSAyMCkgewogICAgICAgICAgcmVmID0gYmFyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYmFyQ2FzZV8gPT0gMjApIHsKICAgICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgICBiYXJfID0gczsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmdfd2l0aF9lbXB0eV9kZWZhdWx0ID0gMjAgW2RlZmF1bHQgPSAiIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0QmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDIwKSB7CiAgICAgICAgICByZWYgPSBiYXJfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKGJhckNhc2VfID09IDIwKSB7CiAgICAgICAgICAgIGJhcl8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX3N0cmluZ193aXRoX2VtcHR5X2RlZmF1bHQgPSAyMCBbZGVmYXVsdCA9ICIiXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJhclN0cmluZ1dpdGhFbXB0eURlZmF1bHQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBiYXJDYXNlXyA9IDIwOwogICAgICAgIGJhcl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmdfd2l0aF9lbXB0eV9kZWZhdWx0ID0gMjAgW2RlZmF1bHQgPSAiIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJhclN0cmluZ1dpdGhFbXB0eURlZmF1bHQoKSB7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDIwKSB7CiAgICAgICAgICBiYXJDYXNlXyA9IDA7CiAgICAgICAgICBiYXJfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmdfd2l0aF9lbXB0eV9kZWZhdWx0ID0gMjAgW2RlZmF1bHQgPSAiIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBiYXJTdHJpbmdXaXRoRW1wdHlEZWZhdWx0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBiYXJDYXNlXyA9IDIwOwogICAgICAgIGJhcl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBiYXJfY29yZF93aXRoX2VtcHR5X2RlZmF1bHQgPSAyMSBbZGVmYXVsdCA9ICIiLCBjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJDb3JkV2l0aEVtcHR5RGVmYXVsdCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0JhckNvcmRXaXRoRW1wdHlEZWZhdWx0KCkgewogICAgICAgIHJldHVybiBiYXJDYXNlXyA9PSAyMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGJhcl9jb3JkX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIxIFtkZWZhdWx0ID0gIiIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBiYXJDb3JkV2l0aEVtcHR5RGVmYXVsdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0QmFyQ29yZFdpdGhFbXB0eURlZmF1bHQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAoYmFyQ2FzZV8gPT0gMjEpIHsKICAgICAgICAgIHJlZiA9IGJhcl87CiAgICAgICAgfQogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJhckNhc2VfID09IDIxKSB7CiAgICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgICAgYmFyXyA9IHM7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBiYXJfY29yZF93aXRoX2VtcHR5X2RlZmF1bHQgPSAyMSBbZGVmYXVsdCA9ICIiLCBjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGJhckNvcmRXaXRoRW1wdHlEZWZhdWx0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRCYXJDb3JkV2l0aEVtcHR5RGVmYXVsdEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDIxKSB7CiAgICAgICAgICByZWYgPSBiYXJfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKGJhckNhc2VfID09IDIxKSB7CiAgICAgICAgICAgIGJhcl8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX2NvcmRfd2l0aF9lbXB0eV9kZWZhdWx0ID0gMjEgW2RlZmF1bHQgPSAiIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYmFyQ29yZFdpdGhFbXB0eURlZmF1bHQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRCYXJDb3JkV2l0aEVtcHR5RGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGJhckNhc2VfID0gMjE7CiAgICAgICAgYmFyXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX2NvcmRfd2l0aF9lbXB0eV9kZWZhdWx0ID0gMjEgW2RlZmF1bHQgPSAiIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQmFyQ29yZFdpdGhFbXB0eURlZmF1bHQoKSB7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDIxKSB7CiAgICAgICAgICBiYXJDYXNlXyA9IDA7CiAgICAgICAgICBiYXJfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGJhcl9jb3JkX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIxIFtkZWZhdWx0ID0gIiIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBiYXJDb3JkV2l0aEVtcHR5RGVmYXVsdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJhckNvcmRXaXRoRW1wdHlEZWZhdWx0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGJhckNhc2VfID0gMjE7CiAgICAgICAgYmFyXyA9IHZhbHVlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmdfcGllY2Vfd2l0aF9lbXB0eV9kZWZhdWx0ID0gMjIgW2RlZmF1bHQgPSAiIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXJTdHJpbmdQaWVjZVdpdGhFbXB0eURlZmF1bHQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNCYXJTdHJpbmdQaWVjZVdpdGhFbXB0eURlZmF1bHQoKSB7CiAgICAgICAgcmV0dXJuIGJhckNhc2VfID09IDIyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgYmFyX3N0cmluZ19waWVjZV93aXRoX2VtcHR5X2RlZmF1bHQgPSAyMiBbZGVmYXVsdCA9ICIiLCBjdHlwZSA9IFNUUklOR19QSUVDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBiYXJTdHJpbmdQaWVjZVdpdGhFbXB0eURlZmF1bHQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEJhclN0cmluZ1BpZWNlV2l0aEVtcHR5RGVmYXVsdCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICAgIGlmIChiYXJDYXNlXyA9PSAyMikgewogICAgICAgICAgcmVmID0gYmFyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYmFyQ2FzZV8gPT0gMjIpIHsKICAgICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgICBiYXJfID0gczsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGJhcl9zdHJpbmdfcGllY2Vfd2l0aF9lbXB0eV9kZWZhdWx0ID0gMjIgW2RlZmF1bHQgPSAiIiwgY3R5cGUgPSBTVFJJTkdfUElFQ0VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGJhclN0cmluZ1BpZWNlV2l0aEVtcHR5RGVmYXVsdC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0QmFyU3RyaW5nUGllY2VXaXRoRW1wdHlEZWZhdWx0Qnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAoYmFyQ2FzZV8gPT0gMjIpIHsKICAgICAgICAgIHJlZiA9IGJhcl87CiAgICAgICAgfQogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBpZiAoYmFyQ2FzZV8gPT0gMjIpIHsKICAgICAgICAgICAgYmFyXyA9IGI7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3BpZWNlX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIyIFtkZWZhdWx0ID0gIiIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYmFyU3RyaW5nUGllY2VXaXRoRW1wdHlEZWZhdWx0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmFyU3RyaW5nUGllY2VXaXRoRW1wdHlEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgYmFyQ2FzZV8gPSAyMjsKICAgICAgICBiYXJfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3BpZWNlX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIyIFtkZWZhdWx0ID0gIiIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQmFyU3RyaW5nUGllY2VXaXRoRW1wdHlEZWZhdWx0KCkgewogICAgICAgIGlmIChiYXJDYXNlXyA9PSAyMikgewogICAgICAgICAgYmFyQ2FzZV8gPSAwOwogICAgICAgICAgYmFyXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBiYXJfc3RyaW5nX3BpZWNlX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIyIFtkZWZhdWx0ID0gIiIsIGN0eXBlID0gU1RSSU5HX1BJRUNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIGJhclN0cmluZ1BpZWNlV2l0aEVtcHR5RGVmYXVsdCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJhclN0cmluZ1BpZWNlV2l0aEVtcHR5RGVmYXVsdEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBiYXJDYXNlXyA9IDIyOwogICAgICAgIGJhcl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIGJhcl9ieXRlc193aXRoX2VtcHR5X2RlZmF1bHQgPSAyMyBbZGVmYXVsdCA9ICIiXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYmFyQnl0ZXNXaXRoRW1wdHlEZWZhdWx0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0JhckJ5dGVzV2l0aEVtcHR5RGVmYXVsdCgpIHsKICAgICAgICByZXR1cm4gYmFyQ2FzZV8gPT0gMjM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIGJhcl9ieXRlc193aXRoX2VtcHR5X2RlZmF1bHQgPSAyMyBbZGVmYXVsdCA9ICIiXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJhckJ5dGVzV2l0aEVtcHR5RGVmYXVsdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0QmFyQnl0ZXNXaXRoRW1wdHlEZWZhdWx0KCkgewogICAgICAgIGlmIChiYXJDYXNlXyA9PSAyMykgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIGJhcl87CiAgICAgICAgfQogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmJ5dGVzRGVmYXVsdFZhbHVlKCIiKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgYmFyX2J5dGVzX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIzIFtkZWZhdWx0ID0gIiJdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBiYXJCeXRlc1dpdGhFbXB0eURlZmF1bHQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRCYXJCeXRlc1dpdGhFbXB0eURlZmF1bHQoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBiYXJDYXNlXyA9IDIzOwogICAgICAgIGJhcl8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgYmFyX2J5dGVzX3dpdGhfZW1wdHlfZGVmYXVsdCA9IDIzIFtkZWZhdWx0ID0gIiJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJCYXJCeXRlc1dpdGhFbXB0eURlZmF1bHQoKSB7CiAgICAgICAgaWYgKGJhckNhc2VfID09IDIzKSB7CiAgICAgICAgICBiYXJDYXNlXyA9IDA7CiAgICAgICAgICBiYXJfID0gbnVsbDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYmF6SW50XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYXpfaW50ID0gMTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJhekludCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0JhekludCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDEwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJhel9pbnQgPSAxODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJhekludC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRCYXpJbnQoKSB7CiAgICAgICAgcmV0dXJuIGJhekludF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGJhel9pbnQgPSAxODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYmF6SW50IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmF6SW50KGludCB2YWx1ZSkgewoKICAgICAgICBiYXpJbnRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBiYXpfaW50ID0gMTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJhekludCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDEwMDAwMCk7CiAgICAgICAgYmF6SW50XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBiYXpTdHJpbmdfID0gIkJBWiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYmF6X3N0cmluZyA9IDE5IFtkZWZhdWx0ID0gIkJBWiJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBiYXpTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzQmF6U3RyaW5nKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGJhel9zdHJpbmcgPSAxOSBbZGVmYXVsdCA9ICJCQVoiXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJhelN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEJhelN0cmluZygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGJhelN0cmluZ187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBiYXpTdHJpbmdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiYXpfc3RyaW5nID0gMTkgW2RlZmF1bHQgPSAiQkFaIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYmF6U3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0QmF6U3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBiYXpTdHJpbmdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBiYXpTdHJpbmdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGJhel9zdHJpbmcgPSAxOSBbZGVmYXVsdCA9ICJCQVoiXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYmF6U3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QmF6U3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgYmF6U3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGJhel9zdHJpbmcgPSAxOSBbZGVmYXVsdCA9ICJCQVoiXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQmF6U3RyaW5nKCkgewogICAgICAgIGJhelN0cmluZ18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRCYXpTdHJpbmcoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBiYXpfc3RyaW5nID0gMTkgW2RlZmF1bHQgPSAiQkFaIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBiYXpTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRCYXpTdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgYmF6U3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE9uZW9mMigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE9uZW9mMj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0T25lb2YyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE9uZW9mMiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RPbmVvZjI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE9uZW9mMj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0T25lb2YyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFJlcXVpcmVkT25lb2ZPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQzMiBmb29faW50ID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb0ludCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRm9vSW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb0ludC4KICAgICAqLwogICAgaW50IGdldEZvb0ludCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb29TdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb1N0cmluZy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRGb29TdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBmb29TdHJpbmcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEZvb1N0cmluZ0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29NZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb29NZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29NZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgZ2V0Rm9vTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0Rm9vTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgZm9vX2xhenlfbWVzc2FnZSA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb0xhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb29MYXp5TWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBmb29fbGF6eV9tZXNzYWdlID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb0xhenlNZXNzYWdlLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgZ2V0Rm9vTGF6eU1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgZm9vX2xhenlfbWVzc2FnZSA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRGb29MYXp5TWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuRm9vQ2FzZSBnZXRGb29DYXNlKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9uZW9mfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFJlcXVpcmVkT25lb2YgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YpCiAgICAgIFRlc3RSZXF1aXJlZE9uZW9mT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0UmVxdWlyZWRPbmVvZi5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0UmVxdWlyZWRPbmVvZihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RSZXF1aXJlZE9uZW9mKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RSZXF1aXJlZE9uZW9mKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkT25lb2ZfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRPbmVvZl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGRvdWJsZSByZXF1aXJlZF9kb3VibGUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXF1aXJlZERvdWJsZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc1JlcXVpcmVkRG91YmxlKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBkb3VibGUgcmVxdWlyZWRfZG91YmxlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRG91YmxlLgogICAgICAgKi8KICAgICAgZG91YmxlIGdldFJlcXVpcmVkRG91YmxlKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTmVzdGVkTWVzc2FnZSBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSkKICAgICAgICBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgTmVzdGVkTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIE5lc3RlZE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBOZXN0ZWRNZXNzYWdlKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE9uZW9mX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkT25lb2ZfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVRVUlSRURfRE9VQkxFX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIHByaXZhdGUgZG91YmxlIHJlcXVpcmVkRG91YmxlXyA9IDBEOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgZG91YmxlIHJlcXVpcmVkX2RvdWJsZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkRG91YmxlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUmVxdWlyZWREb3VibGUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCBkb3VibGUgcmVxdWlyZWRfZG91YmxlID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRG91YmxlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZG91YmxlIGdldFJlcXVpcmVkRG91YmxlKCkgewogICAgICAgIHJldHVybiByZXF1aXJlZERvdWJsZV87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIGlmICghaGFzUmVxdWlyZWREb3VibGUoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZURvdWJsZSgxLCByZXF1aXJlZERvdWJsZV8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZURvdWJsZVNpemUoMSwgcmVxdWlyZWREb3VibGVfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlKSBvYmo7CgogICAgICAgIGlmIChoYXNSZXF1aXJlZERvdWJsZSgpICE9IG90aGVyLmhhc1JlcXVpcmVkRG91YmxlKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzUmVxdWlyZWREb3VibGUoKSkgewogICAgICAgICAgaWYgKGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cyhnZXRSZXF1aXJlZERvdWJsZSgpKQogICAgICAgICAgICAgICE9IGphdmEubGFuZy5Eb3VibGUuZG91YmxlVG9Mb25nQml0cygKICAgICAgICAgICAgICAgICAgb3RoZXIuZ2V0UmVxdWlyZWREb3VibGUoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNSZXF1aXJlZERvdWJsZSgpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVFVSVJFRF9ET1VCTEVfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmRvdWJsZVRvTG9uZ0JpdHMoZ2V0UmVxdWlyZWREb3VibGUoKSkpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSkKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRPbmVvZl9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRPbmVvZl9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICByZXF1aXJlZERvdWJsZV8gPSAwRDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkT25lb2ZfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5yZXF1aXJlZERvdWJsZV8gPSByZXF1aXJlZERvdWJsZV87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzUmVxdWlyZWREb3VibGUoKSkgewogICAgICAgICAgICBzZXRSZXF1aXJlZERvdWJsZShvdGhlci5nZXRSZXF1aXJlZERvdWJsZSgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICBpZiAoIWhhc1JlcXVpcmVkRG91YmxlKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDk6IHsKICAgICAgICAgICAgICAgICAgcmVxdWlyZWREb3VibGVfID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDkKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgIHByaXZhdGUgZG91YmxlIHJlcXVpcmVkRG91YmxlXyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVxdWlyZWQgZG91YmxlIHJlcXVpcmVkX2RvdWJsZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWREb3VibGUgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNSZXF1aXJlZERvdWJsZSgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVxdWlyZWQgZG91YmxlIHJlcXVpcmVkX2RvdWJsZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkRG91YmxlLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZG91YmxlIGdldFJlcXVpcmVkRG91YmxlKCkgewogICAgICAgICAgcmV0dXJuIHJlcXVpcmVkRG91YmxlXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVxdWlyZWQgZG91YmxlIHJlcXVpcmVkX2RvdWJsZSA9IDE7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVxdWlyZWREb3VibGUgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXF1aXJlZERvdWJsZShkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgICByZXF1aXJlZERvdWJsZV8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcXVpcmVkIGRvdWJsZSByZXF1aXJlZF9kb3VibGUgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXF1aXJlZERvdWJsZSgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIHJlcXVpcmVkRG91YmxlXyA9IDBEOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkTWVzc2FnZT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBOZXN0ZWRNZXNzYWdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgZm9vQ2FzZV8gPSAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgZm9vXzsKICAgIHB1YmxpYyBlbnVtIEZvb0Nhc2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkludGVybmFsT25lT2ZFbnVtIHsKICAgICAgRk9PX0lOVCgxKSwKICAgICAgRk9PX1NUUklORygyKSwKICAgICAgRk9PX01FU1NBR0UoMyksCiAgICAgIEZPT19MQVpZX01FU1NBR0UoNCksCiAgICAgIEZPT19OT1RfU0VUKDApOwogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKICAgICAgcHJpdmF0ZSBGb29DYXNlKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1iZXIgb2YgdGhlIGVudW0gdG8gbG9vayBmb3IuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1iZXIuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgRm9vQ2FzZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIEZvb0Nhc2UgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIEZPT19JTlQ7CiAgICAgICAgICBjYXNlIDI6IHJldHVybiBGT09fU1RSSU5HOwogICAgICAgICAgY2FzZSAzOiByZXR1cm4gRk9PX01FU1NBR0U7CiAgICAgICAgICBjYXNlIDQ6IHJldHVybiBGT09fTEFaWV9NRVNTQUdFOwogICAgICAgICAgY2FzZSAwOiByZXR1cm4gRk9PX05PVF9TRVQ7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KICAgICAgcHVibGljIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIEZvb0Nhc2UKICAgIGdldEZvb0Nhc2UoKSB7CiAgICAgIHJldHVybiBGb29DYXNlLmZvck51bWJlcigKICAgICAgICAgIGZvb0Nhc2VfKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fSU5UX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAvKioKICAgICAqIDxjb2RlPmludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vSW50IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vSW50KCkgewogICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gMTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+aW50MzIgZm9vX2ludCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vSW50LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZvb0ludCgpIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDEpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSBmb29fOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19TVFJJTkdfRklFTERfTlVNQkVSID0gMjsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vU3RyaW5nKCkgewogICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gMjsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb1N0cmluZy4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Rm9vU3RyaW5nKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICBpZiAoZm9vQ2FzZV8gPT0gMikgewogICAgICAgIHJlZiA9IGZvb187CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpICYmIChmb29DYXNlXyA9PSAyKSkgewogICAgICAgICAgZm9vXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBmb29fc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZm9vU3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0Rm9vU3RyaW5nQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChmb29DYXNlXyA9PSAyKSB7CiAgICAgICAgcmVmID0gZm9vXzsKICAgICAgfQogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMikgewogICAgICAgICAgZm9vXyA9IGI7CiAgICAgICAgfQogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSAzOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29NZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDM7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29NZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGdldEZvb01lc3NhZ2UoKSB7CiAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlKSBmb29fOwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0Rm9vTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDMpIHsKICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UpIGZvb187CiAgICAgIH0KICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDQ7CiAgICAvKioKICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGZvb19sYXp5X21lc3NhZ2UgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29MYXp5TWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb0xhenlNZXNzYWdlKCkgewogICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gNDsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgZm9vX2xhenlfbWVzc2FnZSA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29MYXp5TWVzc2FnZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBnZXRGb29MYXp5TWVzc2FnZSgpIHsKICAgICAgaWYgKGZvb0Nhc2VfID09IDQpIHsKICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UpIGZvb187CiAgICAgIH0KICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgZm9vX2xhenlfbWVzc2FnZSA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2VPckJ1aWxkZXIgZ2V0Rm9vTGF6eU1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIGlmIChmb29DYXNlXyA9PSA0KSB7CiAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlKSBmb29fOwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKGhhc0Zvb01lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0Rm9vTWVzc2FnZSgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGhhc0Zvb0xhenlNZXNzYWdlKCkpIHsKICAgICAgICBpZiAoIWdldEZvb0xhenlNZXNzYWdlKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmIChmb29DYXNlXyA9PSAxKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoCiAgICAgICAgICAgIDEsIChpbnQpKChqYXZhLmxhbmcuSW50ZWdlcikgZm9vXykpOwogICAgICB9CiAgICAgIGlmIChmb29DYXNlXyA9PSAyKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyLCBmb29fKTsKICAgICAgfQogICAgICBpZiAoZm9vQ2FzZV8gPT0gMykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMywgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSkgZm9vXyk7CiAgICAgIH0KICAgICAgaWYgKGZvb0Nhc2VfID09IDQpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDQsIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UpIGZvb18pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoZm9vQ2FzZV8gPT0gMSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoCiAgICAgICAgICAgICAgMSwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSBmb29fKSk7CiAgICAgIH0KICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDIsIGZvb18pOwogICAgICB9CiAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UpIGZvb18pOwogICAgICB9CiAgICAgIGlmIChmb29DYXNlXyA9PSA0KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDQsIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UpIGZvb18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2Ygb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZikgb2JqOwoKICAgICAgaWYgKCFnZXRGb29DYXNlKCkuZXF1YWxzKG90aGVyLmdldEZvb0Nhc2UoKSkpIHJldHVybiBmYWxzZTsKICAgICAgc3dpdGNoIChmb29DYXNlXykgewogICAgICAgIGNhc2UgMToKICAgICAgICAgIGlmIChnZXRGb29JbnQoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEZvb0ludCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICBpZiAoIWdldEZvb1N0cmluZygpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGb29TdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMzoKICAgICAgICAgIGlmICghZ2V0Rm9vTWVzc2FnZSgpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGb29NZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICBpZiAoIWdldEZvb0xhenlNZXNzYWdlKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZvb0xhenlNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIHN3aXRjaCAoZm9vQ2FzZV8pIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGT09fSU5UX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZvb0ludCgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGb29TdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAzOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Rm9vTWVzc2FnZSgpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGT09fTEFaWV9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZvb0xhenlNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICBkZWZhdWx0OgogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2Z9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE9uZW9mX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE9uZW9mX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoZm9vTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGZvb01lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBpZiAoZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBmb29MYXp5TWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkT25lb2ZfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgYnVpbGRQYXJ0aWFsT25lb2ZzKHJlc3VsdCk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxPbmVvZnMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZiByZXN1bHQpIHsKICAgICAgICByZXN1bHQuZm9vQ2FzZV8gPSBmb29DYXNlXzsKICAgICAgICByZXN1bHQuZm9vXyA9IHRoaXMuZm9vXzsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMyAmJgogICAgICAgICAgICBmb29NZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmVzdWx0LmZvb18gPSBmb29NZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDQgJiYKICAgICAgICAgICAgZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXN1bHQuZm9vXyA9IGZvb0xhenlNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2Ygb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgc3dpdGNoIChvdGhlci5nZXRGb29DYXNlKCkpIHsKICAgICAgICAgIGNhc2UgRk9PX0lOVDogewogICAgICAgICAgICBzZXRGb29JbnQob3RoZXIuZ2V0Rm9vSW50KCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRk9PX1NUUklORzogewogICAgICAgICAgICBmb29DYXNlXyA9IDI7CiAgICAgICAgICAgIGZvb18gPSBvdGhlci5mb29fOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIEZPT19NRVNTQUdFOiB7CiAgICAgICAgICAgIG1lcmdlRm9vTWVzc2FnZShvdGhlci5nZXRGb29NZXNzYWdlKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRk9PX0xBWllfTUVTU0FHRTogewogICAgICAgICAgICBtZXJnZUZvb0xhenlNZXNzYWdlKG90aGVyLmdldEZvb0xhenlNZXNzYWdlKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgRk9PX05PVF9TRVQ6IHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoaGFzRm9vTWVzc2FnZSgpKSB7CiAgICAgICAgICBpZiAoIWdldEZvb01lc3NhZ2UoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoaGFzRm9vTGF6eU1lc3NhZ2UoKSkgewogICAgICAgICAgaWYgKCFnZXRGb29MYXp5TWVzc2FnZSgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBmb29fID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBmb29DYXNlXyA9IDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZm9vQ2FzZV8gPSAyOwogICAgICAgICAgICAgICAgZm9vXyA9IGJzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0Rm9vTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBmb29DYXNlXyA9IDM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDM0OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRGb29MYXp5TWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBmb29DYXNlXyA9IDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBmb29DYXNlXyA9IDA7CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBmb29fOwogICAgICBwdWJsaWMgRm9vQ2FzZQogICAgICAgICAgZ2V0Rm9vQ2FzZSgpIHsKICAgICAgICByZXR1cm4gRm9vQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICAgIGZvb0Nhc2VfKTsKICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb28oKSB7CiAgICAgICAgZm9vQ2FzZV8gPSAwOwogICAgICAgIGZvb18gPSBudWxsOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDMyIGZvb19pbnQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29JbnQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vSW50KCkgewogICAgICAgIHJldHVybiBmb29DYXNlXyA9PSAxOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQzMiBmb29faW50ID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZvb0ludC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0Rm9vSW50KCkgewogICAgICAgIGlmIChmb29DYXNlXyA9PSAxKSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5JbnRlZ2VyKSBmb29fOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgZm9vX2ludCA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZvb0ludCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvb0ludChpbnQgdmFsdWUpIHsKCiAgICAgICAgZm9vQ2FzZV8gPSAxOwogICAgICAgIGZvb18gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50MzIgZm9vX2ludCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZvb0ludCgpIHsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMSkgewogICAgICAgICAgZm9vQ2FzZV8gPSAwOwogICAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb1N0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb1N0cmluZygpIHsKICAgICAgICByZXR1cm4gZm9vQ2FzZV8gPT0gMjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZm9vU3RyaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGb29TdHJpbmcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSAiIjsKICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMikgewogICAgICAgICAgcmVmID0gZm9vXzsKICAgICAgICB9CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMikgewogICAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICAgIGZvb18gPSBzOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgZm9vU3RyaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRGb29TdHJpbmdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9ICIiOwogICAgICAgIGlmIChmb29DYXNlXyA9PSAyKSB7CiAgICAgICAgICByZWYgPSBmb29fOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICAgICAgZm9vXyA9IGI7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBmb29fc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZm9vU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZm9vQ2FzZV8gPSAyOwogICAgICAgIGZvb18gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+c3RyaW5nIGZvb19zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb29TdHJpbmcoKSB7CiAgICAgICAgaWYgKGZvb0Nhc2VfID09IDIpIHsKICAgICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgZm9vX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBmb29TdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29TdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZm9vQ2FzZV8gPSAyOwogICAgICAgIGZvb18gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiBmb29NZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb01lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29NZXNzYWdlKCkgewogICAgICAgIHJldHVybiBmb29DYXNlXyA9PSAzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmb29NZXNzYWdlLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGdldEZvb01lc3NhZ2UoKSB7CiAgICAgICAgaWYgKGZvb01lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMykgewogICAgICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSkgZm9vXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgICAgIHJldHVybiBmb29NZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29NZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChmb29NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDM7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29NZXNzYWdlKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKGZvb01lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBmb29fID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDM7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGZvb19tZXNzYWdlID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZvb01lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKGZvb01lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMyAmJgogICAgICAgICAgICAgIGZvb18gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGZvb18gPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlKSBmb29fKQogICAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDMpIHsKICAgICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb29NZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvb0Nhc2VfID0gMzsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vTWVzc2FnZSgpIHsKICAgICAgICBpZiAoZm9vTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSAzKSB7CiAgICAgICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gMykgewogICAgICAgICAgICBmb29DYXNlXyA9IDA7CiAgICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgZm9vTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGdldEZvb01lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRGb29NZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBmb29fbWVzc2FnZSA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGdldEZvb01lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKChmb29DYXNlXyA9PSAzKSAmJiAoZm9vTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgICByZXR1cm4gZm9vTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDMpIHsKICAgICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UpIGZvb187CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgZm9vX21lc3NhZ2UgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGb29NZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmb29NZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCEoZm9vQ2FzZV8gPT0gMykpIHsKICAgICAgICAgICAgZm9vXyA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIGZvb01lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UpIGZvb18sCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgZm9vQ2FzZV8gPSAzOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBmb29NZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZU9yQnVpbGRlcj4gZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGZvb19sYXp5X21lc3NhZ2UgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb0xhenlNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuIGZvb0Nhc2VfID09IDQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGZvb19sYXp5X21lc3NhZ2UgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmb29MYXp5TWVzc2FnZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBnZXRGb29MYXp5TWVzc2FnZSgpIHsKICAgICAgICBpZiAoZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gNCkgewogICAgICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSkgZm9vXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSA0KSB7CiAgICAgICAgICAgIHJldHVybiBmb29MYXp5TWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBmb29fbGF6eV9tZXNzYWdlID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvb0xhenlNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChmb29MYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZm9vXyA9IHZhbHVlOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvb0xhenlNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGZvb0Nhc2VfID0gNDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgZm9vX2xhenlfbWVzc2FnZSA9IDQgW2xhenkgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29MYXp5TWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChmb29MYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGZvb18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBmb29MYXp5TWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDQ7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGZvb19sYXp5X21lc3NhZ2UgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGb29MYXp5TWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAoZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoZm9vQ2FzZV8gPT0gNCAmJgogICAgICAgICAgICAgIGZvb18gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGZvb18gPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlKSBmb29fKQogICAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb29fID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDQpIHsKICAgICAgICAgICAgZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9vQ2FzZV8gPSA0OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBmb29fbGF6eV9tZXNzYWdlID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRm9vTGF6eU1lc3NhZ2UoKSB7CiAgICAgICAgaWYgKGZvb0xhenlNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKGZvb0Nhc2VfID09IDQpIHsKICAgICAgICAgICAgZm9vQ2FzZV8gPSAwOwogICAgICAgICAgICBmb29fID0gbnVsbDsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSA0KSB7CiAgICAgICAgICAgIGZvb0Nhc2VfID0gMDsKICAgICAgICAgICAgZm9vXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICBmb29MYXp5TWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBmb29fbGF6eV9tZXNzYWdlID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciBnZXRGb29MYXp5TWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldEZvb0xhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSBmb29fbGF6eV9tZXNzYWdlID0gNCBbbGF6eSA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZU9yQnVpbGRlciBnZXRGb29MYXp5TWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAoKGZvb0Nhc2VfID09IDQpICYmIChmb29MYXp5TWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgICByZXR1cm4gZm9vTGF6eU1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChmb29DYXNlXyA9PSA0KSB7CiAgICAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlKSBmb29fOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlIGZvb19sYXp5X21lc3NhZ2UgPSA0IFtsYXp5ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZvb0xhenlNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChmb29MYXp5TWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghKGZvb0Nhc2VfID09IDQpKSB7CiAgICAgICAgICAgIGZvb18gPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBmb29MYXp5TWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZSkgZm9vXywKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIGZvb18gPSBudWxsOwogICAgICAgIH0KICAgICAgICBmb29DYXNlXyA9IDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGZvb0xhenlNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkT25lb2YpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE9uZW9mKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVxdWlyZWRPbmVvZiBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlcXVpcmVkT25lb2Y+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFJlcXVpcmVkT25lb2Y+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UmVxdWlyZWRPbmVvZiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXF1aXJlZE9uZW9mPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXF1aXJlZE9uZW9mPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXF1aXJlZE9uZW9mIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFBhY2tlZFR5cGVzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFBhY2tlZEludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRJbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRQYWNrZWRJbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDY0LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkSW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UGFja2VkSW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFVpbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFBhY2tlZFVpbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkVWludDMyLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkVWludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRVaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkVWludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRVaW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRQYWNrZWRVaW50NjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFVpbnQ2NC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZFVpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkVWludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRQYWNrZWRVaW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNpbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFBhY2tlZFNpbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ludDMyLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2ludDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2ludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTaW50NjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRQYWNrZWRTaW50NjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNpbnQ2NC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZFNpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRQYWNrZWRTaW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRml4ZWQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFBhY2tlZEZpeGVkMzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEZpeGVkMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRGaXhlZDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEZpeGVkNjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRQYWNrZWRGaXhlZDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEZpeGVkNjQuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRGaXhlZDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFBhY2tlZEZpeGVkNjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZml4ZWQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFBhY2tlZFNmaXhlZDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ZpeGVkMzIuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRTZml4ZWQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZFNmaXhlZDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ZpeGVkNjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNmaXhlZDY0LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2ZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UGFja2VkU2ZpeGVkNjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRmxvYXQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4gZ2V0UGFja2VkRmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRmxvYXQuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRGbG9hdENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRGbG9hdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGZsb2F0IGdldFBhY2tlZEZsb2F0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRG91YmxlLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPiBnZXRQYWNrZWREb3VibGVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWREb3VibGUuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWREb3VibGVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBkb3VibGUgZ2V0UGFja2VkRG91YmxlKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRCb29sLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0UGFja2VkQm9vbExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkQm9vbC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEJvb2xDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEJvb2wgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBib29sZWFuIGdldFBhY2tlZEJvb2woaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRW51bS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bT4gZ2V0UGFja2VkRW51bUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRFbnVtLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkRW51bUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBnZXRQYWNrZWRFbnVtKGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RQYWNrZWRUeXBlcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMpCiAgICAgIFRlc3RQYWNrZWRUeXBlc09yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFBhY2tlZFR5cGVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RQYWNrZWRUeXBlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RQYWNrZWRUeXBlcygpIHsKICAgICAgcGFja2VkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHBhY2tlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcGFja2VkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwYWNrZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHBhY2tlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHBhY2tlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHBhY2tlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwYWNrZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcGFja2VkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwYWNrZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICBwYWNrZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgIHBhY2tlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICBwYWNrZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0UGFja2VkVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDkwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRJbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRQYWNrZWRJbnQzMkxpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkSW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkSW50MzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfSU5UNjRfRklFTERfTlVNQkVSID0gOTE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBwYWNrZWRJbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UGFja2VkSW50NjRMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkSW50NjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UGFja2VkSW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRJbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDkyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRVaW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkVWludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UGFja2VkVWludDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFVpbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFVpbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFVpbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFVpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkVWludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkVWludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkVWludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9VSU5UNjRfRklFTERfTlVNQkVSID0gOTM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBwYWNrZWRVaW50NjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFVpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFBhY2tlZFVpbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRVaW50NjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRVaW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkVWludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRVaW50NjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRVaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRVaW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRVaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkVWludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9TSU5UMzJfRklFTERfTlVNQkVSID0gOTQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZFNpbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRQYWNrZWRTaW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkU2ludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkU2ludDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRTaW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRTaW50MzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRTaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1NJTlQ2NF9GSUVMRF9OVU1CRVIgPSA5NTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFNpbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0UGFja2VkU2ludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNpbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNpbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRTaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNpbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZFNpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRTaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0ZJWEVEMzJfRklFTERfTlVNQkVSID0gOTY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZEZpeGVkMzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UGFja2VkRml4ZWQzMkxpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRGaXhlZDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGaXhlZDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkMzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRGaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkRml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSA5NzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZEZpeGVkNjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFBhY2tlZEZpeGVkNjRMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkRml4ZWQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRml4ZWQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRGaXhlZDY0Q291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRGaXhlZDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UGFja2VkRml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkNjRfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkRml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfU0ZJWEVEMzJfRklFTERfTlVNQkVSID0gOTg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZFNmaXhlZDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFBhY2tlZFNmaXhlZDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNmaXhlZDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNmaXhlZDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiBwYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2ZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZFNmaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9TRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSA5OTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZFNmaXhlZDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2ZpeGVkNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZml4ZWQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRTZml4ZWQ2NENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkU2ZpeGVkNjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRTZml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZFNmaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9GTE9BVF9GSUVMRF9OVU1CRVIgPSAxMDA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5GbG9hdExpc3QgcGFja2VkRmxvYXRfID0KICAgICAgICBlbXB0eUZsb2F0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCBwYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEZsb2F0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkZsb2F0PgogICAgICAgIGdldFBhY2tlZEZsb2F0TGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEZsb2F0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGbG9hdC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRGbG9hdENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkRmxvYXRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGZsb2F0IGdldFBhY2tlZEZsb2F0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkRmxvYXRfLmdldEZsb2F0KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEZsb2F0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9ET1VCTEVfRklFTERfTlVNQkVSID0gMTAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCBwYWNrZWREb3VibGVfID0KICAgICAgICBlbXB0eURvdWJsZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZERvdWJsZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZ2V0UGFja2VkRG91YmxlTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZERvdWJsZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWREb3VibGUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRG91YmxlQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWREb3VibGVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGRvdWJsZSBnZXRQYWNrZWREb3VibGUoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWREb3VibGVfLmdldERvdWJsZShpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWREb3VibGVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0JPT0xfRklFTERfTlVNQkVSID0gMTAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgcGFja2VkQm9vbF8gPQogICAgICAgIGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkQm9vbC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGdldFBhY2tlZEJvb2xMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkQm9vbF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEJvb2wuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkQm9vbENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkQm9vbF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEJvb2wgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRQYWNrZWRCb29sKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkQm9vbF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRCb29sTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9FTlVNX0ZJRUxEX05VTUJFUiA9IDEwMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2VkRW51bV87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bT4gcGFja2VkRW51bV9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uRk9SRUlHTl9GT08gOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtPiBnZXRQYWNrZWRFbnVtTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+KHBhY2tlZEVudW1fLCBwYWNrZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRW51bUNvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkRW51bV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRW51bSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIGdldFBhY2tlZEVudW0oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRFbnVtX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRFbnVtXy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgaWYgKGdldFBhY2tlZEludDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3MjIpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMk5vVGFnKHBhY2tlZEludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRJbnQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzMwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRJbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkSW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjROb1RhZyhwYWNrZWRJbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFVpbnQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzM4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRVaW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFVpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFVpbnQ2NExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzQ2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRVaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50NjROb1RhZyhwYWNrZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTaW50MzJMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDc1NCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2ludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDMyTm9UYWcocGFja2VkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTaW50NjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDc2Mik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2ludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRTaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0Tm9UYWcocGFja2VkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkRml4ZWQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzcwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRGaXhlZDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRGaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkMzJOb1RhZyhwYWNrZWRGaXhlZDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRGaXhlZDY0TGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3NzgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEZpeGVkNjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQ2NE5vVGFnKHBhY2tlZEZpeGVkNjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTZml4ZWQzMkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoNzg2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRTZml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2ZpeGVkMzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ZpeGVkMzJOb1RhZyhwYWNrZWRTZml4ZWQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2ZpeGVkNjRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDc5NCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2ZpeGVkNjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNmaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDY0Tm9UYWcocGFja2VkU2ZpeGVkNjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRGbG9hdExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoODAyKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRGbG9hdE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkRmxvYXRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRmxvYXROb1RhZyhwYWNrZWRGbG9hdF8uZ2V0RmxvYXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWREb3VibGVMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDgxMCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkRG91YmxlTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWREb3VibGVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlTm9UYWcocGFja2VkRG91YmxlXy5nZXREb3VibGUoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRCb29sTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MTgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEJvb2xNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEJvb2xfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbE5vVGFnKHBhY2tlZEJvb2xfLmdldEJvb2xlYW4oaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRFbnVtTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MjYpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bU5vVGFnKHBhY2tlZEVudW1fLmdldChpKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkSW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcocGFja2VkSW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRJbnQzMkxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZU5vVGFnKHBhY2tlZEludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEludDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkVWludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhwYWNrZWRVaW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRVaW50MzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkVWludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyhwYWNrZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkVWludDY0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZFVpbnQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50MzJTaXplTm9UYWcocGFja2VkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkU2ludDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZFNpbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50NjRTaXplTm9UYWcocGFja2VkU2ludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZFNpbnQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRTaW50NjRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UGFja2VkRml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEZpeGVkMzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkRml4ZWQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDggKiBnZXRQYWNrZWRGaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkRml4ZWQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRGaXhlZDY0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFBhY2tlZFNmaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkU2ZpeGVkMzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UGFja2VkU2ZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRTZml4ZWQ2NE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRQYWNrZWRGbG9hdExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEZsb2F0TGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEZsb2F0TWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFBhY2tlZERvdWJsZUxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZERvdWJsZUxpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWREb3VibGVNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSAxICogZ2V0UGFja2VkQm9vbExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEJvb2xMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkQm9vbE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhwYWNrZWRFbnVtXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkRW51bUxpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfXBhY2tlZEVudW1NZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzKSBvYmo7CgogICAgICBpZiAoIWdldFBhY2tlZEludDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEludDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEludDY0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZFVpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRVaW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkVWludDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZFVpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRTaW50MzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkU2ludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZFNpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRTaW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkRml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRGaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkRml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRTZml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRTZml4ZWQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRTZml4ZWQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRTZml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRGbG9hdExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRGbG9hdExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWREb3VibGVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkRG91YmxlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEJvb2xMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkQm9vbExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFwYWNrZWRFbnVtXy5lcXVhbHMob3RoZXIucGFja2VkRW51bV8pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGdldFBhY2tlZEludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfSU5UNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFVpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1VJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkVWludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFVpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1VJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkVWludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1NJTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkU2ludDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1NJTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkU2ludDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEZpeGVkMzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9GSVhFRDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRGaXhlZDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEZpeGVkNjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRGaXhlZDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNmaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfU0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZFNmaXhlZDMyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNmaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfU0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZFNmaXhlZDY0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEZsb2F0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfRkxPQVRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEZsb2F0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZERvdWJsZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX0RPVUJMRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkRG91YmxlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEJvb2xDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9CT09MX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRCb29sTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEVudW1Db3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBwYWNrZWRFbnVtXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBwYWNrZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBwYWNrZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcGFja2VkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHBhY2tlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcGFja2VkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHBhY2tlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcGFja2VkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBwYWNrZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBwYWNrZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBwYWNrZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcGFja2VkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBwYWNrZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgcGFja2VkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgcGFja2VkRW51bV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyh0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyByZXN1bHQpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMjAwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocGFja2VkRW51bV8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQucGFja2VkRW51bV8gPSBwYWNrZWRFbnVtXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkSW50MzJfID0gcGFja2VkSW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRJbnQ2NF8gPSBwYWNrZWRJbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRVaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRVaW50MzJfID0gcGFja2VkVWludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZFVpbnQ2NF8gPSBwYWNrZWRVaW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkU2ludDMyXyA9IHBhY2tlZFNpbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRTaW50NjRfID0gcGFja2VkU2ludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRGaXhlZDMyXyA9IHBhY2tlZEZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZEZpeGVkNjRfID0gcGFja2VkRml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZFNmaXhlZDMyXyA9IHBhY2tlZFNmaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkU2ZpeGVkNjRfID0gcGFja2VkU2ZpeGVkNjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRGbG9hdF8gPSBwYWNrZWRGbG9hdF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWREb3VibGVfID0gcGFja2VkRG91YmxlXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEJvb2xfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRCb29sXyA9IHBhY2tlZEJvb2xfOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRJbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRJbnQzMl8gPSBvdGhlci5wYWNrZWRJbnQzMl87CiAgICAgICAgICAgIHBhY2tlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEludDMyXy5hZGRBbGwob3RoZXIucGFja2VkSW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRJbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEludDY0XyA9IG90aGVyLnBhY2tlZEludDY0XzsKICAgICAgICAgICAgcGFja2VkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkSW50NjRfLmFkZEFsbChvdGhlci5wYWNrZWRJbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkVWludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRVaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRVaW50MzJfID0gb3RoZXIucGFja2VkVWludDMyXzsKICAgICAgICAgICAgcGFja2VkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRVaW50MzJfLmFkZEFsbChvdGhlci5wYWNrZWRVaW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZFVpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkVWludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkVWludDY0XyA9IG90aGVyLnBhY2tlZFVpbnQ2NF87CiAgICAgICAgICAgIHBhY2tlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkVWludDY0Xy5hZGRBbGwob3RoZXIucGFja2VkVWludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRTaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFNpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZFNpbnQzMl8gPSBvdGhlci5wYWNrZWRTaW50MzJfOwogICAgICAgICAgICBwYWNrZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFNpbnQzMl8uYWRkQWxsKG90aGVyLnBhY2tlZFNpbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkU2ludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRTaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRTaW50NjRfID0gb3RoZXIucGFja2VkU2ludDY0XzsKICAgICAgICAgICAgcGFja2VkU2ludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRTaW50NjRfLmFkZEFsbChvdGhlci5wYWNrZWRTaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRGaXhlZDMyXyA9IG90aGVyLnBhY2tlZEZpeGVkMzJfOwogICAgICAgICAgICBwYWNrZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkRml4ZWQzMl8uYWRkQWxsKG90aGVyLnBhY2tlZEZpeGVkMzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRGaXhlZDY0XyA9IG90aGVyLnBhY2tlZEZpeGVkNjRfOwogICAgICAgICAgICBwYWNrZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkRml4ZWQ2NF8uYWRkQWxsKG90aGVyLnBhY2tlZEZpeGVkNjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZFNmaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRTZml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZFNmaXhlZDMyXyA9IG90aGVyLnBhY2tlZFNmaXhlZDMyXzsKICAgICAgICAgICAgcGFja2VkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkU2ZpeGVkMzJfLmFkZEFsbChvdGhlci5wYWNrZWRTZml4ZWQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkU2ZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFNmaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkU2ZpeGVkNjRfID0gb3RoZXIucGFja2VkU2ZpeGVkNjRfOwogICAgICAgICAgICBwYWNrZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRTZml4ZWQ2NF8uYWRkQWxsKG90aGVyLnBhY2tlZFNmaXhlZDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRGbG9hdF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkRmxvYXRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRGbG9hdF8gPSBvdGhlci5wYWNrZWRGbG9hdF87CiAgICAgICAgICAgIHBhY2tlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEZsb2F0Xy5hZGRBbGwob3RoZXIucGFja2VkRmxvYXRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZERvdWJsZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkRG91YmxlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkRG91YmxlXyA9IG90aGVyLnBhY2tlZERvdWJsZV87CiAgICAgICAgICAgIHBhY2tlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkRG91YmxlXy5hZGRBbGwob3RoZXIucGFja2VkRG91YmxlXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRCb29sXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRCb29sXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkQm9vbF8gPSBvdGhlci5wYWNrZWRCb29sXzsKICAgICAgICAgICAgcGFja2VkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEJvb2xfLmFkZEFsbChvdGhlci5wYWNrZWRCb29sXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkRW51bV8gPSBvdGhlci5wYWNrZWRFbnVtXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRFbnVtXy5hZGRBbGwob3RoZXIucGFja2VkRW51bV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgNzIwOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZEludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzIwCiAgICAgICAgICAgICAgY2FzZSA3MjI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkSW50MzJfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzIyCiAgICAgICAgICAgICAgY2FzZSA3Mjg6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZEludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDcyOAogICAgICAgICAgICAgIGNhc2UgNzMwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZEludDY0Xy5hZGRMb25nKGlucHV0LnJlYWRJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MzAKICAgICAgICAgICAgICBjYXNlIDczNjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZFVpbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDczNgogICAgICAgICAgICAgIGNhc2UgNzM4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRVaW50MzJfLmFkZEludChpbnB1dC5yZWFkVUludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDczOAogICAgICAgICAgICAgIGNhc2UgNzQ0OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkVUludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZFVpbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NDQKICAgICAgICAgICAgICBjYXNlIDc0NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkVWludDY0Xy5hZGRMb25nKGlucHV0LnJlYWRVSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQ2CiAgICAgICAgICAgICAgY2FzZSA3NTI6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFNJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRTaW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NTIKICAgICAgICAgICAgICBjYXNlIDc1NDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkU2ludDMyXy5hZGRJbnQoaW5wdXQucmVhZFNJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NTQKICAgICAgICAgICAgICBjYXNlIDc2MDogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRTaW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzYwCiAgICAgICAgICAgICAgY2FzZSA3NjI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZFNpbnQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkU0ludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc2MgogICAgICAgICAgICAgIGNhc2UgNzczOiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRGaXhlZDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzczCiAgICAgICAgICAgICAgY2FzZSA3NzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDMySXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZEZpeGVkMzJfLmFkZEludChpbnB1dC5yZWFkRml4ZWQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzAKICAgICAgICAgICAgICBjYXNlIDc3NzogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZEZpeGVkNjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzc3CiAgICAgICAgICAgICAgY2FzZSA3Nzg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDY0SXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZEZpeGVkNjRfLmFkZExvbmcoaW5wdXQucmVhZEZpeGVkNjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzc4CiAgICAgICAgICAgICAgY2FzZSA3ODk6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFNGaXhlZDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkU2ZpeGVkMzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3ODkKICAgICAgICAgICAgICBjYXNlIDc4NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZFNmaXhlZDMyXy5hZGRJbnQoaW5wdXQucmVhZFNGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc4NgogICAgICAgICAgICAgIGNhc2UgNzkzOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRTZml4ZWQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3OTMKICAgICAgICAgICAgICBjYXNlIDc5NDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZFNmaXhlZDY0Xy5hZGRMb25nKGlucHV0LnJlYWRTRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3OTQKICAgICAgICAgICAgICBjYXNlIDgwNTogewogICAgICAgICAgICAgICAgZmxvYXQgdiA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZEZsb2F0Xy5hZGRGbG9hdCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDUKICAgICAgICAgICAgICBjYXNlIDgwMjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEZsb2F0SXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZEZsb2F0Xy5hZGRGbG9hdChpbnB1dC5yZWFkRmxvYXQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAyCiAgICAgICAgICAgICAgY2FzZSA4MDk6IHsKICAgICAgICAgICAgICAgIGRvdWJsZSB2ID0gaW5wdXQucmVhZERvdWJsZSgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWREb3VibGVfLmFkZERvdWJsZSh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDkKICAgICAgICAgICAgICBjYXNlIDgxMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWREb3VibGVfLmFkZERvdWJsZShpbnB1dC5yZWFkRG91YmxlKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxMAogICAgICAgICAgICAgIGNhc2UgODE2OiB7CiAgICAgICAgICAgICAgICBib29sZWFuIHYgPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkQm9vbElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkQm9vbF8uYWRkQm9vbGVhbih2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MTYKICAgICAgICAgICAgICBjYXNlIDgxODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoYWxsb2MgLyAxKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkQm9vbF8uYWRkQm9vbGVhbihpbnB1dC5yZWFkQm9vbCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MTgKICAgICAgICAgICAgICBjYXNlIDgyNDogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMTAzLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBwYWNrZWRFbnVtXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MjQKICAgICAgICAgICAgICBjYXNlIDgyNjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDMsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIHBhY2tlZEVudW1fLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODI2CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkSW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRJbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEludDMyXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRJbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UGFja2VkSW50MzJMaXN0KCkgewogICAgICAgIHBhY2tlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRJbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkSW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRJbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50MzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRJbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZEludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkSW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRJbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRJbnQzMigpIHsKICAgICAgICBwYWNrZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBwYWNrZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRJbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkSW50NjRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRQYWNrZWRJbnQ2NExpc3QoKSB7CiAgICAgICAgcGFja2VkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkSW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkSW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZEludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRJbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRJbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkSW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkSW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRJbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkSW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkSW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRJbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEludDY0KCkgewogICAgICAgIHBhY2tlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFVpbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZFVpbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZFVpbnQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkVWludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRVaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRQYWNrZWRVaW50MzJMaXN0KCkgewogICAgICAgIHBhY2tlZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRVaW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkVWludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFVpbnQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgcGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRVaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRVaW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFVpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkVWludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkVWludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkVWludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRVaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRVaW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFVpbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiBwYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkVWludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkVWludDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZFVpbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZFVpbnQzMigpIHsKICAgICAgICBwYWNrZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZFVpbnQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZFVpbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkVWludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRVaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRQYWNrZWRVaW50NjRMaXN0KCkgewogICAgICAgIHBhY2tlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRVaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkVWludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFVpbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRVaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UGFja2VkVWludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRVaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRVaW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRVaW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkVWludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkVWludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkVWludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkVWludDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCBwYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkVWludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkVWludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZFVpbnQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZFVpbnQ2NCgpIHsKICAgICAgICBwYWNrZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkU2ludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkU2ludDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkU2ludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkU2ludDMyXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRTaW50MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFBhY2tlZFNpbnQzMkxpc3QoKSB7CiAgICAgICAgcGFja2VkU2ludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRTaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRTaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRTaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTaW50MzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2ludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRTaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRTaW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkU2ludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkU2ludDMyKCkgewogICAgICAgIHBhY2tlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBwYWNrZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkU2ludDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkU2ludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkU2ludDY0XyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRTaW50NjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFBhY2tlZFNpbnQ2NExpc3QoKSB7CiAgICAgICAgcGFja2VkU2ludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRTaW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2ludDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRTaW50NjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZFNpbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTaW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCBwYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRTaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRTaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTaW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRTaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRTaW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkU2ludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgcGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkU2ludDY0KCkgewogICAgICAgIHBhY2tlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRml4ZWQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRGaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRGaXhlZDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRml4ZWQzMklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXBhY2tlZEZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRGaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRGaXhlZDMyXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRGaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UGFja2VkRml4ZWQzMkxpc3QoKSB7CiAgICAgICAgcGFja2VkRml4ZWQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRGaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRml4ZWQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRGaXhlZDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRGaXhlZDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRGaXhlZDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEZpeGVkMzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRGaXhlZDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiBwYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZEZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRGaXhlZDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRGaXhlZDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRGaXhlZDMyKCkgewogICAgICAgIHBhY2tlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRGaXhlZDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkRml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEZpeGVkNjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRGaXhlZDY0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkRml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEZpeGVkNjRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRQYWNrZWRGaXhlZDY0TGlzdCgpIHsKICAgICAgICBwYWNrZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRml4ZWQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRGaXhlZDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRQYWNrZWRGaXhlZDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRGaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRGaXhlZDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkRml4ZWQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRml4ZWQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCBwYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRml4ZWQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkRml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEZpeGVkNjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEZpeGVkNjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEZpeGVkNjQoKSB7CiAgICAgICAgcGFja2VkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkU2ZpeGVkMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRTZml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkU2ZpeGVkMzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRTZml4ZWQzMklzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXBhY2tlZFNmaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkU2ZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFNmaXhlZDMyXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNmaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UGFja2VkU2ZpeGVkMzJMaXN0KCkgewogICAgICAgIHBhY2tlZFNmaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2ZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNmaXhlZDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNmaXhlZDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNmaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkU2ZpeGVkMzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNmaXhlZDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2ZpeGVkMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRTZml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTZml4ZWQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNmaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkU2ZpeGVkMzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRTZml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRTZml4ZWQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgcGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRTZml4ZWQzMigpIHsKICAgICAgICBwYWNrZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCBwYWNrZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZFNmaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkU2ZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZFNmaXhlZDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkU2ZpeGVkNjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWRTZml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZFNmaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRTZml4ZWQ2NF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFBhY2tlZFNmaXhlZDY0TGlzdCgpIHsKICAgICAgICBwYWNrZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNmaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRTZml4ZWQ2NENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRTZml4ZWQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UGFja2VkU2ZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNmaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNmaXhlZDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkU2ZpeGVkNjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTZml4ZWQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgcGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRTZml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNmaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTZml4ZWQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCBwYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRTZml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZFNmaXhlZDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkU2ZpeGVkNjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkU2ZpeGVkNjQoKSB7CiAgICAgICAgcGFja2VkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkZsb2F0TGlzdCBwYWNrZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRGbG9hdF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEZsb2F0XyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRGbG9hdF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEZsb2F0SXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkRmxvYXRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRGbG9hdF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRmxvYXRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEZsb2F0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICAgIGdldFBhY2tlZEZsb2F0TGlzdCgpIHsKICAgICAgICBwYWNrZWRGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRGbG9hdF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRGbG9hdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRmxvYXRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRmxvYXRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRGbG9hdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZmxvYXQgZ2V0UGFja2VkRmxvYXQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEZsb2F0Xy5nZXRGbG9hdChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkRmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRGbG9hdCgKICAgICAgICAgIGludCBpbmRleCwgZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRGbG9hdF8uc2V0RmxvYXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEZsb2F0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkRmxvYXQoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRGbG9hdF8uYWRkRmxvYXQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZEZsb2F0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkRmxvYXQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkRmxvYXRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkRmxvYXRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEZsb2F0KCkgewogICAgICAgIHBhY2tlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA0MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRG91YmxlTGlzdCBwYWNrZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWREb3VibGVJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWREb3VibGVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWREb3VibGVfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZERvdWJsZV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXBhY2tlZERvdWJsZV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZERvdWJsZV8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkRG91YmxlXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZERvdWJsZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPgogICAgICAgICAgZ2V0UGFja2VkRG91YmxlTGlzdCgpIHsKICAgICAgICBwYWNrZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkRG91YmxlXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkRG91YmxlLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWREb3VibGVDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRG91YmxlXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSBwYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGRvdWJsZSBnZXRQYWNrZWREb3VibGUoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZERvdWJsZV8uZ2V0RG91YmxlKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZERvdWJsZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZERvdWJsZSgKICAgICAgICAgIGludCBpbmRleCwgZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZERvdWJsZV8uc2V0RG91YmxlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZERvdWJsZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZERvdWJsZShkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRG91YmxlXy5hZGREb3VibGUodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkRG91YmxlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkRG91YmxlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkRG91YmxlXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgcGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZERvdWJsZSgpIHsKICAgICAgICBwYWNrZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgcGFja2VkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRCb29sSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkQm9vbF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEJvb2xfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEJvb2xfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRCb29sSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkQm9vbF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEJvb2xfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEJvb2xfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRCb29sLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0UGFja2VkQm9vbExpc3QoKSB7CiAgICAgICAgcGFja2VkQm9vbF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRCb29sXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRCb29sLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRCb29sQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEJvb2xfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRQYWNrZWRCb29sKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRCb29sXy5nZXRCb29sZWFuKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkQm9vbCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEJvb2woCiAgICAgICAgICBpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkQm9vbElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEJvb2xfLnNldEJvb2xlYW4oaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRCb29sIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkQm9vbChib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEJvb2xJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRCb29sXy5hZGRCb29sZWFuKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkQm9vbCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEJvb2woCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRCb29sSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEJvb2xfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRCb29sKCkgewogICAgICAgIHBhY2tlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2VkRW51bV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkRW51bV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4ocGFja2VkRW51bV8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bT4gZ2V0UGFja2VkRW51bUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bT4ocGFja2VkRW51bV8sIHBhY2tlZEVudW1fY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRFbnVtLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRFbnVtQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIGdldFBhY2tlZEVudW0oaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHBhY2tlZEVudW1fLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEVudW0gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRFbnVtKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVQYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkRW51bV8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBwYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRFbnVtKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBwYWNrZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkRW51bSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEVudW0oCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHBhY2tlZEVudW1fLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gcGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRFbnVtKCkgewogICAgICAgIHBhY2tlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkVHlwZXMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZFR5cGVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQYWNrZWRUeXBlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0UGFja2VkVHlwZXM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0UGFja2VkVHlwZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UGFja2VkVHlwZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFBhY2tlZFR5cGVzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RVbnBhY2tlZFR5cGVzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZFR5cGVzKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgdW5wYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHVucGFja2VkSW50MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRVbnBhY2tlZEludDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB1bnBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRJbnQzMi4KICAgICAqLwogICAgaW50IGdldFVucGFja2VkSW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB1bnBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSB1bnBhY2tlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFVucGFja2VkSW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHVucGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZEludDY0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0VW5wYWNrZWRJbnQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgdW5wYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkSW50NjQuCiAgICAgKi8KICAgIGludCBnZXRVbnBhY2tlZEludDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgdW5wYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRJbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0VW5wYWNrZWRJbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHVucGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWRVaW50MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRVbnBhY2tlZFVpbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHVucGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRVaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRVbnBhY2tlZFVpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiB1bnBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRVaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0VW5wYWNrZWRVaW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCB1bnBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHVucGFja2VkVWludDY0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0VW5wYWNrZWRVaW50NjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCB1bnBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkVWludDY0LgogICAgICovCiAgICBpbnQgZ2V0VW5wYWNrZWRVaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgdW5wYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHVucGFja2VkVWludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRVbnBhY2tlZFVpbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHVucGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWRTaW50MzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRVbnBhY2tlZFNpbnQzMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHVucGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRTaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRVbnBhY2tlZFNpbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiB1bnBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRTaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0VW5wYWNrZWRTaW50MzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCB1bnBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHVucGFja2VkU2ludDY0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0VW5wYWNrZWRTaW50NjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCB1bnBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkU2ludDY0LgogICAgICovCiAgICBpbnQgZ2V0VW5wYWNrZWRTaW50NjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgdW5wYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHVucGFja2VkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRVbnBhY2tlZFNpbnQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiB1bnBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZEZpeGVkMzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRVbnBhY2tlZEZpeGVkMzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgdW5wYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRGaXhlZDMyLgogICAgICovCiAgICBpbnQgZ2V0VW5wYWNrZWRGaXhlZDMyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiB1bnBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHVucGFja2VkRml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRVbnBhY2tlZEZpeGVkMzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgdW5wYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWRGaXhlZDY0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0VW5wYWNrZWRGaXhlZDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHVucGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkRml4ZWQ2NC4KICAgICAqLwogICAgaW50IGdldFVucGFja2VkRml4ZWQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgdW5wYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSB1bnBhY2tlZEZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFVucGFja2VkRml4ZWQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgdW5wYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHVucGFja2VkU2ZpeGVkMzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRVbnBhY2tlZFNmaXhlZDMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiB1bnBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRTZml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldFVucGFja2VkU2ZpeGVkMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiB1bnBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSB1bnBhY2tlZFNmaXhlZDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFVucGFja2VkU2ZpeGVkMzIoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHVucGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZFNmaXhlZDY0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0VW5wYWNrZWRTZml4ZWQ2NExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgdW5wYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkU2ZpeGVkNjQuCiAgICAgKi8KICAgIGludCBnZXRVbnBhY2tlZFNmaXhlZDY0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgdW5wYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0VW5wYWNrZWRTZml4ZWQ2NChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgdW5wYWNrZWRfZmxvYXQgPSAxMDAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZEZsb2F0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+IGdldFVucGFja2VkRmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHVucGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRGbG9hdC4KICAgICAqLwogICAgaW50IGdldFVucGFja2VkRmxvYXRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCB1bnBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRGbG9hdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGZsb2F0IGdldFVucGFja2VkRmxvYXQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSB1bnBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZERvdWJsZS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4gZ2V0VW5wYWNrZWREb3VibGVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSB1bnBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB1bnBhY2tlZERvdWJsZS4KICAgICAqLwogICAgaW50IGdldFVucGFja2VkRG91YmxlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHVucGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBkb3VibGUgZ2V0VW5wYWNrZWREb3VibGUoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgdW5wYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHVucGFja2VkQm9vbC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+IGdldFVucGFja2VkQm9vbExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCB1bnBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRCb29sLgogICAgICovCiAgICBpbnQgZ2V0VW5wYWNrZWRCb29sQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCB1bnBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSB1bnBhY2tlZEJvb2wgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBib29sZWFuIGdldFVucGFja2VkQm9vbChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHVucGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZEVudW0uCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+IGdldFVucGFja2VkRW51bUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHVucGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB1bnBhY2tlZEVudW0uCiAgICAgKi8KICAgIGludCBnZXRVbnBhY2tlZEVudW1Db3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gdW5wYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBnZXRVbnBhY2tlZEVudW0oaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogPHByZT4KICAgKiBBIG1lc3NhZ2Ugd2l0aCB0aGUgc2FtZSBmaWVsZHMgYXMgVGVzdFBhY2tlZFR5cGVzLCBidXQgd2l0aG91dCBwYWNraW5nLiBVc2VkCiAgICogdG8gdGVzdCBwYWNrZWQgJmx0Oy0mZ3Q7IHVucGFja2VkIHdpcmUgY29tcGF0aWJpbGl0eS4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZFR5cGVzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFVucGFja2VkVHlwZXMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkVHlwZXMpCiAgICAgIFRlc3RVbnBhY2tlZFR5cGVzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0VW5wYWNrZWRUeXBlcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0VW5wYWNrZWRUeXBlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RVbnBhY2tlZFR5cGVzKCkgewogICAgICB1bnBhY2tlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICB1bnBhY2tlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgdW5wYWNrZWRVaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHVucGFja2VkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgdW5wYWNrZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHVucGFja2VkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgdW5wYWNrZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICB1bnBhY2tlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICB1bnBhY2tlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICB1bnBhY2tlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgdW5wYWNrZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICB1bnBhY2tlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgdW5wYWNrZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgdW5wYWNrZWRFbnVtXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0VW5wYWNrZWRUeXBlcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFVucGFja2VkVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOUEFDS0VEX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDkwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCB1bnBhY2tlZEludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHVucGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZEludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0VW5wYWNrZWRJbnQzMkxpc3QoKSB7CiAgICAgIHJldHVybiB1bnBhY2tlZEludDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgdW5wYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkSW50MzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0VW5wYWNrZWRJbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gdW5wYWNrZWRJbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB1bnBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSB1bnBhY2tlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRVbnBhY2tlZEludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gdW5wYWNrZWRJbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlBBQ0tFRF9JTlQ2NF9GSUVMRF9OVU1CRVIgPSA5MTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHVucGFja2VkSW50NjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHVucGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZEludDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgZ2V0VW5wYWNrZWRJbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiB1bnBhY2tlZEludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgdW5wYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkSW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0VW5wYWNrZWRJbnQ2NENvdW50KCkgewogICAgICByZXR1cm4gdW5wYWNrZWRJbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCB1bnBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSB1bnBhY2tlZEludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0VW5wYWNrZWRJbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkSW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOUEFDS0VEX1VJTlQzMl9GSUVMRF9OVU1CRVIgPSA5MjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgdW5wYWNrZWRVaW50MzJfID0KICAgICAgICBlbXB0eUludExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHVucGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWRVaW50MzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRVbnBhY2tlZFVpbnQzMkxpc3QoKSB7CiAgICAgIHJldHVybiB1bnBhY2tlZFVpbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiB1bnBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkVWludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFVucGFja2VkVWludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiB1bnBhY2tlZFVpbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgdW5wYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHVucGFja2VkVWludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRVbnBhY2tlZFVpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkVWludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOUEFDS0VEX1VJTlQ2NF9GSUVMRF9OVU1CRVIgPSA5MzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHVucGFja2VkVWludDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgdW5wYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZFVpbnQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFVucGFja2VkVWludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkVWludDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHVucGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRVaW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0VW5wYWNrZWRVaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkVWludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCB1bnBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRVaW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRVbnBhY2tlZFVpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkVWludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlBBQ0tFRF9TSU5UMzJfRklFTERfTlVNQkVSID0gOTQ7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHVucGFja2VkU2ludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiB1bnBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHVucGFja2VkU2ludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0VW5wYWNrZWRTaW50MzJMaXN0KCkgewogICAgICByZXR1cm4gdW5wYWNrZWRTaW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgdW5wYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB1bnBhY2tlZFNpbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRVbnBhY2tlZFNpbnQzMkNvdW50KCkgewogICAgICByZXR1cm4gdW5wYWNrZWRTaW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHVucGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSB1bnBhY2tlZFNpbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0VW5wYWNrZWRTaW50MzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiB1bnBhY2tlZFNpbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlBBQ0tFRF9TSU5UNjRfRklFTERfTlVNQkVSID0gOTU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCB1bnBhY2tlZFNpbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHVucGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWRTaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRVbnBhY2tlZFNpbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiB1bnBhY2tlZFNpbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCB1bnBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkU2ludDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFVucGFja2VkU2ludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiB1bnBhY2tlZFNpbnQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgdW5wYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHVucGFja2VkU2ludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0VW5wYWNrZWRTaW50NjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiB1bnBhY2tlZFNpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5QQUNLRURfRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA5NjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgdW5wYWNrZWRGaXhlZDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgdW5wYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWRGaXhlZDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0VW5wYWNrZWRGaXhlZDMyTGlzdCgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkRml4ZWQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgdW5wYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRGaXhlZDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFVucGFja2VkRml4ZWQzMkNvdW50KCkgewogICAgICByZXR1cm4gdW5wYWNrZWRGaXhlZDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgdW5wYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSB1bnBhY2tlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFVucGFja2VkRml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkRml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlBBQ0tFRF9GSVhFRDY0X0ZJRUxEX05VTUJFUiA9IDk3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgdW5wYWNrZWRGaXhlZDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHVucGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHVucGFja2VkRml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFVucGFja2VkRml4ZWQ2NExpc3QoKSB7CiAgICAgIHJldHVybiB1bnBhY2tlZEZpeGVkNjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHVucGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkRml4ZWQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRVbnBhY2tlZEZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkRml4ZWQ2NF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHVucGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0VW5wYWNrZWRGaXhlZDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gdW5wYWNrZWRGaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlBBQ0tFRF9TRklYRUQzMl9GSUVMRF9OVU1CRVIgPSA5ODsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgdW5wYWNrZWRTZml4ZWQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiB1bnBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWRTZml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFVucGFja2VkU2ZpeGVkMzJMaXN0KCkgewogICAgICByZXR1cm4gdW5wYWNrZWRTZml4ZWQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHVucGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB1bnBhY2tlZFNmaXhlZDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFVucGFja2VkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkU2ZpeGVkMzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgdW5wYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0VW5wYWNrZWRTZml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkU2ZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5QQUNLRURfU0ZJWEVENjRfRklFTERfTlVNQkVSID0gOTk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCB1bnBhY2tlZFNmaXhlZDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCB1bnBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWRTZml4ZWQ2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFVucGFja2VkU2ZpeGVkNjRMaXN0KCkgewogICAgICByZXR1cm4gdW5wYWNrZWRTZml4ZWQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHVucGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB1bnBhY2tlZFNmaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFVucGFja2VkU2ZpeGVkNjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkU2ZpeGVkNjRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgdW5wYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRTZml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFVucGFja2VkU2ZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiB1bnBhY2tlZFNmaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlBBQ0tFRF9GTE9BVF9GSUVMRF9OVU1CRVIgPSAxMDA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5GbG9hdExpc3QgdW5wYWNrZWRGbG9hdF8gPQogICAgICAgIGVtcHR5RmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHVucGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWRGbG9hdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICBnZXRVbnBhY2tlZEZsb2F0TGlzdCgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkRmxvYXRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCB1bnBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkRmxvYXQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0VW5wYWNrZWRGbG9hdENvdW50KCkgewogICAgICByZXR1cm4gdW5wYWNrZWRGbG9hdF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCB1bnBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRGbG9hdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBmbG9hdCBnZXRVbnBhY2tlZEZsb2F0KGludCBpbmRleCkgewogICAgICByZXR1cm4gdW5wYWNrZWRGbG9hdF8uZ2V0RmxvYXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOUEFDS0VEX0RPVUJMRV9GSUVMRF9OVU1CRVIgPSAxMDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHVucGFja2VkRG91YmxlXyA9CiAgICAgICAgZW1wdHlEb3VibGVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSB1bnBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZERvdWJsZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Eb3VibGU+CiAgICAgICAgZ2V0VW5wYWNrZWREb3VibGVMaXN0KCkgewogICAgICByZXR1cm4gdW5wYWNrZWREb3VibGVfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgdW5wYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWREb3VibGUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0VW5wYWNrZWREb3VibGVDb3VudCgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkRG91YmxlXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSB1bnBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHVucGFja2VkRG91YmxlIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGRvdWJsZSBnZXRVbnBhY2tlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkRG91YmxlXy5nZXREb3VibGUoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOUEFDS0VEX0JPT0xfRklFTERfTlVNQkVSID0gMTAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgdW5wYWNrZWRCb29sXyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHVucGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZEJvb2wuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBnZXRVbnBhY2tlZEJvb2xMaXN0KCkgewogICAgICByZXR1cm4gdW5wYWNrZWRCb29sXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCB1bnBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRCb29sLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFVucGFja2VkQm9vbENvdW50KCkgewogICAgICByZXR1cm4gdW5wYWNrZWRCb29sXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgdW5wYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRCb29sIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZ2V0VW5wYWNrZWRCb29sKGludCBpbmRleCkgewogICAgICByZXR1cm4gdW5wYWNrZWRCb29sXy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlBBQ0tFRF9FTlVNX0ZJRUxEX05VTUJFUiA9IDEwMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gdW5wYWNrZWRFbnVtXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtPiB1bnBhY2tlZEVudW1fY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLkZPUkVJR05fRk9PIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHVucGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZEVudW0uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtPiBnZXRVbnBhY2tlZEVudW1MaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bT4odW5wYWNrZWRFbnVtXywgdW5wYWNrZWRFbnVtX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gdW5wYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRVbnBhY2tlZEVudW1Db3VudCgpIHsKICAgICAgcmV0dXJuIHVucGFja2VkRW51bV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gdW5wYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRFbnVtIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0VW5wYWNrZWRFbnVtKGludCBpbmRleCkgewogICAgICByZXR1cm4gdW5wYWNrZWRFbnVtX2NvbnZlcnRlcl8uY29udmVydCh1bnBhY2tlZEVudW1fLmdldChpbmRleCkpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bnBhY2tlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDkwLCB1bnBhY2tlZEludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5wYWNrZWRJbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCg5MSwgdW5wYWNrZWRJbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bnBhY2tlZFVpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoOTIsIHVucGFja2VkVWludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5wYWNrZWRVaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDY0KDkzLCB1bnBhY2tlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bnBhY2tlZFNpbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTSW50MzIoOTQsIHVucGFja2VkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5wYWNrZWRTaW50NjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlU0ludDY0KDk1LCB1bnBhY2tlZFNpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bnBhY2tlZEZpeGVkMzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMig5NiwgdW5wYWNrZWRGaXhlZDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5wYWNrZWRGaXhlZDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZpeGVkNjQoOTcsIHVucGFja2VkRml4ZWQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bnBhY2tlZFNmaXhlZDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNGaXhlZDMyKDk4LCB1bnBhY2tlZFNmaXhlZDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5wYWNrZWRTZml4ZWQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVTRml4ZWQ2NCg5OSwgdW5wYWNrZWRTZml4ZWQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bnBhY2tlZEZsb2F0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0KDEwMCwgdW5wYWNrZWRGbG9hdF8uZ2V0RmxvYXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5wYWNrZWREb3VibGVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRG91YmxlKDEwMSwgdW5wYWNrZWREb3VibGVfLmdldERvdWJsZShpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bnBhY2tlZEJvb2xfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgxMDIsIHVucGFja2VkQm9vbF8uZ2V0Qm9vbGVhbihpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bnBhY2tlZEVudW1fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgxMDMsIHVucGFja2VkRW51bV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bnBhY2tlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKHVucGFja2VkSW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0VW5wYWNrZWRJbnQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB1bnBhY2tlZEludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZU5vVGFnKHVucGFja2VkSW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFVucGFja2VkSW50NjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5wYWNrZWRVaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKHVucGFja2VkVWludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFVucGFja2VkVWludDMyTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHVucGFja2VkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQ2NFNpemVOb1RhZyh1bnBhY2tlZFVpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0VW5wYWNrZWRVaW50NjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdW5wYWNrZWRTaW50MzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlU0ludDMyU2l6ZU5vVGFnKHVucGFja2VkU2ludDMyXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFVucGFja2VkU2ludDMyTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHVucGFja2VkU2ludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVNJbnQ2NFNpemVOb1RhZyh1bnBhY2tlZFNpbnQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0VW5wYWNrZWRTaW50NjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFVucGFja2VkRml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRVbnBhY2tlZEZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFVucGFja2VkRml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRVbnBhY2tlZEZpeGVkNjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFVucGFja2VkU2ZpeGVkMzJMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0VW5wYWNrZWRTZml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0VW5wYWNrZWRTZml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRVbnBhY2tlZFNmaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDQgKiBnZXRVbnBhY2tlZEZsb2F0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFVucGFja2VkRmxvYXRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gOCAqIGdldFVucGFja2VkRG91YmxlTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFVucGFja2VkRG91YmxlTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDEgKiBnZXRVbnBhY2tlZEJvb2xMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0VW5wYWNrZWRCb29sTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHVucGFja2VkRW51bV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHVucGFja2VkRW51bV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiB1bnBhY2tlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMpIG9iajsKCiAgICAgIGlmICghZ2V0VW5wYWNrZWRJbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRVbnBhY2tlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVucGFja2VkSW50NjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0VW5wYWNrZWRJbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbnBhY2tlZFVpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRVbnBhY2tlZFVpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbnBhY2tlZFVpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRVbnBhY2tlZFVpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbnBhY2tlZFNpbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRVbnBhY2tlZFNpbnQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbnBhY2tlZFNpbnQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRVbnBhY2tlZFNpbnQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbnBhY2tlZEZpeGVkMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0VW5wYWNrZWRGaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVucGFja2VkRml4ZWQ2NExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRVbnBhY2tlZEZpeGVkNjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5wYWNrZWRTZml4ZWQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRVbnBhY2tlZFNmaXhlZDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVucGFja2VkU2ZpeGVkNjRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0VW5wYWNrZWRTZml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbnBhY2tlZEZsb2F0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFVucGFja2VkRmxvYXRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5wYWNrZWREb3VibGVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0VW5wYWNrZWREb3VibGVMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5wYWNrZWRCb29sTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFVucGFja2VkQm9vbExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCF1bnBhY2tlZEVudW1fLmVxdWFscyhvdGhlci51bnBhY2tlZEVudW1fKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChnZXRVbnBhY2tlZEludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVTlBBQ0tFRF9JTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VW5wYWNrZWRJbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRVbnBhY2tlZEludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVTlBBQ0tFRF9JTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VW5wYWNrZWRJbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRVbnBhY2tlZFVpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5QQUNLRURfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRVbnBhY2tlZFVpbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRVbnBhY2tlZFVpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5QQUNLRURfVUlOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRVbnBhY2tlZFVpbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRVbnBhY2tlZFNpbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5QQUNLRURfU0lOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRVbnBhY2tlZFNpbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRVbnBhY2tlZFNpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5QQUNLRURfU0lOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRVbnBhY2tlZFNpbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRVbnBhY2tlZEZpeGVkMzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVOUEFDS0VEX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFVucGFja2VkRml4ZWQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRVbnBhY2tlZEZpeGVkNjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVOUEFDS0VEX0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFVucGFja2VkRml4ZWQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRVbnBhY2tlZFNmaXhlZDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVTlBBQ0tFRF9TRklYRUQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VW5wYWNrZWRTZml4ZWQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRVbnBhY2tlZFNmaXhlZDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVTlBBQ0tFRF9TRklYRUQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VW5wYWNrZWRTZml4ZWQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRVbnBhY2tlZEZsb2F0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBVTlBBQ0tFRF9GTE9BVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0VW5wYWNrZWRGbG9hdExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRVbnBhY2tlZERvdWJsZUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgVU5QQUNLRURfRE9VQkxFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRVbnBhY2tlZERvdWJsZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRVbnBhY2tlZEJvb2xDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVOUEFDS0VEX0JPT0xfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFVucGFja2VkQm9vbExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRVbnBhY2tlZEVudW1Db3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFVOUEFDS0VEX0VOVU1fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHVucGFja2VkRW51bV8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBIG1lc3NhZ2Ugd2l0aCB0aGUgc2FtZSBmaWVsZHMgYXMgVGVzdFBhY2tlZFR5cGVzLCBidXQgd2l0aG91dCBwYWNraW5nLiBVc2VkCiAgICAgKiB0byB0ZXN0IHBhY2tlZCAmbHQ7LSZndDsgdW5wYWNrZWQgd2lyZSBjb21wYXRpYmlsaXR5LgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkVHlwZXN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICB1bnBhY2tlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHVucGFja2VkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHVucGFja2VkVWludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHVucGFja2VkVWludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICB1bnBhY2tlZFNpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICB1bnBhY2tlZFNpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgdW5wYWNrZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHVucGFja2VkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgdW5wYWNrZWRTZml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICB1bnBhY2tlZFNmaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICB1bnBhY2tlZEZsb2F0XyA9IGVtcHR5RmxvYXRMaXN0KCk7CiAgICAgICAgdW5wYWNrZWREb3VibGVfID0gZW1wdHlEb3VibGVMaXN0KCk7CiAgICAgICAgdW5wYWNrZWRCb29sXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICB1bnBhY2tlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFVucGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMgcmVzdWx0KSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICB1bnBhY2tlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QodW5wYWNrZWRFbnVtXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC51bnBhY2tlZEVudW1fID0gdW5wYWNrZWRFbnVtXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgdW5wYWNrZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnVucGFja2VkSW50MzJfID0gdW5wYWNrZWRJbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICB1bnBhY2tlZEludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQudW5wYWNrZWRJbnQ2NF8gPSB1bnBhY2tlZEludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHVucGFja2VkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQudW5wYWNrZWRVaW50MzJfID0gdW5wYWNrZWRVaW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgdW5wYWNrZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC51bnBhY2tlZFVpbnQ2NF8gPSB1bnBhY2tlZFVpbnQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICB1bnBhY2tlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnVucGFja2VkU2ludDMyXyA9IHVucGFja2VkU2ludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHVucGFja2VkU2ludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQudW5wYWNrZWRTaW50NjRfID0gdW5wYWNrZWRTaW50NjRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgdW5wYWNrZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQudW5wYWNrZWRGaXhlZDMyXyA9IHVucGFja2VkRml4ZWQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICB1bnBhY2tlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC51bnBhY2tlZEZpeGVkNjRfID0gdW5wYWNrZWRGaXhlZDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHVucGFja2VkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC51bnBhY2tlZFNmaXhlZDMyXyA9IHVucGFja2VkU2ZpeGVkMzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgdW5wYWNrZWRTZml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnVucGFja2VkU2ZpeGVkNjRfID0gdW5wYWNrZWRTZml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgICB1bnBhY2tlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQudW5wYWNrZWRGbG9hdF8gPSB1bnBhY2tlZEZsb2F0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICAgIHVucGFja2VkRG91YmxlXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQudW5wYWNrZWREb3VibGVfID0gdW5wYWNrZWREb3VibGVfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgICAgdW5wYWNrZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQudW5wYWNrZWRCb29sXyA9IHVucGFja2VkQm9vbF87CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRUeXBlcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmICghb3RoZXIudW5wYWNrZWRJbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAodW5wYWNrZWRJbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHVucGFja2VkSW50MzJfID0gb3RoZXIudW5wYWNrZWRJbnQzMl87CiAgICAgICAgICAgIHVucGFja2VkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICB1bnBhY2tlZEludDMyXy5hZGRBbGwob3RoZXIudW5wYWNrZWRJbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIudW5wYWNrZWRJbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAodW5wYWNrZWRJbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHVucGFja2VkSW50NjRfID0gb3RoZXIudW5wYWNrZWRJbnQ2NF87CiAgICAgICAgICAgIHVucGFja2VkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICB1bnBhY2tlZEludDY0Xy5hZGRBbGwob3RoZXIudW5wYWNrZWRJbnQ2NF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIudW5wYWNrZWRVaW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHVucGFja2VkVWludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgdW5wYWNrZWRVaW50MzJfID0gb3RoZXIudW5wYWNrZWRVaW50MzJfOwogICAgICAgICAgICB1bnBhY2tlZFVpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVVbnBhY2tlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICB1bnBhY2tlZFVpbnQzMl8uYWRkQWxsKG90aGVyLnVucGFja2VkVWludDMyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci51bnBhY2tlZFVpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAodW5wYWNrZWRVaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICB1bnBhY2tlZFVpbnQ2NF8gPSBvdGhlci51bnBhY2tlZFVpbnQ2NF87CiAgICAgICAgICAgIHVucGFja2VkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVVucGFja2VkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHVucGFja2VkVWludDY0Xy5hZGRBbGwob3RoZXIudW5wYWNrZWRVaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnVucGFja2VkU2ludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmICh1bnBhY2tlZFNpbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHVucGFja2VkU2ludDMyXyA9IG90aGVyLnVucGFja2VkU2ludDMyXzsKICAgICAgICAgICAgdW5wYWNrZWRTaW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgdW5wYWNrZWRTaW50MzJfLmFkZEFsbChvdGhlci51bnBhY2tlZFNpbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIudW5wYWNrZWRTaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHVucGFja2VkU2ludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgdW5wYWNrZWRTaW50NjRfID0gb3RoZXIudW5wYWNrZWRTaW50NjRfOwogICAgICAgICAgICB1bnBhY2tlZFNpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVVbnBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICB1bnBhY2tlZFNpbnQ2NF8uYWRkQWxsKG90aGVyLnVucGFja2VkU2ludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci51bnBhY2tlZEZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHVucGFja2VkRml4ZWQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHVucGFja2VkRml4ZWQzMl8gPSBvdGhlci51bnBhY2tlZEZpeGVkMzJfOwogICAgICAgICAgICB1bnBhY2tlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHVucGFja2VkRml4ZWQzMl8uYWRkQWxsKG90aGVyLnVucGFja2VkRml4ZWQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIudW5wYWNrZWRGaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmICh1bnBhY2tlZEZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICB1bnBhY2tlZEZpeGVkNjRfID0gb3RoZXIudW5wYWNrZWRGaXhlZDY0XzsKICAgICAgICAgICAgdW5wYWNrZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVVucGFja2VkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICB1bnBhY2tlZEZpeGVkNjRfLmFkZEFsbChvdGhlci51bnBhY2tlZEZpeGVkNjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnVucGFja2VkU2ZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHVucGFja2VkU2ZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICB1bnBhY2tlZFNmaXhlZDMyXyA9IG90aGVyLnVucGFja2VkU2ZpeGVkMzJfOwogICAgICAgICAgICB1bnBhY2tlZFNmaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVVucGFja2VkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgdW5wYWNrZWRTZml4ZWQzMl8uYWRkQWxsKG90aGVyLnVucGFja2VkU2ZpeGVkMzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnVucGFja2VkU2ZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHVucGFja2VkU2ZpeGVkNjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICB1bnBhY2tlZFNmaXhlZDY0XyA9IG90aGVyLnVucGFja2VkU2ZpeGVkNjRfOwogICAgICAgICAgICB1bnBhY2tlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVVucGFja2VkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgdW5wYWNrZWRTZml4ZWQ2NF8uYWRkQWxsKG90aGVyLnVucGFja2VkU2ZpeGVkNjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnVucGFja2VkRmxvYXRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHVucGFja2VkRmxvYXRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICB1bnBhY2tlZEZsb2F0XyA9IG90aGVyLnVucGFja2VkRmxvYXRfOwogICAgICAgICAgICB1bnBhY2tlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVVucGFja2VkRmxvYXRJc011dGFibGUoKTsKICAgICAgICAgICAgdW5wYWNrZWRGbG9hdF8uYWRkQWxsKG90aGVyLnVucGFja2VkRmxvYXRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnVucGFja2VkRG91YmxlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmICh1bnBhY2tlZERvdWJsZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHVucGFja2VkRG91YmxlXyA9IG90aGVyLnVucGFja2VkRG91YmxlXzsKICAgICAgICAgICAgdW5wYWNrZWREb3VibGVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICAgICAgdW5wYWNrZWREb3VibGVfLmFkZEFsbChvdGhlci51bnBhY2tlZERvdWJsZV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIudW5wYWNrZWRCb29sXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmICh1bnBhY2tlZEJvb2xfLmlzRW1wdHkoKSkgewogICAgICAgICAgICB1bnBhY2tlZEJvb2xfID0gb3RoZXIudW5wYWNrZWRCb29sXzsKICAgICAgICAgICAgdW5wYWNrZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVVucGFja2VkQm9vbElzTXV0YWJsZSgpOwogICAgICAgICAgICB1bnBhY2tlZEJvb2xfLmFkZEFsbChvdGhlci51bnBhY2tlZEJvb2xfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnVucGFja2VkRW51bV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAodW5wYWNrZWRFbnVtXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgdW5wYWNrZWRFbnVtXyA9IG90aGVyLnVucGFja2VkRW51bV87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVVucGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICB1bnBhY2tlZEVudW1fLmFkZEFsbChvdGhlci51bnBhY2tlZEVudW1fKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDcyMDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVVucGFja2VkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHVucGFja2VkSW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MjAKICAgICAgICAgICAgICBjYXNlIDcyMjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVVbnBhY2tlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHVucGFja2VkSW50MzJfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzIyCiAgICAgICAgICAgICAgY2FzZSA3Mjg6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgdW5wYWNrZWRJbnQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MjgKICAgICAgICAgICAgICBjYXNlIDczMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVVbnBhY2tlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHVucGFja2VkSW50NjRfLmFkZExvbmcoaW5wdXQucmVhZEludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDczMAogICAgICAgICAgICAgIGNhc2UgNzM2OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVVucGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB1bnBhY2tlZFVpbnQzMl8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDczNgogICAgICAgICAgICAgIGNhc2UgNzM4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVVucGFja2VkVWludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHVucGFja2VkVWludDMyXy5hZGRJbnQoaW5wdXQucmVhZFVJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MzgKICAgICAgICAgICAgICBjYXNlIDc0NDogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFVJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHVucGFja2VkVWludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0NAogICAgICAgICAgICAgIGNhc2UgNzQ2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVVucGFja2VkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHVucGFja2VkVWludDY0Xy5hZGRMb25nKGlucHV0LnJlYWRVSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQ2CiAgICAgICAgICAgICAgY2FzZSA3NTI6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFNJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHVucGFja2VkU2ludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzUyCiAgICAgICAgICAgICAgY2FzZSA3NTQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgdW5wYWNrZWRTaW50MzJfLmFkZEludChpbnB1dC5yZWFkU0ludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc1NAogICAgICAgICAgICAgIGNhc2UgNzYwOiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkU0ludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVVbnBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgdW5wYWNrZWRTaW50NjRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzYwCiAgICAgICAgICAgICAgY2FzZSA3NjI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgdW5wYWNrZWRTaW50NjRfLmFkZExvbmcoaW5wdXQucmVhZFNJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NjIKICAgICAgICAgICAgICBjYXNlIDc3MzogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB1bnBhY2tlZEZpeGVkMzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzMKICAgICAgICAgICAgICBjYXNlIDc3MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVVucGFja2VkRml4ZWQzMklzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICB1bnBhY2tlZEZpeGVkMzJfLmFkZEludChpbnB1dC5yZWFkRml4ZWQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzAKICAgICAgICAgICAgICBjYXNlIDc3NzogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEZpeGVkNjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVVucGFja2VkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgdW5wYWNrZWRGaXhlZDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc3NwogICAgICAgICAgICAgIGNhc2UgNzc4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRGaXhlZDY0SXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHVucGFja2VkRml4ZWQ2NF8uYWRkTG9uZyhpbnB1dC5yZWFkRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NzgKICAgICAgICAgICAgICBjYXNlIDc4OTogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkU0ZpeGVkMzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVVucGFja2VkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHVucGFja2VkU2ZpeGVkMzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3ODkKICAgICAgICAgICAgICBjYXNlIDc4NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVVucGFja2VkU2ZpeGVkMzJJc011dGFibGUoYWxsb2MgLyA0KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgdW5wYWNrZWRTZml4ZWQzMl8uYWRkSW50KGlucHV0LnJlYWRTRml4ZWQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3ODYKICAgICAgICAgICAgICBjYXNlIDc5MzogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFNGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVVbnBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB1bnBhY2tlZFNmaXhlZDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc5MwogICAgICAgICAgICAgIGNhc2UgNzk0OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRTZml4ZWQ2NElzTXV0YWJsZShhbGxvYyAvIDgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICB1bnBhY2tlZFNmaXhlZDY0Xy5hZGRMb25nKGlucHV0LnJlYWRTRml4ZWQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3OTQKICAgICAgICAgICAgICBjYXNlIDgwNTogewogICAgICAgICAgICAgICAgZmxvYXQgdiA9IGlucHV0LnJlYWRGbG9hdCgpOwogICAgICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgdW5wYWNrZWRGbG9hdF8uYWRkRmxvYXQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODA1CiAgICAgICAgICAgICAgY2FzZSA4MDI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVVbnBhY2tlZEZsb2F0SXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHVucGFja2VkRmxvYXRfLmFkZEZsb2F0KGlucHV0LnJlYWRGbG9hdCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDIKICAgICAgICAgICAgICBjYXNlIDgwOTogewogICAgICAgICAgICAgICAgZG91YmxlIHYgPSBpbnB1dC5yZWFkRG91YmxlKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVVbnBhY2tlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgdW5wYWNrZWREb3VibGVfLmFkZERvdWJsZSh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDkKICAgICAgICAgICAgICBjYXNlIDgxMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVVucGFja2VkRG91YmxlSXNNdXRhYmxlKGFsbG9jIC8gOCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHVucGFja2VkRG91YmxlXy5hZGREb3VibGUoaW5wdXQucmVhZERvdWJsZSgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MTAKICAgICAgICAgICAgICBjYXNlIDgxNjogewogICAgICAgICAgICAgICAgYm9vbGVhbiB2ID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGVuc3VyZVVucGFja2VkQm9vbElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgdW5wYWNrZWRCb29sXy5hZGRCb29sZWFuKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgxNgogICAgICAgICAgICAgIGNhc2UgODE4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRCb29sSXNNdXRhYmxlKGFsbG9jIC8gMSk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHVucGFja2VkQm9vbF8uYWRkQm9vbGVhbihpbnB1dC5yZWFkQm9vbCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MTgKICAgICAgICAgICAgICBjYXNlIDgyNDogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMTAzLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlVW5wYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHVucGFja2VkRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODI0CiAgICAgICAgICAgICAgY2FzZSA4MjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMTAzLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZVVucGFja2VkRW51bUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIHVucGFja2VkRW51bV8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MjYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgdW5wYWNrZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVVucGFja2VkSW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCF1bnBhY2tlZEludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgdW5wYWNrZWRJbnQzMl8gPSBtYWtlTXV0YWJsZUNvcHkodW5wYWNrZWRJbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHVucGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHVucGFja2VkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRVbnBhY2tlZEludDMyTGlzdCgpIHsKICAgICAgICB1bnBhY2tlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHVucGFja2VkSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB1bnBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB1bnBhY2tlZEludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRVbnBhY2tlZEludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHVucGFja2VkSW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgdW5wYWNrZWRfaW50MzIgPSA5MCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHVucGFja2VkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRVbnBhY2tlZEludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiB1bnBhY2tlZEludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB1bnBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdW5wYWNrZWRJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFVucGFja2VkSW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVVbnBhY2tlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgdW5wYWNrZWRJbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB1bnBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHVucGFja2VkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRVbnBhY2tlZEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVVbnBhY2tlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgdW5wYWNrZWRJbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHVucGFja2VkX2ludDMyID0gOTAgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHVucGFja2VkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxVbnBhY2tlZEludDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlVW5wYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCB1bnBhY2tlZEludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiB1bnBhY2tlZF9pbnQzMiA9IDkwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVucGFja2VkSW50MzIoKSB7CiAgICAgICAgdW5wYWNrZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCB1bnBhY2tlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVVucGFja2VkSW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCF1bnBhY2tlZEludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgdW5wYWNrZWRJbnQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkodW5wYWNrZWRJbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHVucGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHVucGFja2VkSW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRVbnBhY2tlZEludDY0TGlzdCgpIHsKICAgICAgICB1bnBhY2tlZEludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHVucGFja2VkSW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCB1bnBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB1bnBhY2tlZEludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRVbnBhY2tlZEludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHVucGFja2VkSW50NjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgdW5wYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHVucGFja2VkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0VW5wYWNrZWRJbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gdW5wYWNrZWRJbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHVucGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB1bnBhY2tlZEludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VW5wYWNrZWRJbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVVbnBhY2tlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgdW5wYWNrZWRJbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgdW5wYWNrZWRfaW50NjQgPSA5MSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB1bnBhY2tlZEludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkVW5wYWNrZWRJbnQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVVucGFja2VkSW50NjRJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZEludDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHVucGFja2VkX2ludDY0ID0gOTEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHVucGFja2VkSW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxVbnBhY2tlZEludDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlVW5wYWNrZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCB1bnBhY2tlZEludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCB1bnBhY2tlZF9pbnQ2NCA9IDkxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVucGFja2VkSW50NjQoKSB7CiAgICAgICAgdW5wYWNrZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCB1bnBhY2tlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVVucGFja2VkVWludDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghdW5wYWNrZWRVaW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICB1bnBhY2tlZFVpbnQzMl8gPSBtYWtlTXV0YWJsZUNvcHkodW5wYWNrZWRVaW50MzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50MzIgdW5wYWNrZWRfdWludDMyID0gOTIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHVucGFja2VkVWludDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0VW5wYWNrZWRVaW50MzJMaXN0KCkgewogICAgICAgIHVucGFja2VkVWludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHVucGFja2VkVWludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHVucGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB1bnBhY2tlZFVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5wYWNrZWRVaW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gdW5wYWNrZWRVaW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHVucGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRVaW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRVbnBhY2tlZFVpbnQzMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gdW5wYWNrZWRVaW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiB1bnBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHVucGFja2VkVWludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VW5wYWNrZWRVaW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVVbnBhY2tlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHVucGFja2VkVWludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiB1bnBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB1bnBhY2tlZFVpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFVucGFja2VkVWludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVVbnBhY2tlZFVpbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHVucGFja2VkVWludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDMyIHVucGFja2VkX3VpbnQzMiA9IDkyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSB1bnBhY2tlZFVpbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFVucGFja2VkVWludDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlVW5wYWNrZWRVaW50MzJJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgdW5wYWNrZWRVaW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQzMiB1bnBhY2tlZF91aW50MzIgPSA5MiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVbnBhY2tlZFVpbnQzMigpIHsKICAgICAgICB1bnBhY2tlZFVpbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCB1bnBhY2tlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVVbnBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXVucGFja2VkVWludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgdW5wYWNrZWRVaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHVucGFja2VkVWludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHVucGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZFVpbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFVucGFja2VkVWludDY0TGlzdCgpIHsKICAgICAgICB1bnBhY2tlZFVpbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiB1bnBhY2tlZFVpbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCB1bnBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRVaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFVucGFja2VkVWludDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHVucGFja2VkVWludDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCB1bnBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHVucGFja2VkVWludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFVucGFja2VkVWludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiB1bnBhY2tlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCB1bnBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHVucGFja2VkVWludDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VW5wYWNrZWRVaW50NjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlVW5wYWNrZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZFVpbnQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHVucGFja2VkX3VpbnQ2NCA9IDkzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHVucGFja2VkVWludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkVW5wYWNrZWRVaW50NjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVVbnBhY2tlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHVucGFja2VkVWludDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCB1bnBhY2tlZF91aW50NjQgPSA5MyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgdW5wYWNrZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxVbnBhY2tlZFVpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVVucGFja2VkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHVucGFja2VkVWludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgdW5wYWNrZWRfdWludDY0ID0gOTMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5wYWNrZWRVaW50NjQoKSB7CiAgICAgICAgdW5wYWNrZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgdW5wYWNrZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVVbnBhY2tlZFNpbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXVucGFja2VkU2ludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgdW5wYWNrZWRTaW50MzJfID0gbWFrZU11dGFibGVDb3B5KHVucGFja2VkU2ludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHVucGFja2VkX3NpbnQzMiA9IDk0IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZFNpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFVucGFja2VkU2ludDMyTGlzdCgpIHsKICAgICAgICB1bnBhY2tlZFNpbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiB1bnBhY2tlZFNpbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiB1bnBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRTaW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFVucGFja2VkU2ludDMyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHVucGFja2VkU2ludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiB1bnBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHVucGFja2VkU2ludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5wYWNrZWRTaW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHVucGFja2VkU2ludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgdW5wYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB1bnBhY2tlZFNpbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFVucGFja2VkU2ludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlVW5wYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZFNpbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgdW5wYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdW5wYWNrZWRTaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRVbnBhY2tlZFNpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlVW5wYWNrZWRTaW50MzJJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZFNpbnQzMl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiB1bnBhY2tlZF9zaW50MzIgPSA5NCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgdW5wYWNrZWRTaW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxVbnBhY2tlZFNpbnQzMigKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVVucGFja2VkU2ludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHVucGFja2VkU2ludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgdW5wYWNrZWRfc2ludDMyID0gOTQgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5wYWNrZWRTaW50MzIoKSB7CiAgICAgICAgdW5wYWNrZWRTaW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgdW5wYWNrZWRTaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlVW5wYWNrZWRTaW50NjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCF1bnBhY2tlZFNpbnQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHVucGFja2VkU2ludDY0XyA9IG1ha2VNdXRhYmxlQ29weSh1bnBhY2tlZFNpbnQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCB1bnBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWRTaW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRVbnBhY2tlZFNpbnQ2NExpc3QoKSB7CiAgICAgICAgdW5wYWNrZWRTaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gdW5wYWNrZWRTaW50NjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgdW5wYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkU2ludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRVbnBhY2tlZFNpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiB1bnBhY2tlZFNpbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgdW5wYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSB1bnBhY2tlZFNpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRVbnBhY2tlZFNpbnQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gdW5wYWNrZWRTaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgdW5wYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB1bnBhY2tlZFNpbnQ2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFVucGFja2VkU2ludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVVucGFja2VkU2ludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgdW5wYWNrZWRTaW50NjRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQ2NCB1bnBhY2tlZF9zaW50NjQgPSA5NSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB1bnBhY2tlZFNpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFVucGFja2VkU2ludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlVW5wYWNrZWRTaW50NjRJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZFNpbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50NjQgdW5wYWNrZWRfc2ludDY0ID0gOTUgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHVucGFja2VkU2ludDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsVW5wYWNrZWRTaW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVVbnBhY2tlZFNpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCB1bnBhY2tlZFNpbnQ2NF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDY0IHVucGFja2VkX3NpbnQ2NCA9IDk1IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVucGFja2VkU2ludDY0KCkgewogICAgICAgIHVucGFja2VkU2ludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHVucGFja2VkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVVucGFja2VkRml4ZWQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXVucGFja2VkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHVucGFja2VkRml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkodW5wYWNrZWRGaXhlZDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlVW5wYWNrZWRGaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghdW5wYWNrZWRGaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgdW5wYWNrZWRGaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weSh1bnBhY2tlZEZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiB1bnBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHVucGFja2VkRml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFVucGFja2VkRml4ZWQzMkxpc3QoKSB7CiAgICAgICAgdW5wYWNrZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHVucGFja2VkRml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgdW5wYWNrZWRfZml4ZWQzMiA9IDk2IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB1bnBhY2tlZEZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFVucGFja2VkRml4ZWQzMkNvdW50KCkgewogICAgICAgIHJldHVybiB1bnBhY2tlZEZpeGVkMzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiB1bnBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSB1bnBhY2tlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRVbnBhY2tlZEZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHVucGFja2VkRml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiB1bnBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB1bnBhY2tlZEZpeGVkMzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRVbnBhY2tlZEZpeGVkMzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVVbnBhY2tlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZEZpeGVkMzJfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiB1bnBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdW5wYWNrZWRGaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkVW5wYWNrZWRGaXhlZDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVVbnBhY2tlZEZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZEZpeGVkMzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHVucGFja2VkX2ZpeGVkMzIgPSA5NiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgdW5wYWNrZWRGaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsVW5wYWNrZWRGaXhlZDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlVW5wYWNrZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHVucGFja2VkRml4ZWQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiB1bnBhY2tlZF9maXhlZDMyID0gOTYgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5wYWNrZWRGaXhlZDMyKCkgewogICAgICAgIHVucGFja2VkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCB1bnBhY2tlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlVW5wYWNrZWRGaXhlZDY0SXNNdXRhYmxlKCkgewogICAgICAgIGlmICghdW5wYWNrZWRGaXhlZDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgdW5wYWNrZWRGaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weSh1bnBhY2tlZEZpeGVkNjRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVVbnBhY2tlZEZpeGVkNjRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCF1bnBhY2tlZEZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICB1bnBhY2tlZEZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHVucGFja2VkRml4ZWQ2NF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHVucGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWRGaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0VW5wYWNrZWRGaXhlZDY0TGlzdCgpIHsKICAgICAgICB1bnBhY2tlZEZpeGVkNjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gdW5wYWNrZWRGaXhlZDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCB1bnBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkRml4ZWQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5wYWNrZWRGaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHVucGFja2VkRml4ZWQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHVucGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHVucGFja2VkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRVbnBhY2tlZEZpeGVkNjQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHVucGFja2VkRml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgdW5wYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdW5wYWNrZWRGaXhlZDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VW5wYWNrZWRGaXhlZDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVVucGFja2VkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIHVucGFja2VkRml4ZWQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCB1bnBhY2tlZF9maXhlZDY0ID0gOTcgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdW5wYWNrZWRGaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkVW5wYWNrZWRGaXhlZDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlVW5wYWNrZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgdW5wYWNrZWRGaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgdW5wYWNrZWRfZml4ZWQ2NCA9IDk3IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSB1bnBhY2tlZEZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxVbnBhY2tlZEZpeGVkNjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVVbnBhY2tlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgdW5wYWNrZWRGaXhlZDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHVucGFja2VkX2ZpeGVkNjQgPSA5NyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVbnBhY2tlZEZpeGVkNjQoKSB7CiAgICAgICAgdW5wYWNrZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHVucGFja2VkU2ZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVVbnBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCkgewogICAgICAgIGlmICghdW5wYWNrZWRTZml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHVucGFja2VkU2ZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHVucGFja2VkU2ZpeGVkMzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVVbnBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghdW5wYWNrZWRTZml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHVucGFja2VkU2ZpeGVkMzJfID0gbWFrZU11dGFibGVDb3B5KHVucGFja2VkU2ZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgdW5wYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWRTZml4ZWQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFVucGFja2VkU2ZpeGVkMzJMaXN0KCkgewogICAgICAgIHVucGFja2VkU2ZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gdW5wYWNrZWRTZml4ZWQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHVucGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkU2ZpeGVkMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFVucGFja2VkU2ZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gdW5wYWNrZWRTZml4ZWQzMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQzMiB1bnBhY2tlZF9zZml4ZWQzMiA9IDk4IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRTZml4ZWQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFVucGFja2VkU2ZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHVucGFja2VkU2ZpeGVkMzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHVucGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB1bnBhY2tlZFNmaXhlZDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VW5wYWNrZWRTZml4ZWQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVVucGFja2VkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZFNmaXhlZDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHVucGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdW5wYWNrZWRTZml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFVucGFja2VkU2ZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVVucGFja2VkU2ZpeGVkMzJJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZFNmaXhlZDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkMzIgdW5wYWNrZWRfc2ZpeGVkMzIgPSA5OCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgdW5wYWNrZWRTZml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFVucGFja2VkU2ZpeGVkMzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVVbnBhY2tlZFNmaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHVucGFja2VkU2ZpeGVkMzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDMyIHVucGFja2VkX3NmaXhlZDMyID0gOTggW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5wYWNrZWRTZml4ZWQzMigpIHsKICAgICAgICB1bnBhY2tlZFNmaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHVucGFja2VkU2ZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlVW5wYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXVucGFja2VkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICB1bnBhY2tlZFNmaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weSh1bnBhY2tlZFNmaXhlZDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlVW5wYWNrZWRTZml4ZWQ2NElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXVucGFja2VkU2ZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICB1bnBhY2tlZFNmaXhlZDY0XyA9IG1ha2VNdXRhYmxlQ29weSh1bnBhY2tlZFNmaXhlZDY0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHVucGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHVucGFja2VkU2ZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRVbnBhY2tlZFNmaXhlZDY0TGlzdCgpIHsKICAgICAgICB1bnBhY2tlZFNmaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHVucGFja2VkU2ZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCB1bnBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB1bnBhY2tlZFNmaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRVbnBhY2tlZFNmaXhlZDY0Q291bnQoKSB7CiAgICAgICAgcmV0dXJuIHVucGFja2VkU2ZpeGVkNjRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgdW5wYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHVucGFja2VkU2ZpeGVkNjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0VW5wYWNrZWRTZml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gdW5wYWNrZWRTZml4ZWQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHVucGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB1bnBhY2tlZFNmaXhlZDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VW5wYWNrZWRTZml4ZWQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVVbnBhY2tlZFNmaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgdW5wYWNrZWRTZml4ZWQ2NF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ZpeGVkNjQgdW5wYWNrZWRfc2ZpeGVkNjQgPSA5OSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB1bnBhY2tlZFNmaXhlZDY0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkVW5wYWNrZWRTZml4ZWQ2NChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVVucGFja2VkU2ZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZFNmaXhlZDY0Xy5hZGRMb25nKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNmaXhlZDY0IHVucGFja2VkX3NmaXhlZDY0ID0gOTkgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHVucGFja2VkU2ZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxVbnBhY2tlZFNmaXhlZDY0KAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlVW5wYWNrZWRTZml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCB1bnBhY2tlZFNmaXhlZDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzZml4ZWQ2NCB1bnBhY2tlZF9zZml4ZWQ2NCA9IDk5IFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVucGFja2VkU2ZpeGVkNjQoKSB7CiAgICAgICAgdW5wYWNrZWRTZml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IHVucGFja2VkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVVucGFja2VkRmxvYXRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCF1bnBhY2tlZEZsb2F0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgdW5wYWNrZWRGbG9hdF8gPSBtYWtlTXV0YWJsZUNvcHkodW5wYWNrZWRGbG9hdF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVVucGFja2VkRmxvYXRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCF1bnBhY2tlZEZsb2F0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgdW5wYWNrZWRGbG9hdF8gPSBtYWtlTXV0YWJsZUNvcHkodW5wYWNrZWRGbG9hdF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCB1bnBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWRGbG9hdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRVbnBhY2tlZEZsb2F0TGlzdCgpIHsKICAgICAgICB1bnBhY2tlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHVucGFja2VkRmxvYXRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCB1bnBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRGbG9hdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0VW5wYWNrZWRGbG9hdENvdW50KCkgewogICAgICAgIHJldHVybiB1bnBhY2tlZEZsb2F0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHVucGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgdW5wYWNrZWRGbG9hdCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgZmxvYXQgZ2V0VW5wYWNrZWRGbG9hdChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gdW5wYWNrZWRGbG9hdF8uZ2V0RmxvYXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCB1bnBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHVucGFja2VkRmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRVbnBhY2tlZEZsb2F0KAogICAgICAgICAgaW50IGluZGV4LCBmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVVbnBhY2tlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgdW5wYWNrZWRGbG9hdF8uc2V0RmxvYXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHVucGFja2VkX2Zsb2F0ID0gMTAwIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHVucGFja2VkRmxvYXQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRVbnBhY2tlZEZsb2F0KGZsb2F0IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVVucGFja2VkRmxvYXRJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZEZsb2F0Xy5hZGRGbG9hdCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCB1bnBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgdW5wYWNrZWRGbG9hdCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFVucGFja2VkRmxvYXQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5GbG9hdD4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlVW5wYWNrZWRGbG9hdElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCB1bnBhY2tlZEZsb2F0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCB1bnBhY2tlZF9mbG9hdCA9IDEwMCBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVbnBhY2tlZEZsb2F0KCkgewogICAgICAgIHVucGFja2VkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDQwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Eb3VibGVMaXN0IHVucGFja2VkRG91YmxlXyA9IGVtcHR5RG91YmxlTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlVW5wYWNrZWREb3VibGVJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCF1bnBhY2tlZERvdWJsZV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHVucGFja2VkRG91YmxlXyA9IG1ha2VNdXRhYmxlQ29weSh1bnBhY2tlZERvdWJsZV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVVucGFja2VkRG91YmxlSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghdW5wYWNrZWREb3VibGVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICB1bnBhY2tlZERvdWJsZV8gPSBtYWtlTXV0YWJsZUNvcHkodW5wYWNrZWREb3VibGVfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHVucGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgdW5wYWNrZWREb3VibGUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4KICAgICAgICAgIGdldFVucGFja2VkRG91YmxlTGlzdCgpIHsKICAgICAgICB1bnBhY2tlZERvdWJsZV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiB1bnBhY2tlZERvdWJsZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSB1bnBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHVucGFja2VkRG91YmxlLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRVbnBhY2tlZERvdWJsZUNvdW50KCkgewogICAgICAgIHJldHVybiB1bnBhY2tlZERvdWJsZV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgdW5wYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgdW5wYWNrZWREb3VibGUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGRvdWJsZSBnZXRVbnBhY2tlZERvdWJsZShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gdW5wYWNrZWREb3VibGVfLmdldERvdWJsZShpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGRvdWJsZSB1bnBhY2tlZF9kb3VibGUgPSAxMDEgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB1bnBhY2tlZERvdWJsZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFVucGFja2VkRG91YmxlKAogICAgICAgICAgaW50IGluZGV4LCBkb3VibGUgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlVW5wYWNrZWREb3VibGVJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZERvdWJsZV8uc2V0RG91YmxlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgdW5wYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHVucGFja2VkRG91YmxlIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkVW5wYWNrZWREb3VibGUoZG91YmxlIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVVucGFja2VkRG91YmxlSXNNdXRhYmxlKCk7CiAgICAgICAgdW5wYWNrZWREb3VibGVfLmFkZERvdWJsZSh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBkb3VibGUgdW5wYWNrZWRfZG91YmxlID0gMTAxIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSB1bnBhY2tlZERvdWJsZSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFVucGFja2VkRG91YmxlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuRG91YmxlPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVVbnBhY2tlZERvdWJsZUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCB1bnBhY2tlZERvdWJsZV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZG91YmxlIHVucGFja2VkX2RvdWJsZSA9IDEwMSBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJVbnBhY2tlZERvdWJsZSgpIHsKICAgICAgICB1bnBhY2tlZERvdWJsZV8gPSBlbXB0eURvdWJsZUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDgwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCB1bnBhY2tlZEJvb2xfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlVW5wYWNrZWRCb29sSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghdW5wYWNrZWRCb29sXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgdW5wYWNrZWRCb29sXyA9IG1ha2VNdXRhYmxlQ29weSh1bnBhY2tlZEJvb2xfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVVbnBhY2tlZEJvb2xJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCF1bnBhY2tlZEJvb2xfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICB1bnBhY2tlZEJvb2xfID0gbWFrZU11dGFibGVDb3B5KHVucGFja2VkQm9vbF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHVucGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHVucGFja2VkQm9vbC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldFVucGFja2VkQm9vbExpc3QoKSB7CiAgICAgICAgdW5wYWNrZWRCb29sXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHVucGFja2VkQm9vbF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgdW5wYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdW5wYWNrZWRCb29sLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRVbnBhY2tlZEJvb2xDb3VudCgpIHsKICAgICAgICByZXR1cm4gdW5wYWNrZWRCb29sXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgdW5wYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHVucGFja2VkQm9vbCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRVbnBhY2tlZEJvb2woaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHVucGFja2VkQm9vbF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgdW5wYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHVucGFja2VkQm9vbCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFVucGFja2VkQm9vbCgKICAgICAgICAgIGludCBpbmRleCwgYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVVbnBhY2tlZEJvb2xJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZEJvb2xfLnNldEJvb2xlYW4oaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgdW5wYWNrZWRfYm9vbCA9IDEwMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB1bnBhY2tlZEJvb2wgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRVbnBhY2tlZEJvb2woYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVVbnBhY2tlZEJvb2xJc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZEJvb2xfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCB1bnBhY2tlZF9ib29sID0gMTAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSB1bnBhY2tlZEJvb2wgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxVbnBhY2tlZEJvb2woCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVVbnBhY2tlZEJvb2xJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgdW5wYWNrZWRCb29sXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHVucGFja2VkX2Jvb2wgPSAxMDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVW5wYWNrZWRCb29sKCkgewogICAgICAgIHVucGFja2VkQm9vbF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiB1bnBhY2tlZEVudW1fID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVVbnBhY2tlZEVudW1Jc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgdW5wYWNrZWRFbnVtXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPih1bnBhY2tlZEVudW1fKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSB1bnBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB1bnBhY2tlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bT4gZ2V0VW5wYWNrZWRFbnVtTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtPih1bnBhY2tlZEVudW1fLCB1bnBhY2tlZEVudW1fY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSB1bnBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB1bnBhY2tlZEVudW0uCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFVucGFja2VkRW51bUNvdW50KCkgewogICAgICAgIHJldHVybiB1bnBhY2tlZEVudW1fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIHVucGFja2VkX2VudW0gPSAxMDMgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSB1bnBhY2tlZEVudW0gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0VW5wYWNrZWRFbnVtKGludCBpbmRleCkgewogICAgICAgIHJldHVybiB1bnBhY2tlZEVudW1fY29udmVydGVyXy5jb252ZXJ0KHVucGFja2VkRW51bV8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSB1bnBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdW5wYWNrZWRFbnVtIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VW5wYWNrZWRFbnVtKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVVbnBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICB1bnBhY2tlZEVudW1fLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gdW5wYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB1bnBhY2tlZEVudW0gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRVbnBhY2tlZEVudW0ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlVW5wYWNrZWRFbnVtSXNNdXRhYmxlKCk7CiAgICAgICAgdW5wYWNrZWRFbnVtXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gdW5wYWNrZWRfZW51bSA9IDEwMyBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgdW5wYWNrZWRFbnVtIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsVW5wYWNrZWRFbnVtKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVVbnBhY2tlZEVudW1Jc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHVucGFja2VkRW51bV8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSB1bnBhY2tlZF9lbnVtID0gMTAzIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclVucGFja2VkRW51bSgpIHsKICAgICAgICB1bnBhY2tlZEVudW1fID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNrZWRUeXBlcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkVHlwZXMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZFR5cGVzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VW5wYWNrZWRUeXBlcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0VW5wYWNrZWRUeXBlcz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RVbnBhY2tlZFR5cGVzIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFVucGFja2VkVHlwZXM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFVucGFja2VkVHlwZXM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkVHlwZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0UGFja2VkRXh0ZW5zaW9uc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxUZXN0UGFja2VkRXh0ZW5zaW9ucz4gewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9uc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RQYWNrZWRFeHRlbnNpb25zIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZU1lc3NhZ2U8CiAgICAgICAgVGVzdFBhY2tlZEV4dGVuc2lvbnM+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucykKICAgICAgVGVzdFBhY2tlZEV4dGVuc2lvbnNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RQYWNrZWRFeHRlbnNpb25zLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RQYWNrZWRFeHRlbnNpb25zKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMsID8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RQYWNrZWRFeHRlbnNpb25zKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RQYWNrZWRFeHRlbnNpb25zKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhY2tlZEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFja2VkRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuRXh0ZW5kYWJsZU1lc3NhZ2U8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucz4uRXh0ZW5zaW9uV3JpdGVyCiAgICAgICAgICBleHRlbnNpb25Xcml0ZXIgPSBuZXdFeHRlbnNpb25Xcml0ZXIoKTsKICAgICAgZXh0ZW5zaW9uV3JpdGVyLndyaXRlVW50aWwoNTM2ODcwOTEyLCBvdXRwdXQpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBleHRlbnNpb25zU2VyaWFsaXplZFNpemUoKTsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucyBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFeHRlbnNpb25zKSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEV4dGVuc2lvbkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRFeHRlbnNpb25GaWVsZHMoKSkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSBoYXNoRmllbGRzKGhhc2gsIGdldEV4dGVuc2lvbkZpZWxkcygpKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9uc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMsIEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNpb25zKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhY2tlZEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhY2tlZEV4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFja2VkRXh0ZW5zaW9uc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFeHRlbnNpb25zIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnModGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMsIFR5cGU+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucywgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucywgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFeHRlbnNpb25zLCBUPiBleHRlbnNpb24pIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFeHRlbnNpb25zKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFeHRlbnNpb25zKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvbnMpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFeHRlbnNpb25zIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UGFja2VkRXh0ZW5zaW9ucz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0UGFja2VkRXh0ZW5zaW9ucz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RQYWNrZWRFeHRlbnNpb25zIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFBhY2tlZEV4dGVuc2lvbnM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFBhY2tlZEV4dGVuc2lvbnM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0VW5wYWNrZWRFeHRlbnNpb25zT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLgogICAgICAgICAgRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXI8VGVzdFVucGFja2VkRXh0ZW5zaW9ucz4gewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNrZWRFeHRlbnNpb25zfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFVucGFja2VkRXh0ZW5zaW9ucyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVNZXNzYWdlPAogICAgICAgIFRlc3RVbnBhY2tlZEV4dGVuc2lvbnM+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNrZWRFeHRlbnNpb25zKQogICAgICBUZXN0VW5wYWNrZWRFeHRlbnNpb25zT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0VW5wYWNrZWRFeHRlbnNpb25zLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RVbnBhY2tlZEV4dGVuc2lvbnMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0VW5wYWNrZWRFeHRlbnNpb25zKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RVbnBhY2tlZEV4dGVuc2lvbnMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VW5wYWNrZWRFeHRlbnNpb25zX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFVucGFja2VkRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLkV4dGVuZGFibGVNZXNzYWdlPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucz4uRXh0ZW5zaW9uV3JpdGVyCiAgICAgICAgICBleHRlbnNpb25Xcml0ZXIgPSBuZXdFeHRlbnNpb25Xcml0ZXIoKTsKICAgICAgZXh0ZW5zaW9uV3JpdGVyLndyaXRlVW50aWwoNTM2ODcwOTEyLCBvdXRwdXQpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBleHRlbnNpb25zU2VyaWFsaXplZFNpemUoKTsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zKSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldEV4dGVuc2lvbkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRFeHRlbnNpb25GaWVsZHMoKSkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSBoYXNoRmllbGRzKGhhc2gsIGdldEV4dGVuc2lvbkZpZWxkcygpKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZEV4dGVuc2lvbnN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMsIEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFVucGFja2VkRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnModGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucywgVHlwZT4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBhZGRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucywgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMsIFQ+IGV4dGVuc2lvbikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckV4dGVuc2lvbihleHRlbnNpb24pOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucyBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VFeHRlbnNpb25GaWVsZHMob3RoZXIpOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkRXh0ZW5zaW9ucykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkRXh0ZW5zaW9ucykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbnBhY2tlZEV4dGVuc2lvbnM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFVucGFja2VkRXh0ZW5zaW9ucz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RVbnBhY2tlZEV4dGVuc2lvbnMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VW5wYWNrZWRFeHRlbnNpb25zPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RVbnBhY2tlZEV4dGVuc2lvbnM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3REeW5hbWljRXh0ZW5zaW9uc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIHNjYWxhcl9leHRlbnNpb24gPSAyMDAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc2NhbGFyRXh0ZW5zaW9uIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTY2FsYXJFeHRlbnNpb24oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBzY2FsYXJfZXh0ZW5zaW9uID0gMjAwMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzY2FsYXJFeHRlbnNpb24uCiAgICAgKi8KICAgIGludCBnZXRTY2FsYXJFeHRlbnNpb24oKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBlbnVtX2V4dGVuc2lvbiA9IDIwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBlbnVtRXh0ZW5zaW9uIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNFbnVtRXh0ZW5zaW9uKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBlbnVtX2V4dGVuc2lvbiA9IDIwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZW51bUV4dGVuc2lvbi4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBnZXRFbnVtRXh0ZW5zaW9uKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNFbnVtVHlwZSBkeW5hbWljX2VudW1fZXh0ZW5zaW9uID0gMjAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR5bmFtaWNFbnVtRXh0ZW5zaW9uIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEeW5hbWljRW51bUV4dGVuc2lvbigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNFbnVtVHlwZSBkeW5hbWljX2VudW1fZXh0ZW5zaW9uID0gMjAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkeW5hbWljRW51bUV4dGVuc2lvbi4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY0VudW1UeXBlIGdldER5bmFtaWNFbnVtRXh0ZW5zaW9uKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbWVzc2FnZV9leHRlbnNpb24gPSAyMDAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZUV4dGVuc2lvbiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTWVzc2FnZUV4dGVuc2lvbigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbWVzc2FnZV9leHRlbnNpb24gPSAyMDAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG1lc3NhZ2VFeHRlbnNpb24uCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0TWVzc2FnZUV4dGVuc2lvbigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbWVzc2FnZV9leHRlbnNpb24gPSAyMDAzOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRNZXNzYWdlRXh0ZW5zaW9uT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBkeW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uID0gMjAwNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNEeW5hbWljTWVzc2FnZUV4dGVuc2lvbigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBkeW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uID0gMjAwNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbi4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIGdldER5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIGR5bmFtaWNfbWVzc2FnZV9leHRlbnNpb24gPSAyMDA0OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlT3JCdWlsZGVyIGdldER5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfZXh0ZW5zaW9uID0gMjAwNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEV4dGVuc2lvbi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZEV4dGVuc2lvbkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2V4dGVuc2lvbiA9IDIwMDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRFeHRlbnNpb24uCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEV4dGVuc2lvbkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9leHRlbnNpb24gPSAyMDA1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRFeHRlbnNpb24gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkRXh0ZW5zaW9uKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9leHRlbnNpb24gPSAyMDA1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZEV4dGVuc2lvbiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkRXh0ZW5zaW9uQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfZXh0ZW5zaW9uID0gMjAwNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRXh0ZW5zaW9uLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkRXh0ZW5zaW9uTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX2V4dGVuc2lvbiA9IDIwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEV4dGVuc2lvbi4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEV4dGVuc2lvbkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfZXh0ZW5zaW9uID0gMjAwNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRFeHRlbnNpb24gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkRXh0ZW5zaW9uKGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVXNlZCBieSBFeHRlbnNpb25TZXRUZXN0L0R5bmFtaWNFeHRlbnNpb25zLiAgVGhlIHRlc3QgYWN0dWFsbHkgYnVpbGRzCiAgICogYSBzZXQgb2YgZXh0ZW5zaW9ucyB0byBUZXN0QWxsRXh0ZW5zaW9ucyBkeW5hbWljYWxseSwgYmFzZWQgb24gdGhlIGZpZWxkcwogICAqIG9mIHRoaXMgbWVzc2FnZSB0eXBlLgogICAqIDwvcHJlPgogICAqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdER5bmFtaWNFeHRlbnNpb25zIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5zaW9ucykKICAgICAgVGVzdER5bmFtaWNFeHRlbnNpb25zT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0RHluYW1pY0V4dGVuc2lvbnMubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdER5bmFtaWNFeHRlbnNpb25zKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdER5bmFtaWNFeHRlbnNpb25zKCkgewogICAgICBlbnVtRXh0ZW5zaW9uXyA9IDQ7CiAgICAgIGR5bmFtaWNFbnVtRXh0ZW5zaW9uXyA9IDIyMDA7CiAgICAgIHJlcGVhdGVkRXh0ZW5zaW9uXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHBhY2tlZEV4dGVuc2lvbl8gPSBlbXB0eUludExpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0RHluYW1pY0V4dGVuc2lvbnMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHluYW1pY0V4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHluYW1pY0V4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgLyoqCiAgICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY0VudW1UeXBlfQogICAgICovCiAgICBwdWJsaWMgZW51bSBEeW5hbWljRW51bVR5cGUKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5EWU5BTUlDX0ZPTyA9IDIyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgRFlOQU1JQ19GT08oMjIwMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5EWU5BTUlDX0JBUiA9IDIyMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgRFlOQU1JQ19CQVIoMjIwMSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5EWU5BTUlDX0JBWiA9IDIyMDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgRFlOQU1JQ19CQVooMjIwMiksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5EWU5BTUlDX0ZPTyA9IDIyMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRFlOQU1JQ19GT09fVkFMVUUgPSAyMjAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+RFlOQU1JQ19CQVIgPSAyMjAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERZTkFNSUNfQkFSX1ZBTFVFID0gMjIwMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkRZTkFNSUNfQkFaID0gMjIwMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEWU5BTUlDX0JBWl9WQUxVRSA9IDIyMDI7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBEeW5hbWljRW51bVR5cGUgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIER5bmFtaWNFbnVtVHlwZSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAyMjAwOiByZXR1cm4gRFlOQU1JQ19GT087CiAgICAgICAgICBjYXNlIDIyMDE6IHJldHVybiBEWU5BTUlDX0JBUjsKICAgICAgICAgIGNhc2UgMjIwMjogcmV0dXJuIERZTkFNSUNfQkFaOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8RHluYW1pY0VudW1UeXBlPgogICAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgICAgfQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgICAgRHluYW1pY0VudW1UeXBlPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8RHluYW1pY0VudW1UeXBlPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgRHluYW1pY0VudW1UeXBlIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBEeW5hbWljRW51bVR5cGUuZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBEeW5hbWljRW51bVR5cGVbXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgRHluYW1pY0VudW1UeXBlIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgRHluYW1pY0VudW1UeXBlKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNFbnVtVHlwZSkKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIER5bmFtaWNNZXNzYWdlVHlwZU9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkeW5hbWljX2ZpZWxkID0gMjEwMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHluYW1pY0ZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzRHluYW1pY0ZpZWxkKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkeW5hbWljX2ZpZWxkID0gMjEwMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR5bmFtaWNGaWVsZC4KICAgICAgICovCiAgICAgIGludCBnZXREeW5hbWljRmllbGQoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBEeW5hbWljTWVzc2FnZVR5cGUgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUpCiAgICAgICAgRHluYW1pY01lc3NhZ2VUeXBlT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgRHluYW1pY01lc3NhZ2VUeXBlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgRHluYW1pY01lc3NhZ2VUeXBlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgRHluYW1pY01lc3NhZ2VUeXBlKCkgewogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IER5bmFtaWNNZXNzYWdlVHlwZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER5bmFtaWNFeHRlbnNpb25zX0R5bmFtaWNNZXNzYWdlVHlwZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHluYW1pY0V4dGVuc2lvbnNfRHluYW1pY01lc3NhZ2VUeXBlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBEWU5BTUlDX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDIxMDA7CiAgICAgIHByaXZhdGUgaW50IGR5bmFtaWNGaWVsZF8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZHluYW1pY19maWVsZCA9IDIxMDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGR5bmFtaWNGaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0R5bmFtaWNGaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR5bmFtaWNfZmllbGQgPSAyMTAwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZHluYW1pY0ZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldER5bmFtaWNGaWVsZCgpIHsKICAgICAgICByZXR1cm4gZHluYW1pY0ZpZWxkXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDIxMDAsIGR5bmFtaWNGaWVsZF8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgyMTAwLCBkeW5hbWljRmllbGRfKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlKSBvYmo7CgogICAgICAgIGlmIChoYXNEeW5hbWljRmllbGQoKSAhPSBvdGhlci5oYXNEeW5hbWljRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNEeW5hbWljRmllbGQoKSkgewogICAgICAgICAgaWYgKGdldER5bmFtaWNGaWVsZCgpCiAgICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RHluYW1pY0ZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChoYXNEeW5hbWljRmllbGQoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFlOQU1JQ19GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREeW5hbWljRmllbGQoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGV9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUpCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGVPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER5bmFtaWNFeHRlbnNpb25zX0R5bmFtaWNNZXNzYWdlVHlwZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER5bmFtaWNFeHRlbnNpb25zX0R5bmFtaWNNZXNzYWdlVHlwZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgZHluYW1pY0ZpZWxkXyA9IDA7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REeW5hbWljRXh0ZW5zaW9uc19EeW5hbWljTWVzc2FnZVR5cGVfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSh0aGlzKTsKICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQuZHluYW1pY0ZpZWxkXyA9IGR5bmFtaWNGaWVsZF87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzRHluYW1pY0ZpZWxkKCkpIHsKICAgICAgICAgICAgc2V0RHluYW1pY0ZpZWxkKG90aGVyLmdldER5bmFtaWNGaWVsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMTY4MDA6IHsKICAgICAgICAgICAgICAgICAgZHluYW1pY0ZpZWxkXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2ODAwCiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCBkeW5hbWljRmllbGRfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkeW5hbWljX2ZpZWxkID0gMjEwMDs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkeW5hbWljRmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNEeW5hbWljRmllbGQoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR5bmFtaWNfZmllbGQgPSAyMTAwOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBkeW5hbWljRmllbGQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0RHluYW1pY0ZpZWxkKCkgewogICAgICAgICAgcmV0dXJuIGR5bmFtaWNGaWVsZF87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGR5bmFtaWNfZmllbGQgPSAyMTAwOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGR5bmFtaWNGaWVsZCB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER5bmFtaWNGaWVsZChpbnQgdmFsdWUpIHsKCiAgICAgICAgICBkeW5hbWljRmllbGRfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBkeW5hbWljX2ZpZWxkID0gMjEwMDs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRHluYW1pY0ZpZWxkKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgZHluYW1pY0ZpZWxkXyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUpCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPER5bmFtaWNNZXNzYWdlVHlwZT4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPER5bmFtaWNNZXNzYWdlVHlwZT4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBEeW5hbWljTWVzc2FnZVR5cGUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxEeW5hbWljTWVzc2FnZVR5cGU+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxEeW5hbWljTWVzc2FnZVR5cGU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNDQUxBUl9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMjAwMDsKICAgIHByaXZhdGUgaW50IHNjYWxhckV4dGVuc2lvbl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIHNjYWxhcl9leHRlbnNpb24gPSAyMDAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc2NhbGFyRXh0ZW5zaW9uIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU2NhbGFyRXh0ZW5zaW9uKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZpeGVkMzIgc2NhbGFyX2V4dGVuc2lvbiA9IDIwMDA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc2NhbGFyRXh0ZW5zaW9uLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNjYWxhckV4dGVuc2lvbigpIHsKICAgICAgcmV0dXJuIHNjYWxhckV4dGVuc2lvbl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMjAwMTsKICAgIHByaXZhdGUgaW50IGVudW1FeHRlbnNpb25fID0gNDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIGVudW1fZXh0ZW5zaW9uID0gMjAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGVudW1FeHRlbnNpb24gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc0VudW1FeHRlbnNpb24oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIGVudW1fZXh0ZW5zaW9uID0gMjAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBlbnVtRXh0ZW5zaW9uLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIGdldEVudW1FeHRlbnNpb24oKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIoZW51bUV4dGVuc2lvbl8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLkZPUkVJR05fRk9PIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERZTkFNSUNfRU5VTV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMjAwMjsKICAgIHByaXZhdGUgaW50IGR5bmFtaWNFbnVtRXh0ZW5zaW9uXyA9IDIyMDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY0VudW1UeXBlIGR5bmFtaWNfZW51bV9leHRlbnNpb24gPSAyMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHluYW1pY0VudW1FeHRlbnNpb24gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc0R5bmFtaWNFbnVtRXh0ZW5zaW9uKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY0VudW1UeXBlIGR5bmFtaWNfZW51bV9leHRlbnNpb24gPSAyMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR5bmFtaWNFbnVtRXh0ZW5zaW9uLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljRW51bVR5cGUgZ2V0RHluYW1pY0VudW1FeHRlbnNpb24oKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNFbnVtVHlwZSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljRW51bVR5cGUuZm9yTnVtYmVyKGR5bmFtaWNFbnVtRXh0ZW5zaW9uXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNFbnVtVHlwZS5EWU5BTUlDX0ZPTyA6IHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVNTQUdFX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAyMDAzOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIG1lc3NhZ2VFeHRlbnNpb25fOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbWVzc2FnZV9leHRlbnNpb24gPSAyMDAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbWVzc2FnZUV4dGVuc2lvbiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc01lc3NhZ2VFeHRlbnNpb24oKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG1lc3NhZ2VfZXh0ZW5zaW9uID0gMjAwMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtZXNzYWdlRXh0ZW5zaW9uLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRNZXNzYWdlRXh0ZW5zaW9uKCkgewogICAgICByZXR1cm4gbWVzc2FnZUV4dGVuc2lvbl8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlRXh0ZW5zaW9uXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG1lc3NhZ2VfZXh0ZW5zaW9uID0gMjAwMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyIGdldE1lc3NhZ2VFeHRlbnNpb25PckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBtZXNzYWdlRXh0ZW5zaW9uXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1lc3NhZ2VFeHRlbnNpb25fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERZTkFNSUNfTUVTU0FHRV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMjAwNDsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIGR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgZHluYW1pY19tZXNzYWdlX2V4dGVuc2lvbiA9IDIwMDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0R5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIGR5bmFtaWNfbWVzc2FnZV9leHRlbnNpb24gPSAyMDA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIGdldER5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uKCkgewogICAgICByZXR1cm4gZHluYW1pY01lc3NhZ2VFeHRlbnNpb25fID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIGR5bmFtaWNfbWVzc2FnZV9leHRlbnNpb24gPSAyMDA0OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZU9yQnVpbGRlciBnZXREeW5hbWljTWVzc2FnZUV4dGVuc2lvbk9yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZHluYW1pY01lc3NhZ2VFeHRlbnNpb25fOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAyMDA1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZEV4dGVuc2lvbl8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2V4dGVuc2lvbiA9IDIwMDU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRFeHRlbnNpb24uCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkRXh0ZW5zaW9uTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRXh0ZW5zaW9uXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2V4dGVuc2lvbiA9IDIwMDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRFeHRlbnNpb24uCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRFeHRlbnNpb25Db3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRXh0ZW5zaW9uXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9leHRlbnNpb24gPSAyMDA1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRFeHRlbnNpb24gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZEV4dGVuc2lvbihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRXh0ZW5zaW9uXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfZXh0ZW5zaW9uID0gMjAwNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRFeHRlbnNpb24gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRFeHRlbnNpb25CeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRXh0ZW5zaW9uXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDIwMDY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZEV4dGVuc2lvbl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX2V4dGVuc2lvbiA9IDIwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEV4dGVuc2lvbi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFBhY2tlZEV4dGVuc2lvbkxpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRFeHRlbnNpb25fOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX2V4dGVuc2lvbiA9IDIwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEV4dGVuc2lvbi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRFeHRlbnNpb25Db3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEV4dGVuc2lvbl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX2V4dGVuc2lvbiA9IDIwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkRXh0ZW5zaW9uIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRFeHRlbnNpb24oaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRFeHRlbnNpb25fLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRFeHRlbnNpb25NZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDMyKDIwMDAsIHNjYWxhckV4dGVuc2lvbl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMjAwMSwgZW51bUV4dGVuc2lvbl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMjAwMiwgZHluYW1pY0VudW1FeHRlbnNpb25fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIwMDMsIGdldE1lc3NhZ2VFeHRlbnNpb24oKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyMDA0LCBnZXREeW5hbWljTWVzc2FnZUV4dGVuc2lvbigpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRXh0ZW5zaW9uXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMjAwNSwgcmVwZWF0ZWRFeHRlbnNpb25fLmdldFJhdyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEV4dGVuc2lvbkxpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMTYwNTApOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEV4dGVuc2lvbk1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkRXh0ZW5zaW9uXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVNJbnQzMk5vVGFnKHBhY2tlZEV4dGVuc2lvbl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUZpeGVkMzJTaXplKDIwMDAsIHNjYWxhckV4dGVuc2lvbl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSgyMDAxLCBlbnVtRXh0ZW5zaW9uXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDIwMDIsIGR5bmFtaWNFbnVtRXh0ZW5zaW9uXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwMDMsIGdldE1lc3NhZ2VFeHRlbnNpb24oKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIwMDQsIGdldER5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uKCkpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRFeHRlbnNpb25fLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkRXh0ZW5zaW9uXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkRXh0ZW5zaW9uTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEV4dGVuc2lvbl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVTSW50MzJTaXplTm9UYWcocGFja2VkRXh0ZW5zaW9uXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkRXh0ZW5zaW9uTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEV4dGVuc2lvbk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMpIG9iajsKCiAgICAgIGlmIChoYXNTY2FsYXJFeHRlbnNpb24oKSAhPSBvdGhlci5oYXNTY2FsYXJFeHRlbnNpb24oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzU2NhbGFyRXh0ZW5zaW9uKCkpIHsKICAgICAgICBpZiAoZ2V0U2NhbGFyRXh0ZW5zaW9uKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0U2NhbGFyRXh0ZW5zaW9uKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRW51bUV4dGVuc2lvbigpICE9IG90aGVyLmhhc0VudW1FeHRlbnNpb24oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRW51bUV4dGVuc2lvbigpKSB7CiAgICAgICAgaWYgKGVudW1FeHRlbnNpb25fICE9IG90aGVyLmVudW1FeHRlbnNpb25fKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0R5bmFtaWNFbnVtRXh0ZW5zaW9uKCkgIT0gb3RoZXIuaGFzRHluYW1pY0VudW1FeHRlbnNpb24oKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRHluYW1pY0VudW1FeHRlbnNpb24oKSkgewogICAgICAgIGlmIChkeW5hbWljRW51bUV4dGVuc2lvbl8gIT0gb3RoZXIuZHluYW1pY0VudW1FeHRlbnNpb25fKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc01lc3NhZ2VFeHRlbnNpb24oKSAhPSBvdGhlci5oYXNNZXNzYWdlRXh0ZW5zaW9uKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc01lc3NhZ2VFeHRlbnNpb24oKSkgewogICAgICAgIGlmICghZ2V0TWVzc2FnZUV4dGVuc2lvbigpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0TWVzc2FnZUV4dGVuc2lvbigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNEeW5hbWljTWVzc2FnZUV4dGVuc2lvbigpICE9IG90aGVyLmhhc0R5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0R5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uKCkpIHsKICAgICAgICBpZiAoIWdldER5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXREeW5hbWljTWVzc2FnZUV4dGVuc2lvbigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRFeHRlbnNpb25MaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRFeHRlbnNpb25MaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkRXh0ZW5zaW9uTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEV4dGVuc2lvbkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzU2NhbGFyRXh0ZW5zaW9uKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTQ0FMQVJfRVhURU5TSU9OX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTY2FsYXJFeHRlbnNpb24oKTsKICAgICAgfQogICAgICBpZiAoaGFzRW51bUV4dGVuc2lvbigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRU5VTV9FWFRFTlNJT05fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGVudW1FeHRlbnNpb25fOwogICAgICB9CiAgICAgIGlmIChoYXNEeW5hbWljRW51bUV4dGVuc2lvbigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRFlOQU1JQ19FTlVNX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZHluYW1pY0VudW1FeHRlbnNpb25fOwogICAgICB9CiAgICAgIGlmIChoYXNNZXNzYWdlRXh0ZW5zaW9uKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBNRVNTQUdFX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TWVzc2FnZUV4dGVuc2lvbigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0R5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBEWU5BTUlDX01FU1NBR0VfRVhURU5TSU9OX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXREeW5hbWljTWVzc2FnZUV4dGVuc2lvbigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkRXh0ZW5zaW9uQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9FWFRFTlNJT05fRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRXh0ZW5zaW9uTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEV4dGVuc2lvbkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkRXh0ZW5zaW9uTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFVzZWQgYnkgRXh0ZW5zaW9uU2V0VGVzdC9EeW5hbWljRXh0ZW5zaW9ucy4gIFRoZSB0ZXN0IGFjdHVhbGx5IGJ1aWxkcwogICAgICogYSBzZXQgb2YgZXh0ZW5zaW9ucyB0byBUZXN0QWxsRXh0ZW5zaW9ucyBkeW5hbWljYWxseSwgYmFzZWQgb24gdGhlIGZpZWxkcwogICAgICogb2YgdGhpcyBtZXNzYWdlIHR5cGUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER5bmFtaWNFeHRlbnNpb25zX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REeW5hbWljRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRNZXNzYWdlRXh0ZW5zaW9uRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXREeW5hbWljTWVzc2FnZUV4dGVuc2lvbkZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgc2NhbGFyRXh0ZW5zaW9uXyA9IDA7CiAgICAgICAgZW51bUV4dGVuc2lvbl8gPSA0OwogICAgICAgIGR5bmFtaWNFbnVtRXh0ZW5zaW9uXyA9IDIyMDA7CiAgICAgICAgbWVzc2FnZUV4dGVuc2lvbl8gPSBudWxsOwogICAgICAgIGlmIChtZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG1lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uXyA9IG51bGw7CiAgICAgICAgaWYgKGR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgZHluYW1pY01lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmVwZWF0ZWRFeHRlbnNpb25fID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIHBhY2tlZEV4dGVuc2lvbl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER5bmFtaWNFeHRlbnNpb25zX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucyBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucyByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnModGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc2NhbGFyRXh0ZW5zaW9uXyA9IHNjYWxhckV4dGVuc2lvbl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZW51bUV4dGVuc2lvbl8gPSBlbnVtRXh0ZW5zaW9uXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5keW5hbWljRW51bUV4dGVuc2lvbl8gPSBkeW5hbWljRW51bUV4dGVuc2lvbl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubWVzc2FnZUV4dGVuc2lvbl8gPSBtZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gbWVzc2FnZUV4dGVuc2lvbl8KICAgICAgICAgICAgICA6IG1lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uXyA9IGR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gZHluYW1pY01lc3NhZ2VFeHRlbnNpb25fCiAgICAgICAgICAgICAgOiBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEV4dGVuc2lvbl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkRXh0ZW5zaW9uXyA9IHJlcGVhdGVkRXh0ZW5zaW9uXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEV4dGVuc2lvbl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZEV4dGVuc2lvbl8gPSBwYWNrZWRFeHRlbnNpb25fOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzU2NhbGFyRXh0ZW5zaW9uKCkpIHsKICAgICAgICAgIHNldFNjYWxhckV4dGVuc2lvbihvdGhlci5nZXRTY2FsYXJFeHRlbnNpb24oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNFbnVtRXh0ZW5zaW9uKCkpIHsKICAgICAgICAgIHNldEVudW1FeHRlbnNpb24ob3RoZXIuZ2V0RW51bUV4dGVuc2lvbigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0R5bmFtaWNFbnVtRXh0ZW5zaW9uKCkpIHsKICAgICAgICAgIHNldER5bmFtaWNFbnVtRXh0ZW5zaW9uKG90aGVyLmdldER5bmFtaWNFbnVtRXh0ZW5zaW9uKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzTWVzc2FnZUV4dGVuc2lvbigpKSB7CiAgICAgICAgICBtZXJnZU1lc3NhZ2VFeHRlbnNpb24ob3RoZXIuZ2V0TWVzc2FnZUV4dGVuc2lvbigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0R5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uKCkpIHsKICAgICAgICAgIG1lcmdlRHluYW1pY01lc3NhZ2VFeHRlbnNpb24ob3RoZXIuZ2V0RHluYW1pY01lc3NhZ2VFeHRlbnNpb24oKSk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRFeHRlbnNpb25fLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkRXh0ZW5zaW9uXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRFeHRlbnNpb25fID0gb3RoZXIucmVwZWF0ZWRFeHRlbnNpb25fOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEV4dGVuc2lvbklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEV4dGVuc2lvbl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkRXh0ZW5zaW9uXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRFeHRlbnNpb25fLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEV4dGVuc2lvbl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEV4dGVuc2lvbl8gPSBvdGhlci5wYWNrZWRFeHRlbnNpb25fOwogICAgICAgICAgICBwYWNrZWRFeHRlbnNpb25fLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkRXh0ZW5zaW9uSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEV4dGVuc2lvbl8uYWRkQWxsKG90aGVyLnBhY2tlZEV4dGVuc2lvbl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTYwMDU6IHsKICAgICAgICAgICAgICAgIHNjYWxhckV4dGVuc2lvbl8gPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MDA1CiAgICAgICAgICAgICAgY2FzZSAxNjAwODogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMjAwMSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVudW1FeHRlbnNpb25fID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYwMDgKICAgICAgICAgICAgICBjYXNlIDE2MDE2OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNFbnVtVHlwZSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY0VudW1UeXBlLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMjAwMiwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGR5bmFtaWNFbnVtRXh0ZW5zaW9uXyA9IHRtcFJhdzsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MDE2CiAgICAgICAgICAgICAgY2FzZSAxNjAyNjogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZUV4dGVuc2lvbkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYwMjYKICAgICAgICAgICAgICBjYXNlIDE2MDM0OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXREeW5hbWljTWVzc2FnZUV4dGVuc2lvbkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYwMzQKICAgICAgICAgICAgICBjYXNlIDE2MDQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRXh0ZW5zaW9uSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEV4dGVuc2lvbl8uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjA0MgogICAgICAgICAgICAgIGNhc2UgMTYwNDg6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZFNJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRXh0ZW5zaW9uSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRFeHRlbnNpb25fLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjA0OAogICAgICAgICAgICAgIGNhc2UgMTYwNTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkRXh0ZW5zaW9uSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZEV4dGVuc2lvbl8uYWRkSW50KGlucHV0LnJlYWRTSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYwNTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgc2NhbGFyRXh0ZW5zaW9uXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIHNjYWxhcl9leHRlbnNpb24gPSAyMDAwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzY2FsYXJFeHRlbnNpb24gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTY2FsYXJFeHRlbnNpb24oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIHNjYWxhcl9leHRlbnNpb24gPSAyMDAwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgc2NhbGFyRXh0ZW5zaW9uLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNjYWxhckV4dGVuc2lvbigpIHsKICAgICAgICByZXR1cm4gc2NhbGFyRXh0ZW5zaW9uXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZml4ZWQzMiBzY2FsYXJfZXh0ZW5zaW9uID0gMjAwMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc2NhbGFyRXh0ZW5zaW9uIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U2NhbGFyRXh0ZW5zaW9uKGludCB2YWx1ZSkgewoKICAgICAgICBzY2FsYXJFeHRlbnNpb25fID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBmaXhlZDMyIHNjYWxhcl9leHRlbnNpb24gPSAyMDAwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTY2FsYXJFeHRlbnNpb24oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHNjYWxhckV4dGVuc2lvbl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBlbnVtRXh0ZW5zaW9uXyA9IDQ7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gZW51bV9leHRlbnNpb24gPSAyMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBlbnVtRXh0ZW5zaW9uIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzRW51bUV4dGVuc2lvbigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBlbnVtX2V4dGVuc2lvbiA9IDIwMDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtRXh0ZW5zaW9uLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBnZXRFbnVtRXh0ZW5zaW9uKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIoZW51bUV4dGVuc2lvbl8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uRk9SRUlHTl9GT08gOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBlbnVtX2V4dGVuc2lvbiA9IDIwMDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVudW1FeHRlbnNpb24gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRFbnVtRXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBlbnVtRXh0ZW5zaW9uXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gZW51bV9leHRlbnNpb24gPSAyMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJFbnVtRXh0ZW5zaW9uKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBlbnVtRXh0ZW5zaW9uXyA9IDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGR5bmFtaWNFbnVtRXh0ZW5zaW9uXyA9IDIyMDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNFbnVtVHlwZSBkeW5hbWljX2VudW1fZXh0ZW5zaW9uID0gMjAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHluYW1pY0VudW1FeHRlbnNpb24gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNEeW5hbWljRW51bUV4dGVuc2lvbigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY0VudW1UeXBlIGR5bmFtaWNfZW51bV9leHRlbnNpb24gPSAyMDAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZHluYW1pY0VudW1FeHRlbnNpb24uCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljRW51bVR5cGUgZ2V0RHluYW1pY0VudW1FeHRlbnNpb24oKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY0VudW1UeXBlIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNFbnVtVHlwZS5mb3JOdW1iZXIoZHluYW1pY0VudW1FeHRlbnNpb25fKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljRW51bVR5cGUuRFlOQU1JQ19GT08gOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY0VudW1UeXBlIGR5bmFtaWNfZW51bV9leHRlbnNpb24gPSAyMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBkeW5hbWljRW51bUV4dGVuc2lvbiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER5bmFtaWNFbnVtRXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNFbnVtVHlwZSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIGR5bmFtaWNFbnVtRXh0ZW5zaW9uXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNFbnVtVHlwZSBkeW5hbWljX2VudW1fZXh0ZW5zaW9uID0gMjAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRHluYW1pY0VudW1FeHRlbnNpb24oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIGR5bmFtaWNFbnVtRXh0ZW5zaW9uXyA9IDIyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBtZXNzYWdlRXh0ZW5zaW9uXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiBtZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbWVzc2FnZV9leHRlbnNpb24gPSAyMDAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtZXNzYWdlRXh0ZW5zaW9uIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc01lc3NhZ2VFeHRlbnNpb24oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbWVzc2FnZV9leHRlbnNpb24gPSAyMDAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbWVzc2FnZUV4dGVuc2lvbi4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIGdldE1lc3NhZ2VFeHRlbnNpb24oKSB7CiAgICAgICAgaWYgKG1lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUV4dGVuc2lvbl8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBtZXNzYWdlRXh0ZW5zaW9uXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG1lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UgbWVzc2FnZV9leHRlbnNpb24gPSAyMDAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE1lc3NhZ2VFeHRlbnNpb24ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSB2YWx1ZSkgewogICAgICAgIGlmIChtZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBtZXNzYWdlRXh0ZW5zaW9uXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG1lc3NhZ2VfZXh0ZW5zaW9uID0gMjAwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNZXNzYWdlRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChtZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbWVzc2FnZUV4dGVuc2lvbl8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBtZXNzYWdlX2V4dGVuc2lvbiA9IDIwMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VNZXNzYWdlRXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAobWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSAmJgogICAgICAgICAgICBtZXNzYWdlRXh0ZW5zaW9uXyAhPSBudWxsICYmCiAgICAgICAgICAgIG1lc3NhZ2VFeHRlbnNpb25fICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0TWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbWVzc2FnZUV4dGVuc2lvbl8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChtZXNzYWdlRXh0ZW5zaW9uXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBtZXNzYWdlX2V4dGVuc2lvbiA9IDIwMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNZXNzYWdlRXh0ZW5zaW9uKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBtZXNzYWdlRXh0ZW5zaW9uXyA9IG51bGw7CiAgICAgICAgaWYgKG1lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBtZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgbWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBtZXNzYWdlX2V4dGVuc2lvbiA9IDIwMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBnZXRNZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE1lc3NhZ2VFeHRlbnNpb25GaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBtZXNzYWdlX2V4dGVuc2lvbiA9IDIwMDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXIgZ2V0TWVzc2FnZUV4dGVuc2lvbk9yQnVpbGRlcigpIHsKICAgICAgICBpZiAobWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gbWVzc2FnZUV4dGVuc2lvbl8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG1lc3NhZ2VFeHRlbnNpb25fOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG1lc3NhZ2VfZXh0ZW5zaW9uID0gMjAwMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0TWVzc2FnZUV4dGVuc2lvbkZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAobWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG1lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE1lc3NhZ2VFeHRlbnNpb24oKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG1lc3NhZ2VFeHRlbnNpb25fID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgZHluYW1pY01lc3NhZ2VFeHRlbnNpb25fOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGVPckJ1aWxkZXI+IGR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBkeW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uID0gMjAwNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZHluYW1pY01lc3NhZ2VFeHRlbnNpb24gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzRHluYW1pY01lc3NhZ2VFeHRlbnNpb24oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBkeW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uID0gMjAwNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBnZXREeW5hbWljTWVzc2FnZUV4dGVuc2lvbigpIHsKICAgICAgICBpZiAoZHluYW1pY01lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gZHluYW1pY01lc3NhZ2VFeHRlbnNpb25fID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbl87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlIGR5bmFtaWNfbWVzc2FnZV9leHRlbnNpb24gPSAyMDA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldER5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSB2YWx1ZSkgewogICAgICAgIGlmIChkeW5hbWljTWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZHluYW1pY01lc3NhZ2VFeHRlbnNpb25fID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgZHluYW1pY19tZXNzYWdlX2V4dGVuc2lvbiA9IDIwMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RHluYW1pY01lc3NhZ2VFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoZHluYW1pY01lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbl8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZHluYW1pY01lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBkeW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uID0gMjAwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSB2YWx1ZSkgewogICAgICAgIGlmIChkeW5hbWljTWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSAmJgogICAgICAgICAgICBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbl8gIT0gbnVsbCAmJgogICAgICAgICAgICBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbl8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldER5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbl8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgZHluYW1pY01lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoZHluYW1pY01lc3NhZ2VFeHRlbnNpb25fICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgZHluYW1pY19tZXNzYWdlX2V4dGVuc2lvbiA9IDIwMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJEeW5hbWljTWVzc2FnZUV4dGVuc2lvbigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgZHluYW1pY01lc3NhZ2VFeHRlbnNpb25fID0gbnVsbDsKICAgICAgICBpZiAoZHluYW1pY01lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUgZHluYW1pY19tZXNzYWdlX2V4dGVuc2lvbiA9IDIwMDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZS5CdWlsZGVyIGdldER5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldER5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBkeW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uID0gMjAwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlT3JCdWlsZGVyIGdldER5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChkeW5hbWljTWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbkJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbl87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSBkeW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uID0gMjAwNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGUsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5cGVPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RHluYW1pY01lc3NhZ2VFeHRlbnNpb25GaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGR5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZHluYW1pY01lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNNZXNzYWdlVHlwZU9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldER5bmFtaWNNZXNzYWdlRXh0ZW5zaW9uKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBkeW5hbWljTWVzc2FnZUV4dGVuc2lvbl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZHluYW1pY01lc3NhZ2VFeHRlbnNpb25CdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRFeHRlbnNpb25fID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRXh0ZW5zaW9uSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRFeHRlbnNpb25fLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEV4dGVuc2lvbl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KHJlcGVhdGVkRXh0ZW5zaW9uXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2V4dGVuc2lvbiA9IDIwMDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEV4dGVuc2lvbi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0UmVwZWF0ZWRFeHRlbnNpb25MaXN0KCkgewogICAgICAgIHJlcGVhdGVkRXh0ZW5zaW9uXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRXh0ZW5zaW9uXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2V4dGVuc2lvbiA9IDIwMDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEV4dGVuc2lvbi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRFeHRlbnNpb25Db3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRFeHRlbnNpb25fLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2V4dGVuc2lvbiA9IDIwMDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRFeHRlbnNpb24gYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRFeHRlbnNpb24oaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRXh0ZW5zaW9uXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfZXh0ZW5zaW9uID0gMjAwNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkRXh0ZW5zaW9uIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkRXh0ZW5zaW9uQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRXh0ZW5zaW9uXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX2V4dGVuc2lvbiA9IDIwMDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRFeHRlbnNpb24gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEV4dGVuc2lvbigKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRFeHRlbnNpb25Jc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEV4dGVuc2lvbl8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfZXh0ZW5zaW9uID0gMjAwNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRFeHRlbnNpb24gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEV4dGVuc2lvbigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkRXh0ZW5zaW9uSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRFeHRlbnNpb25fLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfZXh0ZW5zaW9uID0gMjAwNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRXh0ZW5zaW9uIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRFeHRlbnNpb25Jc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRFeHRlbnNpb25fKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9leHRlbnNpb24gPSAyMDA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEV4dGVuc2lvbigpIHsKICAgICAgICByZXBlYXRlZEV4dGVuc2lvbl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9leHRlbnNpb24gPSAyMDA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRFeHRlbnNpb24gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEV4dGVuc2lvbkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEV4dGVuc2lvbklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRXh0ZW5zaW9uXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkRXh0ZW5zaW9uXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkRXh0ZW5zaW9uSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkRXh0ZW5zaW9uXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkRXh0ZW5zaW9uXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRFeHRlbnNpb25fKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX2V4dGVuc2lvbiA9IDIwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkRXh0ZW5zaW9uLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UGFja2VkRXh0ZW5zaW9uTGlzdCgpIHsKICAgICAgICBwYWNrZWRFeHRlbnNpb25fLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkRXh0ZW5zaW9uXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc2ludDMyIHBhY2tlZF9leHRlbnNpb24gPSAyMDA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEV4dGVuc2lvbi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkRXh0ZW5zaW9uQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEV4dGVuc2lvbl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX2V4dGVuc2lvbiA9IDIwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEV4dGVuc2lvbiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEV4dGVuc2lvbihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkRXh0ZW5zaW9uXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX2V4dGVuc2lvbiA9IDIwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEV4dGVuc2lvbiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEV4dGVuc2lvbigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEV4dGVuc2lvbklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEV4dGVuc2lvbl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX2V4dGVuc2lvbiA9IDIwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRFeHRlbnNpb24gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRFeHRlbnNpb24oaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEV4dGVuc2lvbklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEV4dGVuc2lvbl8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHNpbnQzMiBwYWNrZWRfZXh0ZW5zaW9uID0gMjAwNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRFeHRlbnNpb24gdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRFeHRlbnNpb24oCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRFeHRlbnNpb25Jc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkRXh0ZW5zaW9uXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzaW50MzIgcGFja2VkX2V4dGVuc2lvbiA9IDIwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRFeHRlbnNpb24oKSB7CiAgICAgICAgcGFja2VkRXh0ZW5zaW9uXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5zaW9ucykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdER5bmFtaWNFeHRlbnNpb25zKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3REeW5hbWljRXh0ZW5zaW9ucz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0RHluYW1pY0V4dGVuc2lvbnM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0RHluYW1pY0V4dGVuc2lvbnMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RHluYW1pY0V4dGVuc2lvbnM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdER5bmFtaWNFeHRlbnNpb25zPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3REeW5hbWljRXh0ZW5zaW9ucyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RSZXBlYXRlZFN0cmluZ09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVwZWF0ZWRTdHJpbmcpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcxLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU3RyaW5nMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcxID0gMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcxKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcxID0gMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcyID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcyLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZzIgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzIoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZzIgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzJCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMxMSA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQnl0ZXMxMS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBnZXRSZXBlYXRlZEJ5dGVzMTFMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzMTEgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJ5dGVzMTEuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEJ5dGVzMTFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlczExID0gMTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJ5dGVzMTEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlczExKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlczEyID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCeXRlczEyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IGdldFJlcGVhdGVkQnl0ZXMxMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMxMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMxMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQnl0ZXMxMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzMTIgPSAxMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQnl0ZXMxMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXBlYXRlZEJ5dGVzMTIoaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcGVhdGVkU3RyaW5nfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFJlcGVhdGVkU3RyaW5nIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXBlYXRlZFN0cmluZykKICAgICAgVGVzdFJlcGVhdGVkU3RyaW5nT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0UmVwZWF0ZWRTdHJpbmcubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFJlcGVhdGVkU3RyaW5nKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFJlcGVhdGVkU3RyaW5nKCkgewogICAgICByZXBlYXRlZFN0cmluZzFfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmcyXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkQnl0ZXMxMV8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgcmVwZWF0ZWRCeXRlczEyXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RSZXBlYXRlZFN0cmluZygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXBlYXRlZFN0cmluZ19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXBlYXRlZFN0cmluZ19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFN0cmluZy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkcxX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nMV8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMS4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzEuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcxQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzFfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZzEgPSAxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcxKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nMSA9IDE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzFCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HMl9GSUVMRF9OVU1CRVIgPSAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzJfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcyID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzIuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcyID0gMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMl8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZzIgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzJfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0JZVEVTMTFfRklFTERfTlVNQkVSID0gMTE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Qcm90b2J1Zkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiByZXBlYXRlZEJ5dGVzMTFfID0KICAgICAgICBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMxMSA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQnl0ZXMxMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZEJ5dGVzMTFMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlczExXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMxMSA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMxMS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJ5dGVzMTFDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXMxMV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlczExID0gMTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJ5dGVzMTEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldFJlcGVhdGVkQnl0ZXMxMShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXMxMV8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9CWVRFUzEyX0ZJRUxEX05VTUJFUiA9IDEyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gcmVwZWF0ZWRCeXRlczEyXyA9CiAgICAgICAgZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzMTIgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJ5dGVzMTIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRCeXRlczEyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXMxMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzMTIgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJ5dGVzMTIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCeXRlczEyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJ5dGVzMTJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMxMiA9IDEyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCeXRlczEyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXBlYXRlZEJ5dGVzMTIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJ5dGVzMTJfLmdldChpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEsIHJlcGVhdGVkU3RyaW5nMV8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDIsIHJlcGVhdGVkU3RyaW5nMl8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQnl0ZXMxMV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcygxMSwgcmVwZWF0ZWRCeXRlczExXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRCeXRlczEyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDEyLCByZXBlYXRlZEJ5dGVzMTJfLmdldChpKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmcxXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZzFfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRTdHJpbmcxTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmcyXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU3RyaW5nMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEJ5dGVzMTFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplTm9UYWcocmVwZWF0ZWRCeXRlczExXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkQnl0ZXMxMUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEJ5dGVzMTJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplTm9UYWcocmVwZWF0ZWRCeXRlczEyXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkQnl0ZXMxMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nKSBvYmo7CgogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nMUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZzFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmcyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEJ5dGVzMTFMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRCeXRlczExTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkQnl0ZXMxMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEJ5dGVzMTJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nMUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmcxTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmcyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQnl0ZXMxMUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQllURVMxMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRCeXRlczExTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQnl0ZXMxMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQllURVMxMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRCeXRlczEyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFN0cmluZyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFN0cmluZyBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcGVhdGVkU3RyaW5nfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcGVhdGVkU3RyaW5nKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXBlYXRlZFN0cmluZ19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVwZWF0ZWRTdHJpbmdfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMV8gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZEJ5dGVzMTFfID0gZW1wdHlMaXN0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcyk7CiAgICAgICAgcmVwZWF0ZWRCeXRlczEyXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVwZWF0ZWRTdHJpbmdfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFN0cmluZyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFN0cmluZyByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmcxXyA9IHJlcGVhdGVkU3RyaW5nMV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZzJfID0gcmVwZWF0ZWRTdHJpbmcyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQnl0ZXMxMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQnl0ZXMxMV8gPSByZXBlYXRlZEJ5dGVzMTFfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRCeXRlczEyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRCeXRlczEyXyA9IHJlcGVhdGVkQnl0ZXMxMl87CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU3RyaW5nLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmcxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nMV87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzFfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzFfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmcyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nMl87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQnl0ZXMxMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRCeXRlczExXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRCeXRlczExXyA9IG90aGVyLnJlcGVhdGVkQnl0ZXMxMV87CiAgICAgICAgICAgIHJlcGVhdGVkQnl0ZXMxMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEJ5dGVzMTFJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRCeXRlczExXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRCeXRlczExXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEJ5dGVzMTJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkQnl0ZXMxMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQnl0ZXMxMl8gPSBvdGhlci5yZXBlYXRlZEJ5dGVzMTJfOwogICAgICAgICAgICByZXBlYXRlZEJ5dGVzMTJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlczEySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkQnl0ZXMxMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkQnl0ZXMxMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZzFfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyXy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSA5MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHYgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXMxMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRCeXRlczExXy5hZGQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTAKICAgICAgICAgICAgICBjYXNlIDk4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdiA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlczEySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEJ5dGVzMTJfLmFkZCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5OAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzFfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU3RyaW5nMUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMV8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMV8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KHJlcGVhdGVkU3RyaW5nMV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcxID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMS4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcxLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzFDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcxID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcxKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzFfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcxID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzFCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZzEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nMSgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcxID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTdHJpbmcxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcxKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZzEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTdHJpbmcxKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzFfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcxID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmcxKCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcxID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzFJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzFfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzJfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU3RyaW5nMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KHJlcGVhdGVkU3RyaW5nMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcyID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcyID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzJfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcyID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzJCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZzIgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nMigKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcyID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTdHJpbmcyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcyKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZzIgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTdHJpbmcyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcyID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmcyKCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmcyID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzJfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuUHJvdG9idWZMaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gcmVwZWF0ZWRCeXRlczExXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRCeXRlczExSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRCeXRlczExXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRCeXRlczExXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEJ5dGVzMTFfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlczExID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJ5dGVzMTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRCeXRlczExTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEJ5dGVzMTFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlczExXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMxMSA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCeXRlczExLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJ5dGVzMTFDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCeXRlczExXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJ5dGVzMTEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRSZXBlYXRlZEJ5dGVzMTEoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXMxMV8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMxMSA9IDExOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQnl0ZXMxMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQnl0ZXMxMSgKICAgICAgICAgIGludCBpbmRleCwgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEJ5dGVzMTFJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJ5dGVzMTFfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMxMSA9IDExOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJ5dGVzMTEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEJ5dGVzMTEoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEJ5dGVzMTFJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJ5dGVzMTFfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlczExID0gMTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEJ5dGVzMTEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEJ5dGVzMTEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlczExSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkQnl0ZXMxMV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMxMSA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEJ5dGVzMTEoKSB7CiAgICAgICAgcmVwZWF0ZWRCeXRlczExXyA9IGVtcHR5TGlzdChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLlByb3RvYnVmTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHJlcGVhdGVkQnl0ZXMxMl8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQnl0ZXMxMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQnl0ZXMxMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkQnl0ZXMxMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRCeXRlczEyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMxMiA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCeXRlczEyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4KICAgICAgICAgIGdldFJlcGVhdGVkQnl0ZXMxMkxpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRCeXRlczEyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXMxMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQnl0ZXMxMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCeXRlczEyQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQnl0ZXMxMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBieXRlcyByZXBlYXRlZF9ieXRlczEyID0gMTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCeXRlczEyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0UmVwZWF0ZWRCeXRlczEyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEJ5dGVzMTJfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJ5dGVzMTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEJ5dGVzMTIoCiAgICAgICAgICBpbnQgaW5kZXgsIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlczEySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCeXRlczEyXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRCeXRlczEyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRCeXRlczEyKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCeXRlczEySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCeXRlczEyXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYnl0ZXMgcmVwZWF0ZWRfYnl0ZXMxMiA9IDEyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRCeXRlczEyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRCeXRlczEyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkQnl0ZXMxMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEJ5dGVzMTJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJ5dGVzIHJlcGVhdGVkX2J5dGVzMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRCeXRlczEyKCkgewogICAgICAgIHJlcGVhdGVkQnl0ZXMxMl8gPSBlbXB0eUxpc3QoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcGVhdGVkU3RyaW5nKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVwZWF0ZWRTdHJpbmcpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFN0cmluZyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFN0cmluZygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVwZWF0ZWRTdHJpbmc+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFJlcGVhdGVkU3RyaW5nPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdFJlcGVhdGVkU3RyaW5nIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFJlcGVhdGVkU3RyaW5nPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXBlYXRlZFN0cmluZz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTdHJpbmcgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBQYXJzaW5nIHJlcGVhdGVkIGZpeGVkIHNpemUgdmFsdWVzIHVzZWQgdG8gZmFpbC4gVGhpcyBtZXNzYWdlIG5lZWRzIHRvIGJlCiAgICAgKiB1c2VkIGluIG9yZGVyIHRvIGdldCBhIHRhZyBvZiB0aGUgcmlnaHQgc2l6ZTsgYWxsIG9mIHRoZSByZXBlYXRlZCBmaWVsZHMKICAgICAqIGluIFRlc3RBbGxUeXBlcyBkaWRuJ3QgdHJpZ2dlciB0aGUgY2hlY2suCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkMzIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBQYXJzaW5nIHJlcGVhdGVkIGZpeGVkIHNpemUgdmFsdWVzIHVzZWQgdG8gZmFpbC4gVGhpcyBtZXNzYWdlIG5lZWRzIHRvIGJlCiAgICAgKiB1c2VkIGluIG9yZGVyIHRvIGdldCBhIHRhZyBvZiB0aGUgcmlnaHQgc2l6ZTsgYWxsIG9mIHRoZSByZXBlYXRlZCBmaWVsZHMKICAgICAqIGluIFRlc3RBbGxUeXBlcyBkaWRuJ3QgdHJpZ2dlciB0aGUgY2hlY2suCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZpeGVkMzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUGFyc2luZyByZXBlYXRlZCBmaXhlZCBzaXplIHZhbHVlcyB1c2VkIHRvIGZhaWwuIFRoaXMgbWVzc2FnZSBuZWVkcyB0byBiZQogICAgICogdXNlZCBpbiBvcmRlciB0byBnZXQgYSB0YWcgb2YgdGhlIHJpZ2h0IHNpemU7IGFsbCBvZiB0aGUgcmVwZWF0ZWQgZmllbGRzCiAgICAgKiBpbiBUZXN0QWxsVHlwZXMgZGlkbid0IHRyaWdnZXIgdGhlIGNoZWNrLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMTI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGaXhlZDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQ2hlY2sgZm9yIGEgdmFyaW50IHR5cGUsIGp1c3QgZm9yIGdvb2QgbWVhc3VyZS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkSW50MzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBDaGVjayBmb3IgYSB2YXJpbnQgdHlwZSwganVzdCBmb3IgZ29vZCBtZWFzdXJlLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBDaGVjayBmb3IgYSB2YXJpbnQgdHlwZSwganVzdCBmb3IgZ29vZCBtZWFzdXJlLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRJbnQzMihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGhhdmUgdHdvLWJ5dGUgdGFncy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDIwNDY7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGaXhlZDY0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgaGF2ZSB0d28tYnl0ZSB0YWdzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMjA0Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZpeGVkNjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEZpeGVkNjRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgaGF2ZSB0d28tYnl0ZSB0YWdzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMjA0Njs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRml4ZWQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UmVwZWF0ZWRGaXhlZDY0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIwNDc7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+IGdldFJlcGVhdGVkSW50NjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMjA0Nzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDY0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRJbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMjA0Nzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkSW50NjQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaHJlZSBieXRlIHRhZ3MuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDI2MjE0Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZsb2F0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+IGdldFJlcGVhdGVkRmxvYXRMaXN0KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaHJlZSBieXRlIHRhZ3MuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDI2MjE0Mjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEZsb2F0LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRGbG9hdENvdW50KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaHJlZSBieXRlIHRhZ3MuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDI2MjE0Mjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBmbG9hdCBnZXRSZXBlYXRlZEZsb2F0KGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMjYyMTQzOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDY0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAyNjIxNDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFVpbnQ2NENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAyNjIxNDM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UmVwZWF0ZWRVaW50NjQoaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcykKICAgICAgVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMoKSB7CiAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgcmVwZWF0ZWRVaW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXNfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRklYRUQzMl9GSUVMRF9OVU1CRVIgPSAxMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRGaXhlZDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBQYXJzaW5nIHJlcGVhdGVkIGZpeGVkIHNpemUgdmFsdWVzIHVzZWQgdG8gZmFpbC4gVGhpcyBtZXNzYWdlIG5lZWRzIHRvIGJlCiAgICAgKiB1c2VkIGluIG9yZGVyIHRvIGdldCBhIHRhZyBvZiB0aGUgcmlnaHQgc2l6ZTsgYWxsIG9mIHRoZSByZXBlYXRlZCBmaWVsZHMKICAgICAqIGluIFRlc3RBbGxUeXBlcyBkaWRuJ3QgdHJpZ2dlciB0aGUgY2hlY2suCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkMzIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZEZpeGVkMzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXzsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFBhcnNpbmcgcmVwZWF0ZWQgZml4ZWQgc2l6ZSB2YWx1ZXMgdXNlZCB0byBmYWlsLiBUaGlzIG1lc3NhZ2UgbmVlZHMgdG8gYmUKICAgICAqIHVzZWQgaW4gb3JkZXIgdG8gZ2V0IGEgdGFnIG9mIHRoZSByaWdodCBzaXplOyBhbGwgb2YgdGhlIHJlcGVhdGVkIGZpZWxkcwogICAgICogaW4gVGVzdEFsbFR5cGVzIGRpZG4ndCB0cmlnZ2VyIHRoZSBjaGVjay4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRml4ZWQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUGFyc2luZyByZXBlYXRlZCBmaXhlZCBzaXplIHZhbHVlcyB1c2VkIHRvIGZhaWwuIFRoaXMgbWVzc2FnZSBuZWVkcyB0byBiZQogICAgICogdXNlZCBpbiBvcmRlciB0byBnZXQgYSB0YWcgb2YgdGhlIHJpZ2h0IHNpemU7IGFsbCBvZiB0aGUgcmVwZWF0ZWQgZmllbGRzCiAgICAgKiBpbiBUZXN0QWxsVHlwZXMgZGlkbid0IHRyaWdnZXIgdGhlIGNoZWNrLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMTI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTlQzMl9GSUVMRF9OVU1CRVIgPSAxMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRJbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQ2hlY2sgZm9yIGEgdmFyaW50IHR5cGUsIGp1c3QgZm9yIGdvb2QgbWVhc3VyZS4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkSW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBDaGVjayBmb3IgYSB2YXJpbnQgdHlwZSwganVzdCBmb3IgZ29vZCBtZWFzdXJlLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIENoZWNrIGZvciBhIHZhcmludCB0eXBlLCBqdXN0IGZvciBnb29kIG1lYXN1cmUuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRklYRUQ2NF9GSUVMRF9OVU1CRVIgPSAyMDQ2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRGaXhlZDY0XyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhlc2UgaGF2ZSB0d28tYnl0ZSB0YWdzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMjA0Njs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0XzsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRoZXNlIGhhdmUgdHdvLWJ5dGUgdGFncy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDIwNDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDY0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRml4ZWQ2NENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGVzZSBoYXZlIHR3by1ieXRlIHRhZ3MuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAyMDQ2OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRGaXhlZDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTlQ2NF9GSUVMRF9OVU1CRVIgPSAyMDQ3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRJbnQ2NF8gPQogICAgICAgIGVtcHR5TG9uZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyMDQ3OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZEludDY0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIwNDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDY0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMjA0Nzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50NjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRkxPQVRfRklFTERfTlVNQkVSID0gMjYyMTQyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRmxvYXRMaXN0IHJlcGVhdGVkRmxvYXRfID0KICAgICAgICBlbXB0eUZsb2F0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhyZWUgYnl0ZSB0YWdzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAyNjIxNDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGbG9hdC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4KICAgICAgICBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhyZWUgYnl0ZSB0YWdzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAyNjIxNDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGbG9hdC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZsb2F0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaHJlZSBieXRlIHRhZ3MuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDI2MjE0Mjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkRmxvYXQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgZmxvYXQgZ2V0UmVwZWF0ZWRGbG9hdChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9VSU5UNjRfRklFTERfTlVNQkVSID0gMjYyMTQzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRVaW50NjRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAyNjIxNDM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAyNjIxNDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVaW50NjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVaW50NjRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAyNjIxNDM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFVpbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkVWludDY0KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEZpeGVkMzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRml4ZWQzMigxMiwgcmVwZWF0ZWRGaXhlZDMyXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxMywgcmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkRml4ZWQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGaXhlZDY0KDIwNDYsIHJlcGVhdGVkRml4ZWQ2NF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDIwNDcsIHJlcGVhdGVkSW50NjRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVGbG9hdCgyNjIxNDIsIHJlcGVhdGVkRmxvYXRfLmdldEZsb2F0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVWludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQ2NCgyNjIxNDMsIHJlcGVhdGVkVWludDY0Xy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA0ICogZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKHJlcGVhdGVkSW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSA4ICogZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDY0Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZU5vVGFnKHJlcGVhdGVkSW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkSW50NjRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gNCAqIGdldFJlcGVhdGVkRmxvYXRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAzICogZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50NjRTaXplTm9UYWcocmVwZWF0ZWRVaW50NjRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMyAqIGdldFJlcGVhdGVkVWludDY0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMpIG9iajsKCiAgICAgIGlmICghZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkSW50MzJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRGaXhlZDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkSW50NjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEZsb2F0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkVWludDY0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkVWludDY0TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZJWEVEMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRml4ZWQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEludDMyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9JTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZpeGVkNjRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0ZJWEVENjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkRml4ZWQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEludDY0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9JTlQ2NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRJbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEZsb2F0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9GTE9BVF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRGbG9hdExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFVpbnQ2NENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfVUlOVDY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFVpbnQ2NExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcyBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcyByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcyh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZpeGVkMzJfID0gcmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEludDMyXyA9IHJlcGVhdGVkSW50MzJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRGaXhlZDY0XyA9IHJlcGVhdGVkRml4ZWQ2NF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbnQ2NF8gPSByZXBlYXRlZEludDY0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEZsb2F0XyA9IHJlcGVhdGVkRmxvYXRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFVpbnQ2NF8gPSByZXBlYXRlZFVpbnQ2NF87CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRGaXhlZDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEZpeGVkMzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfID0gb3RoZXIucmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZEZpeGVkMzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEludDMyXyA9IG90aGVyLnJlcGVhdGVkSW50MzJfOwogICAgICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkRml4ZWQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRGaXhlZDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0XyA9IG90aGVyLnJlcGVhdGVkRml4ZWQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRGaXhlZDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEludDY0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8gPSBvdGhlci5yZXBlYXRlZEludDY0XzsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEludDY0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEZsb2F0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEZsb2F0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8gPSBvdGhlci5yZXBlYXRlZEZsb2F0XzsKICAgICAgICAgICAgcmVwZWF0ZWRGbG9hdF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkRmxvYXRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEZsb2F0Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFVpbnQ2NF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRVaW50NjRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBvdGhlci5yZXBlYXRlZFVpbnQ2NF87CiAgICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRVaW50NjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwMTogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkRml4ZWQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZpeGVkMzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMDEKICAgICAgICAgICAgICBjYXNlIDk4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKGFsbG9jIC8gNCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uYWRkSW50KGlucHV0LnJlYWRGaXhlZDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDk4CiAgICAgICAgICAgICAgY2FzZSAxMDQ6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA0CiAgICAgICAgICAgICAgY2FzZSAxMDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQoaW5wdXQucmVhZEludDMyKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNgogICAgICAgICAgICAgIGNhc2UgMTYzNjk6IHsKICAgICAgICAgICAgICAgIGxvbmcgdiA9IGlucHV0LnJlYWRGaXhlZDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjM2OQogICAgICAgICAgICAgIGNhc2UgMTYzNzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoYWxsb2MgLyA4KTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5hZGRMb25nKGlucHV0LnJlYWRGaXhlZDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2MzcwCiAgICAgICAgICAgICAgY2FzZSAxNjM3NjogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2Mzc2CiAgICAgICAgICAgICAgY2FzZSAxNjM3ODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZExvbmcoaW5wdXQucmVhZEludDY0KCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2Mzc4CiAgICAgICAgICAgICAgY2FzZSAyMDk3MTQxOiB7CiAgICAgICAgICAgICAgICBmbG9hdCB2ID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMDk3MTQxCiAgICAgICAgICAgICAgY2FzZSAyMDk3MTM4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZShhbGxvYyAvIDQpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEZsb2F0Xy5hZGRGbG9hdChpbnB1dC5yZWFkRmxvYXQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjA5NzEzOAogICAgICAgICAgICAgIGNhc2UgMjA5NzE0NDogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZFVJbnQ2NCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkVWludDY0Xy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIwOTcxNDQKICAgICAgICAgICAgICBjYXNlIDIwOTcxNDY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRVaW50NjRfLmFkZExvbmcoaW5wdXQucmVhZFVJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMDk3MTQ2CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkRml4ZWQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcmVwZWF0ZWRGaXhlZDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZpeGVkMzJfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUGFyc2luZyByZXBlYXRlZCBmaXhlZCBzaXplIHZhbHVlcyB1c2VkIHRvIGZhaWwuIFRoaXMgbWVzc2FnZSBuZWVkcyB0byBiZQogICAgICAgKiB1c2VkIGluIG9yZGVyIHRvIGdldCBhIHRhZyBvZiB0aGUgcmlnaHQgc2l6ZTsgYWxsIG9mIHRoZSByZXBlYXRlZCBmaWVsZHMKICAgICAgICogaW4gVGVzdEFsbFR5cGVzIGRpZG4ndCB0cmlnZ2VyIHRoZSBjaGVjay4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRGaXhlZDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEZpeGVkMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUGFyc2luZyByZXBlYXRlZCBmaXhlZCBzaXplIHZhbHVlcyB1c2VkIHRvIGZhaWwuIFRoaXMgbWVzc2FnZSBuZWVkcyB0byBiZQogICAgICAgKiB1c2VkIGluIG9yZGVyIHRvIGdldCBhIHRhZyBvZiB0aGUgcmlnaHQgc2l6ZTsgYWxsIG9mIHRoZSByZXBlYXRlZCBmaWVsZHMKICAgICAgICogaW4gVGVzdEFsbFR5cGVzIGRpZG4ndCB0cmlnZ2VyIHRoZSBjaGVjay4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDMyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFBhcnNpbmcgcmVwZWF0ZWQgZml4ZWQgc2l6ZSB2YWx1ZXMgdXNlZCB0byBmYWlsLiBUaGlzIG1lc3NhZ2UgbmVlZHMgdG8gYmUKICAgICAgICogdXNlZCBpbiBvcmRlciB0byBnZXQgYSB0YWcgb2YgdGhlIHJpZ2h0IHNpemU7IGFsbCBvZiB0aGUgcmVwZWF0ZWQgZmllbGRzCiAgICAgICAqIGluIFRlc3RBbGxUeXBlcyBkaWRuJ3QgdHJpZ2dlciB0aGUgY2hlY2suCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDMyIHJlcGVhdGVkX2ZpeGVkMzIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZpeGVkMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkMzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRml4ZWQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUGFyc2luZyByZXBlYXRlZCBmaXhlZCBzaXplIHZhbHVlcyB1c2VkIHRvIGZhaWwuIFRoaXMgbWVzc2FnZSBuZWVkcyB0byBiZQogICAgICAgKiB1c2VkIGluIG9yZGVyIHRvIGdldCBhIHRhZyBvZiB0aGUgcmlnaHQgc2l6ZTsgYWxsIG9mIHRoZSByZXBlYXRlZCBmaWVsZHMKICAgICAgICogaW4gVGVzdEFsbFR5cGVzIGRpZG4ndCB0cmlnZ2VyIHRoZSBjaGVjay4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDEyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRml4ZWQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkRml4ZWQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBQYXJzaW5nIHJlcGVhdGVkIGZpeGVkIHNpemUgdmFsdWVzIHVzZWQgdG8gZmFpbC4gVGhpcyBtZXNzYWdlIG5lZWRzIHRvIGJlCiAgICAgICAqIHVzZWQgaW4gb3JkZXIgdG8gZ2V0IGEgdGFnIG9mIHRoZSByaWdodCBzaXplOyBhbGwgb2YgdGhlIHJlcGVhdGVkIGZpZWxkcwogICAgICAgKiBpbiBUZXN0QWxsVHlwZXMgZGlkbid0IHRyaWdnZXIgdGhlIGNoZWNrLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQzMiByZXBlYXRlZF9maXhlZDMyID0gMTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRml4ZWQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRml4ZWQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUGFyc2luZyByZXBlYXRlZCBmaXhlZCBzaXplIHZhbHVlcyB1c2VkIHRvIGZhaWwuIFRoaXMgbWVzc2FnZSBuZWVkcyB0byBiZQogICAgICAgKiB1c2VkIGluIG9yZGVyIHRvIGdldCBhIHRhZyBvZiB0aGUgcmlnaHQgc2l6ZTsgYWxsIG9mIHRoZSByZXBlYXRlZCBmaWVsZHMKICAgICAgICogaW4gVGVzdEFsbFR5cGVzIGRpZG4ndCB0cmlnZ2VyIHRoZSBjaGVjay4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDEyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRGaXhlZDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGaXhlZDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRml4ZWQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogUGFyc2luZyByZXBlYXRlZCBmaXhlZCBzaXplIHZhbHVlcyB1c2VkIHRvIGZhaWwuIFRoaXMgbWVzc2FnZSBuZWVkcyB0byBiZQogICAgICAgKiB1c2VkIGluIG9yZGVyIHRvIGdldCBhIHRhZyBvZiB0aGUgcmlnaHQgc2l6ZTsgYWxsIG9mIHRoZSByZXBlYXRlZCBmaWVsZHMKICAgICAgICogaW4gVGVzdEFsbFR5cGVzIGRpZG4ndCB0cmlnZ2VyIHRoZSBjaGVjay4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkMzIgcmVwZWF0ZWRfZml4ZWQzMiA9IDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZpeGVkMzIoKSB7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEludDMyXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRJbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIENoZWNrIGZvciBhIHZhcmludCB0eXBlLCBqdXN0IGZvciBnb29kIG1lYXN1cmUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkSW50MzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIENoZWNrIGZvciBhIHZhcmludCB0eXBlLCBqdXN0IGZvciBnb29kIG1lYXN1cmUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIENoZWNrIGZvciBhIHZhcmludCB0eXBlLCBqdXN0IGZvciBnb29kIG1lYXN1cmUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBDaGVjayBmb3IgYSB2YXJpbnQgdHlwZSwganVzdCBmb3IgZ29vZCBtZWFzdXJlLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRJbnQzMigKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDMyXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIENoZWNrIGZvciBhIHZhcmludCB0eXBlLCBqdXN0IGZvciBnb29kIG1lYXN1cmUuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBDaGVjayBmb3IgYSB2YXJpbnQgdHlwZSwganVzdCBmb3IgZ29vZCBtZWFzdXJlLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkSW50MzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEludDMyKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEludDMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBDaGVjayBmb3IgYSB2YXJpbnQgdHlwZSwganVzdCBmb3IgZ29vZCBtZWFzdXJlLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRJbnQzMigpIHsKICAgICAgICByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkRml4ZWQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEZpeGVkNjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkRml4ZWQ2NF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRml4ZWQ2NF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRGaXhlZDY0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGhhdmUgdHdvLWJ5dGUgdGFncy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDIwNDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEZpeGVkNjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZEZpeGVkNjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkRml4ZWQ2NF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEZpeGVkNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBoYXZlIHR3by1ieXRlIHRhZ3MuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAyMDQ2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRGaXhlZDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEZpeGVkNjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGhhdmUgdHdvLWJ5dGUgdGFncy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDIwNDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRGaXhlZDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkRml4ZWQ2NChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGaXhlZDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgaGF2ZSB0d28tYnl0ZSB0YWdzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMjA0Njs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpeGVkNjQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRGaXhlZDY0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGaXhlZDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaGVzZSBoYXZlIHR3by1ieXRlIHRhZ3MuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmaXhlZDY0IHJlcGVhdGVkX2ZpeGVkNjQgPSAyMDQ2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZpeGVkNjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpeGVkNjQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZpeGVkNjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhlc2UgaGF2ZSB0d28tYnl0ZSB0YWdzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZml4ZWQ2NCByZXBlYXRlZF9maXhlZDY0ID0gMjA0Njs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkRml4ZWQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkRml4ZWQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkRml4ZWQ2NElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEZpeGVkNjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRoZXNlIGhhdmUgdHdvLWJ5dGUgdGFncy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZpeGVkNjQgcmVwZWF0ZWRfZml4ZWQ2NCA9IDIwNDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkRml4ZWQ2NCgpIHsKICAgICAgICByZXBlYXRlZEZpeGVkNjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkSW50NjRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkSW50NjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEludDY0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyMDQ3OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFJlcGVhdGVkSW50NjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkSW50NjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMjA0Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50NjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50NjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIwNDc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQ2NCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDY0Xy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyMDQ3OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDY0KAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NCA9IDIwNDc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50NjRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjQgPSAyMDQ3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRJbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW50NjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW50NjRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0ID0gMjA0Nzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRJbnQ2NCgpIHsKICAgICAgICByZXBlYXRlZEludDY0XyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5GbG9hdExpc3QgcmVwZWF0ZWRGbG9hdF8gPSBlbXB0eUZsb2F0TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRmxvYXRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZsb2F0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZsb2F0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRGbG9hdElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkRmxvYXRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEZsb2F0XyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEZsb2F0XywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRocmVlIGJ5dGUgdGFncy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMjYyMTQyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRGbG9hdC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+CiAgICAgICAgICBnZXRSZXBlYXRlZEZsb2F0TGlzdCgpIHsKICAgICAgICByZXBlYXRlZEZsb2F0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkRmxvYXRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaHJlZSBieXRlIHRhZ3MuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDI2MjE0Mjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkRmxvYXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkRmxvYXRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRGbG9hdF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBUaHJlZSBieXRlIHRhZ3MuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBmbG9hdCByZXBlYXRlZF9mbG9hdCA9IDI2MjE0Mjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEZsb2F0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRSZXBlYXRlZEZsb2F0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEZsb2F0Xy5nZXRGbG9hdChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRocmVlIGJ5dGUgdGFncy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMjYyMTQyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkRmxvYXQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZsb2F0KAogICAgICAgICAgaW50IGluZGV4LCBmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8uc2V0RmxvYXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRocmVlIGJ5dGUgdGFncy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMjYyMTQyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEZsb2F0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGbG9hdChmbG9hdCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRGbG9hdF8uYWRkRmxvYXQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogVGhyZWUgYnl0ZSB0YWdzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZmxvYXQgcmVwZWF0ZWRfZmxvYXQgPSAyNjIxNDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEZsb2F0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRGbG9hdCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkZsb2F0PiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEZsb2F0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkRmxvYXRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFRocmVlIGJ5dGUgdGFncy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGZsb2F0IHJlcGVhdGVkX2Zsb2F0ID0gMjYyMTQyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEZsb2F0KCkgewogICAgICAgIHJlcGVhdGVkRmxvYXRfID0gZW1wdHlGbG9hdExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkVWludDY0Xy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRVaW50NjRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkVWludDY0Xyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDI2MjE0Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkVWludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRVaW50NjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkVWludDY0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkVWludDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgdWludDY0IHJlcGVhdGVkX3VpbnQ2NCA9IDI2MjE0Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkVWludDY0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVpbnQ2NENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMjYyMTQzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVWludDY0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFJlcGVhdGVkVWludDY0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVpbnQ2NF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHVpbnQ2NCByZXBlYXRlZF91aW50NjQgPSAyNjIxNDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRVaW50NjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFVpbnQ2NCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZFVpbnQ2NElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVWludDY0Xy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMjYyMTQzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFVpbnQ2NCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkVWludDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVaW50NjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMjYyMTQzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRVaW50NjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFVpbnQ2NCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkVWludDY0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkVWludDY0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCB1aW50NjQgcmVwZWF0ZWRfdWludDY0ID0gMjYyMTQzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFVpbnQ2NCgpIHsKICAgICAgICByZXBlYXRlZFVpbnQ2NF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RSZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RQYXJzaW5nTWVyZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhcnNpbmdNZXJnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxUZXN0UGFyc2luZ01lcmdlPiB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcXVpcmVkX2FsbF90eXBlcyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSByZXF1aXJlZEFsbFR5cGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNSZXF1aXJlZEFsbFR5cGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVxdWlyZWRfYWxsX3R5cGVzID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSByZXF1aXJlZEFsbFR5cGVzLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRSZXF1aXJlZEFsbFR5cGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVxdWlyZWRfYWxsX3R5cGVzID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcXVpcmVkQWxsVHlwZXNPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQWxsVHlwZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsQWxsVHlwZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE9wdGlvbmFsQWxsVHlwZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSAyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0T3B0aW9uYWxBbGxUeXBlc09yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAzOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IAogICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQWxsVHlwZXMoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAzOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDM7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbGdyb3VwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEdyb3VwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxncm91cC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAgZ2V0T3B0aW9uYWxHcm91cCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTAgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXBPckJ1aWxkZXIgZ2V0T3B0aW9uYWxHcm91cE9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwPiAKICAgICAgICBnZXRSZXBlYXRlZEdyb3VwTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAgZ2V0UmVwZWF0ZWRHcm91cChpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkR3JvdXBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZEdyb3VwT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXBPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRHcm91cE9yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRlc3QgdGhhdCBpZiBhbiBvcHRpb25hbCBvciByZXF1aXJlZCBtZXNzYWdlL2dyb3VwIGZpZWxkIGFwcGVhcnMgbXVsdGlwbGUKICAgKiB0aW1lcyBpbiB0aGUgaW5wdXQsIHRoZXkgbmVlZCB0byBiZSBtZXJnZWQuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFBhcnNpbmdNZXJnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVNZXNzYWdlPAogICAgICAgIFRlc3RQYXJzaW5nTWVyZ2U+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlKQogICAgICBUZXN0UGFyc2luZ01lcmdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0UGFyc2luZ01lcmdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RQYXJzaW5nTWVyZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0UGFyc2luZ01lcmdlKCkgewogICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRHcm91cF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFBhcnNpbmdNZXJnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBSZXBlYXRlZEZpZWxkc0dlbmVyYXRvck9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IAogICAgICAgICAgZ2V0RmllbGQxTGlzdCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldEZpZWxkMShpbnQgaW5kZXgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIGludCBnZXRGaWVsZDFDb3VudCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZDFPckJ1aWxkZXJMaXN0KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0RmllbGQxT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KTsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IAogICAgICAgICAgZ2V0RmllbGQyTGlzdCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldEZpZWxkMihpbnQgaW5kZXgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIGludCBnZXRGaWVsZDJDb3VudCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZDJPckJ1aWxkZXJMaXN0KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0RmllbGQyT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KTsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IAogICAgICAgICAgZ2V0RmllbGQzTGlzdCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldEZpZWxkMyhpbnQgaW5kZXgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIGludCBnZXRGaWVsZDNDb3VudCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZDNPckJ1aWxkZXJMaXN0KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0RmllbGQzT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KTsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDEgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMT4gCiAgICAgICAgICBnZXRHcm91cDFMaXN0KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDEgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSBnZXRHcm91cDEoaW50IGluZGV4KTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMSA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBpbnQgZ2V0R3JvdXAxQ291bnQoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMSA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRHcm91cDFPckJ1aWxkZXJMaXN0KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDEgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMU9yQnVpbGRlciBnZXRHcm91cDFPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMiA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyPiAKICAgICAgICAgIGdldEdyb3VwMkxpc3QoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMiA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIGdldEdyb3VwMihpbnQgaW5kZXgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAyID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIGludCBnZXRHcm91cDJDb3VudCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAyID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEdyb3VwMk9yQnVpbGRlckxpc3QoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMiA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyT3JCdWlsZGVyIGdldEdyb3VwMk9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCk7CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQxID0gMTAwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gCiAgICAgICAgICBnZXRFeHQxTGlzdCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQxID0gMTAwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRFeHQxKGludCBpbmRleCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDEgPSAxMDAwOzwvY29kZT4KICAgICAgICovCiAgICAgIGludCBnZXRFeHQxQ291bnQoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MSA9IDEwMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEV4dDFPckJ1aWxkZXJMaXN0KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDEgPSAxMDAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldEV4dDFPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MiA9IDEwMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IAogICAgICAgICAgZ2V0RXh0Mkxpc3QoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MiA9IDEwMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0RXh0MihpbnQgaW5kZXgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQyID0gMTAwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBpbnQgZ2V0RXh0MkNvdW50KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDIgPSAxMDAxOzwvY29kZT4KICAgICAgICovCiAgICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRFeHQyT3JCdWlsZGVyTGlzdCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQyID0gMTAwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRFeHQyT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIGRlZmluZXMgbWF0Y2hpbmcgZmllbGQgdHlwZXMgYXMgVGVzdFBhcnNpbmdNZXJnZSwKICAgICAqIGV4Y2VwdCB0aGF0IGFsbCBmaWVsZHMgYXJlIHJlcGVhdGVkLiBJbiB0aGUgdGVzdHMsIHdlIHdpbGwgc2VyaWFsaXplIHRoZQogICAgICogUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgdG8gYnl0ZXMsIGFuZCBwYXJzZSB0aGUgYnl0ZXMgdG8gVGVzdFBhcnNpbmdNZXJnZS4KICAgICAqIFJlcGVhdGVkIGZpZWxkcyBpbiBSZXBlYXRlZEZpZWxkc0dlbmVyYXRvciBhcmUgZXhwZWN0ZWQgdG8gYmUgbWVyZ2VkIGludG8KICAgICAqIHRoZSBjb3JyZXNwb25kaW5nIHJlcXVpcmVkL29wdGlvbmFsIGZpZWxkcyBpbiBUZXN0UGFyc2luZ01lcmdlLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvcn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBSZXBlYXRlZEZpZWxkc0dlbmVyYXRvciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvcikKICAgICAgICBSZXBlYXRlZEZpZWxkc0dlbmVyYXRvck9yQnVpbGRlciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgLy8gVXNlIFJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBSZXBlYXRlZEZpZWxkc0dlbmVyYXRvcigpIHsKICAgICAgICBmaWVsZDFfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGZpZWxkMl8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgZmllbGQzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBncm91cDFfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGdyb3VwMl8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgZXh0MV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgZXh0Ml8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9SZXBlYXRlZEZpZWxkc0dlbmVyYXRvcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHVibGljIGludGVyZmFjZSBHcm91cDFPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxKQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDEgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIGJvb2xlYW4gaGFzRmllbGQxKCk7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgZmllbGQxLgogICAgICAgICAqLwogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldEZpZWxkMSgpOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMTE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldEZpZWxkMU9yQnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMX0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgR3JvdXAxIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEpCiAgICAgICAgICBHcm91cDFPckJ1aWxkZXIgewogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgICAvLyBVc2UgR3JvdXAxLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgICAgcHJpdmF0ZSBHcm91cDEoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBHcm91cDEoKSB7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICAgIHJldHVybiBuZXcgR3JvdXAxKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfR3JvdXAxX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX1JlcGVhdGVkRmllbGRzR2VuZXJhdG9yX0dyb3VwMV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTEQxX0ZJRUxEX05VTUJFUiA9IDExOwogICAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZmllbGQxXzsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDExOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkMSBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkMSgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxMTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgZmllbGQxLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0RmllbGQxKCkgewogICAgICAgICAgcmV0dXJuIGZpZWxkMV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGQxXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRGaWVsZDFPckJ1aWxkZXIoKSB7CiAgICAgICAgICByZXR1cm4gZmllbGQxXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZDFfOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxMSwgZ2V0RmllbGQxKCkpOwogICAgICAgICAgfQogICAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMSwgZ2V0RmllbGQxKCkpOwogICAgICAgICAgfQogICAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgfQogICAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSkpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgICAgfQogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxKSBvYmo7CgogICAgICAgICAgaWYgKGhhc0ZpZWxkMSgpICE9IG90aGVyLmhhc0ZpZWxkMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBpZiAoaGFzRmllbGQxKCkpIHsKICAgICAgICAgICAgaWYgKCFnZXRGaWVsZDEoKQogICAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZDEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICAgIH0KICAgICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGlmIChoYXNGaWVsZDEoKSkgewogICAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRDFfRklFTERfTlVNQkVSOwogICAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZDEoKS5oYXNoQ29kZSgpOwogICAgICAgICAgfQogICAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICAgIHJldHVybiBoYXNoOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxIHBhcnNlRnJvbSgKICAgICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSBwYXJzZUZyb20oCiAgICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSBwYXJzZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSBwYXJzZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEgcGFyc2VGcm9tKAogICAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEgcGFyc2VGcm9tKAogICAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSBwYXJzZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEgcGFyc2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSBwcm90b3R5cGUpIHsKICAgICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMX0KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSkKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMU9yQnVpbGRlciB7CiAgICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX1JlcGVhdGVkRmllbGRzR2VuZXJhdG9yX0dyb3VwMV9kZXNjcmlwdG9yOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfR3JvdXAxX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5CdWlsZGVyLmNsYXNzKTsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5uZXdCdWlsZGVyKCkKICAgICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICAgICAgfQoKICAgICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgICAgICBnZXRGaWVsZDFGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgICBmaWVsZDFfID0gbnVsbDsKICAgICAgICAgICAgaWYgKGZpZWxkMUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgICBmaWVsZDFCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgZmllbGQxQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfR3JvdXAxX2Rlc2NyaXB0b3I7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEgYnVpbGQoKSB7CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEodGhpcyk7CiAgICAgICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgIH0KCiAgICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxIHJlc3VsdCkgewogICAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICAgIHJlc3VsdC5maWVsZDFfID0gZmllbGQxQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgICAgICA/IGZpZWxkMV8KICAgICAgICAgICAgICAgICAgOiBmaWVsZDFCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSkgewogICAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEpb3RoZXIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSBvdGhlcikgewogICAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIGlmIChvdGhlci5oYXNGaWVsZDEoKSkgewogICAgICAgICAgICAgIG1lcmdlRmllbGQxKG90aGVyLmdldEZpZWxkMSgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICBjYXNlIDkwOiB7CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpZWxkMUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgfSAvLyBjYXNlIDkwCiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBmaWVsZDFfOwogICAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gZmllbGQxQnVpbGRlcl87CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMTE7PC9jb2RlPgogICAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDEgZmllbGQgaXMgc2V0LgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZDEoKSB7CiAgICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICAgIH0KICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxMTs8L2NvZGU+CiAgICAgICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDEuCiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRGaWVsZDEoKSB7CiAgICAgICAgICAgIGlmIChmaWVsZDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgcmV0dXJuIGZpZWxkMV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGQxXzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXR1cm4gZmllbGQxQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMTE7PC9jb2RlPgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZDEocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICAgICAgaWYgKGZpZWxkMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGZpZWxkMV8gPSB2YWx1ZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBmaWVsZDFCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxMTs8L2NvZGU+CiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkMSgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgICBpZiAoZmllbGQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgIGZpZWxkMV8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBmaWVsZDFCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxMTs8L2NvZGU+CiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRmllbGQxKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgICAgIGlmIChmaWVsZDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApICYmCiAgICAgICAgICAgICAgICBmaWVsZDFfICE9IG51bGwgJiYKICAgICAgICAgICAgICAgIGZpZWxkMV8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgICAgIGdldEZpZWxkMUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmaWVsZDFfID0gdmFsdWU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGZpZWxkMUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGZpZWxkMV8gIT0gbnVsbCkgewogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxMTs8L2NvZGU+CiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQxKCkgewogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICAgIGZpZWxkMV8gPSBudWxsOwogICAgICAgICAgICBpZiAoZmllbGQxQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICAgIGZpZWxkMUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICBmaWVsZDFCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgICAgLyoqCiAgICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDExOzwvY29kZT4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0RmllbGQxQnVpbGRlcigpIHsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIGdldEZpZWxkMUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgICAgIH0KICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxMTs8L2NvZGU+CiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRGaWVsZDFPckJ1aWxkZXIoKSB7CiAgICAgICAgICAgIGlmIChmaWVsZDFCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICAgICAgcmV0dXJuIGZpZWxkMUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXR1cm4gZmllbGQxXyA9PSBudWxsID8KICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZDFfOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMTE7PC9jb2RlPgogICAgICAgICAgICovCiAgICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICAgICBnZXRGaWVsZDFGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgICAgIGlmIChmaWVsZDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgZmllbGQxQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgICAgIGdldEZpZWxkMSgpLAogICAgICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICAgICAgZmllbGQxXyA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGZpZWxkMUJ1aWxkZXJfOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgICB9CgoKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxKQogICAgICAgIH0KCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxKQogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgICBzdGF0aWMgewogICAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxHcm91cDE+CiAgICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEdyb3VwMT4oKSB7CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgR3JvdXAxIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8R3JvdXAxPiBwYXJzZXIoKSB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxHcm91cDE+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgICB9CgogICAgICB9CgogICAgICBwdWJsaWMgaW50ZXJmYWNlIEdyb3VwMk9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIpCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDIxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkMSBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgYm9vbGVhbiBoYXNGaWVsZDEoKTsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDIxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDEuCiAgICAgICAgICovCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0RmllbGQxKCk7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAyMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0RmllbGQxT3JCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBHcm91cDIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMikKICAgICAgICAgIEdyb3VwMk9yQnVpbGRlciB7CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAgIC8vIFVzZSBHcm91cDIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgICBwcml2YXRlIEdyb3VwMihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIEdyb3VwMigpIHsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgICAgcmV0dXJuIG5ldyBHcm91cDIoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9SZXBlYXRlZEZpZWxkc0dlbmVyYXRvcl9Hcm91cDJfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfR3JvdXAyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRDFfRklFTERfTlVNQkVSID0gMjE7CiAgICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBmaWVsZDFfOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMjE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQxIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGQxKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDIxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDEuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRGaWVsZDEoKSB7CiAgICAgICAgICByZXR1cm4gZmllbGQxXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBmaWVsZDFfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDIxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldEZpZWxkMU9yQnVpbGRlcigpIHsKICAgICAgICAgIHJldHVybiBmaWVsZDFfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkMV87CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIxLCBnZXRGaWVsZDEoKSk7CiAgICAgICAgICB9CiAgICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgICBzaXplID0gMDsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIxLCBnZXRGaWVsZDEoKSk7CiAgICAgICAgICB9CiAgICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICAgIHJldHVybiBzaXplOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyKSkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgICB9CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIpIG9iajsKCiAgICAgICAgICBpZiAoaGFzRmllbGQxKCkgIT0gb3RoZXIuaGFzRmllbGQxKCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGlmIChoYXNGaWVsZDEoKSkgewogICAgICAgICAgICBpZiAoIWdldEZpZWxkMSgpCiAgICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEZpZWxkMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgICAgfQogICAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgICAgaWYgKGhhc0ZpZWxkMSgpKSB7CiAgICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkMSgpLmhhc2hDb2RlKCk7CiAgICAgICAgICB9CiAgICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIgcGFyc2VGcm9tKAogICAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIHBhcnNlRnJvbSgKICAgICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMiBwYXJzZUZyb20oCiAgICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMiBwYXJzZUZyb20oCiAgICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMiBwYXJzZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIHByb3RvdHlwZSkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyfQogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyKQogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyT3JCdWlsZGVyIHsKICAgICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfR3JvdXAyX2Rlc2NyaXB0b3I7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9SZXBlYXRlZEZpZWxkc0dlbmVyYXRvcl9Hcm91cDJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyLm5ld0J1aWxkZXIoKQogICAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgICAgICB9CgogICAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgICAgIGdldEZpZWxkMUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICAgIGZpZWxkMV8gPSBudWxsOwogICAgICAgICAgICBpZiAoZmllbGQxQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICAgIGZpZWxkMUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICBmaWVsZDFCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9SZXBlYXRlZEZpZWxkc0dlbmVyYXRvcl9Hcm91cDJfZGVzY3JpcHRvcjsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMiBidWlsZCgpIHsKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMih0aGlzKTsKICAgICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgfQoKICAgICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIgcmVzdWx0KSB7CiAgICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgICAgcmVzdWx0LmZpZWxkMV8gPSBmaWVsZDFCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgICAgID8gZmllbGQxXwogICAgICAgICAgICAgICAgICA6IGZpZWxkMUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMilvdGhlcik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIG90aGVyKSB7CiAgICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkMSgpKSB7CiAgICAgICAgICAgICAgbWVyZ2VGaWVsZDEob3RoZXIuZ2V0RmllbGQxKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIGNhc2UgMTcwOiB7CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpZWxkMUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgfSAvLyBjYXNlIDE3MAogICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZmllbGQxXzsKICAgICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IGZpZWxkMUJ1aWxkZXJfOwogICAgICAgICAgLyoqCiAgICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDIxOzwvY29kZT4KICAgICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQxIGZpZWxkIGlzIHNldC4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGQxKCkgewogICAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMjE7PC9jb2RlPgogICAgICAgICAgICogQHJldHVybiBUaGUgZmllbGQxLgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0RmllbGQxKCkgewogICAgICAgICAgICBpZiAoZmllbGQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgIHJldHVybiBmaWVsZDFfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGZpZWxkMV87CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmV0dXJuIGZpZWxkMUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgLyoqCiAgICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDIxOzwvY29kZT4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQxKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgICAgIGlmIChmaWVsZDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBmaWVsZDFfID0gdmFsdWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZmllbGQxQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMjE7PC9jb2RlPgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZDEoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgICAgaWYgKGZpZWxkMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICBmaWVsZDFfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZmllbGQxQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMjE7PC9jb2RlPgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZpZWxkMShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgICAgICBpZiAoZmllbGQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICAgICAgZmllbGQxXyAhPSBudWxsICYmCiAgICAgICAgICAgICAgICBmaWVsZDFfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgICAgICBnZXRGaWVsZDFCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZmllbGQxXyA9IHZhbHVlOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBmaWVsZDFCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChmaWVsZDFfICE9IG51bGwpIHsKICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMjE7PC9jb2RlPgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkMSgpIHsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgICBmaWVsZDFfID0gbnVsbDsKICAgICAgICAgICAgaWYgKGZpZWxkMUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgICBmaWVsZDFCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgZmllbGQxQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAyMTs8L2NvZGU+CiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldEZpZWxkMUJ1aWxkZXIoKSB7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIHJldHVybiBnZXRGaWVsZDFGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMjE7PC9jb2RlPgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0RmllbGQxT3JCdWlsZGVyKCkgewogICAgICAgICAgICBpZiAoZmllbGQxQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICAgIHJldHVybiBmaWVsZDFCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmV0dXJuIGZpZWxkMV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogZmllbGQxXzsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgLyoqCiAgICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDIxOzwvY29kZT4KICAgICAgICAgICAqLwogICAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICAgICAgZ2V0RmllbGQxRmllbGRCdWlsZGVyKCkgewogICAgICAgICAgICBpZiAoZmllbGQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgIGZpZWxkMUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgICAgICBnZXRGaWVsZDEoKSwKICAgICAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgICAgIGZpZWxkMV8gPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBmaWVsZDFCdWlsZGVyXzsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgICAgfQoKCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMikKICAgICAgICB9CgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMikKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgICAgc3RhdGljIHsKICAgICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMigpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8R3JvdXAyPgogICAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxHcm91cDI+KCkgewogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEdyb3VwMiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEdyb3VwMj4gcGFyc2VyKCkgewogICAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8R3JvdXAyPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgICAgfQoKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTEQxX0ZJRUxEX05VTUJFUiA9IDE7CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBmaWVsZDFfOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBnZXRGaWVsZDFMaXN0KCkgewogICAgICAgIHJldHVybiBmaWVsZDFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEZpZWxkMU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGQxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkMV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0RmllbGQxKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZDFfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRGaWVsZDFPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGQxXy5nZXQoaW5kZXgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRDJfRklFTERfTlVNQkVSID0gMjsKICAgICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGZpZWxkMl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGdldEZpZWxkMkxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RmllbGQyT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZmllbGQyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZDJDb3VudCgpIHsKICAgICAgICByZXR1cm4gZmllbGQyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRGaWVsZDIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkMl8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldEZpZWxkMk9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBmaWVsZDJfLmdldChpbmRleCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEM19GSUVMRF9OVU1CRVIgPSAzOwogICAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZmllbGQzXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQzID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0RmllbGQzTGlzdCgpIHsKICAgICAgICByZXR1cm4gZmllbGQzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRGaWVsZDNPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBmaWVsZDNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkM0NvdW50KCkgewogICAgICAgIHJldHVybiBmaWVsZDNfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldEZpZWxkMyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZmllbGQzXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0RmllbGQzT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGZpZWxkM18uZ2V0KGluZGV4KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgR1JPVVAxX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxPiBncm91cDFfOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAxID0gMTAgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDE+IGdldEdyb3VwMUxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdyb3VwMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMSA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMU9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRHcm91cDFPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBncm91cDFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDEgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEdyb3VwMUNvdW50KCkgewogICAgICAgIHJldHVybiBncm91cDFfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAxID0gMTAgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEgZ2V0R3JvdXAxKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBncm91cDFfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMSA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxT3JCdWlsZGVyIGdldEdyb3VwMU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBncm91cDFfLmdldChpbmRleCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEdST1VQMl9GSUVMRF9OVU1CRVIgPSAyMDsKICAgICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMj4gZ3JvdXAyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMiA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyPiBnZXRHcm91cDJMaXN0KCkgewogICAgICAgIHJldHVybiBncm91cDJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDIgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDJPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0R3JvdXAyT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ3JvdXAyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAyID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRHcm91cDJDb3VudCgpIHsKICAgICAgICByZXR1cm4gZ3JvdXAyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMiA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIGdldEdyb3VwMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ3JvdXAyXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDIgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMk9yQnVpbGRlciBnZXRHcm91cDJPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ3JvdXAyXy5nZXQoaW5kZXgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFWFQxX0ZJRUxEX05VTUJFUiA9IDEwMDA7CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBleHQxXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MSA9IDEwMDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGdldEV4dDFMaXN0KCkgewogICAgICAgIHJldHVybiBleHQxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQxID0gMTAwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0RXh0MU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGV4dDFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDEgPSAxMDAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRFeHQxQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGV4dDFfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQxID0gMTAwMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRFeHQxKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBleHQxXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDEgPSAxMDAwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldEV4dDFPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZXh0MV8uZ2V0KGluZGV4KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVhUMl9GSUVMRF9OVU1CRVIgPSAxMDAxOwogICAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZXh0Ml87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDIgPSAxMDAxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBnZXRFeHQyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZXh0Ml87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MiA9IDEwMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEV4dDJPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBleHQyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQyID0gMTAwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RXh0MkNvdW50KCkgewogICAgICAgIHJldHVybiBleHQyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MiA9IDEwMDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0RXh0MihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZXh0Ml8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQyID0gMTAwMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRFeHQyT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGV4dDJfLmdldChpbmRleCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZDFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEsIGZpZWxkMV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZDJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDIsIGZpZWxkMl8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZDNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDMsIGZpZWxkM18uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBncm91cDFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVHcm91cCgxMCwgZ3JvdXAxXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdyb3VwMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIG91dHB1dC53cml0ZUdyb3VwKDIwLCBncm91cDJfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZXh0MV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTAwMCwgZXh0MV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHQyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxMDAxLCBleHQyXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGZpZWxkMV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEsIGZpZWxkMV8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZDJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgyLCBmaWVsZDJfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZmllbGQzXy5zaXplKCk7IGkrKykgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMywgZmllbGQzXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdyb3VwMV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUdyb3VwU2l6ZSgxMCwgZ3JvdXAxXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGdyb3VwMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUdyb3VwU2l6ZSgyMCwgZ3JvdXAyXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGV4dDFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDAwLCBleHQxXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGV4dDJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMDAxLCBleHQyXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IpKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvciBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IpIG9iajsKCiAgICAgICAgaWYgKCFnZXRGaWVsZDFMaXN0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZDFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKCFnZXRGaWVsZDJMaXN0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZDJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKCFnZXRGaWVsZDNMaXN0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRGaWVsZDNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKCFnZXRHcm91cDFMaXN0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRHcm91cDFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKCFnZXRHcm91cDJMaXN0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRHcm91cDJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKCFnZXRFeHQxTGlzdCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0RXh0MUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoIWdldEV4dDJMaXN0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRFeHQyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoZ2V0RmllbGQxQ291bnQoKSA+IDApIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZDFMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGdldEZpZWxkMkNvdW50KCkgPiAwKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRDJfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGQyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgICAgfQogICAgICAgIGlmIChnZXRGaWVsZDNDb3VudCgpID4gMCkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTEQzX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkM0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoZ2V0R3JvdXAxQ291bnQoKSA+IDApIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEdST1VQMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRHcm91cDFMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGdldEdyb3VwMkNvdW50KCkgPiAwKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBHUk9VUDJfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0R3JvdXAyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgICAgfQogICAgICAgIGlmIChnZXRFeHQxQ291bnQoKSA+IDApIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEVYVDFfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RXh0MUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoZ2V0RXh0MkNvdW50KCkgPiAwKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBFWFQyX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEV4dDJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvciBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvciBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvciBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIGRlZmluZXMgbWF0Y2hpbmcgZmllbGQgdHlwZXMgYXMgVGVzdFBhcnNpbmdNZXJnZSwKICAgICAgICogZXhjZXB0IHRoYXQgYWxsIGZpZWxkcyBhcmUgcmVwZWF0ZWQuIEluIHRoZSB0ZXN0cywgd2Ugd2lsbCBzZXJpYWxpemUgdGhlCiAgICAgICAqIFJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIHRvIGJ5dGVzLCBhbmQgcGFyc2UgdGhlIGJ5dGVzIHRvIFRlc3RQYXJzaW5nTWVyZ2UuCiAgICAgICAqIFJlcGVhdGVkIGZpZWxkcyBpbiBSZXBlYXRlZEZpZWxkc0dlbmVyYXRvciBhcmUgZXhwZWN0ZWQgdG8gYmUgbWVyZ2VkIGludG8KICAgICAgICogdGhlIGNvcnJlc3BvbmRpbmcgcmVxdWlyZWQvb3B0aW9uYWwgZmllbGRzIGluIFRlc3RQYXJzaW5nTWVyZ2UuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yKQogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGlmIChmaWVsZDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGZpZWxkMV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZDFfID0gbnVsbDsKICAgICAgICAgICAgZmllbGQxQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIGlmIChmaWVsZDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGZpZWxkMl8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZDJfID0gbnVsbDsKICAgICAgICAgICAgZmllbGQyQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICAgIGlmIChmaWVsZDNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGZpZWxkM18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZDNfID0gbnVsbDsKICAgICAgICAgICAgZmllbGQzQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICAgIGlmIChncm91cDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGdyb3VwMV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBncm91cDFfID0gbnVsbDsKICAgICAgICAgICAgZ3JvdXAxQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICAgIGlmIChncm91cDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGdyb3VwMl8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBncm91cDJfID0gbnVsbDsKICAgICAgICAgICAgZ3JvdXAyQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICAgIGlmIChleHQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBleHQxXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGV4dDFfID0gbnVsbDsKICAgICAgICAgICAgZXh0MUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgICB9CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgICBpZiAoZXh0MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZXh0Ml8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBleHQyXyA9IG51bGw7CiAgICAgICAgICAgIGV4dDJCdWlsZGVyXy5jbGVhcigpOwogICAgICAgICAgfQogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX1JlcGVhdGVkRmllbGRzR2VuZXJhdG9yX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIGJ1aWxkKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IodGhpcyk7CiAgICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIHJlc3VsdCkgewogICAgICAgICAgaWYgKGZpZWxkMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgICAgZmllbGQxXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkMV8pOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXN1bHQuZmllbGQxXyA9IGZpZWxkMV87CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHQuZmllbGQxXyA9IGZpZWxkMUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoZmllbGQyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgICAgICBmaWVsZDJfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZmllbGQyXyk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3VsdC5maWVsZDJfID0gZmllbGQyXzsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlc3VsdC5maWVsZDJfID0gZmllbGQyQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChmaWVsZDNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgICAgIGZpZWxkM18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChmaWVsZDNfKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzdWx0LmZpZWxkM18gPSBmaWVsZDNfOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVzdWx0LmZpZWxkM18gPSBmaWVsZDNCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGdyb3VwMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICAgICAgZ3JvdXAxXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGdyb3VwMV8pOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXN1bHQuZ3JvdXAxXyA9IGdyb3VwMV87CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHQuZ3JvdXAxXyA9IGdyb3VwMUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoZ3JvdXAyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgICAgICBncm91cDJfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZ3JvdXAyXyk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3VsdC5ncm91cDJfID0gZ3JvdXAyXzsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlc3VsdC5ncm91cDJfID0gZ3JvdXAyQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChleHQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgICAgICBleHQxXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGV4dDFfKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzdWx0LmV4dDFfID0gZXh0MV87CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHQuZXh0MV8gPSBleHQxQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChleHQyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgICAgICBleHQyXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGV4dDJfKTsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzdWx0LmV4dDJfID0gZXh0Ml87CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHQuZXh0Ml8gPSBleHQyQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvciByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvcilvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3Igb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKGZpZWxkMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCFvdGhlci5maWVsZDFfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGlmIChmaWVsZDFfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgZmllbGQxXyA9IG90aGVyLmZpZWxkMV87CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZmllbGQxXy5hZGRBbGwob3RoZXIuZmllbGQxXyk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoIW90aGVyLmZpZWxkMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgaWYgKGZpZWxkMUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgZmllbGQxQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgICAgZmllbGQxQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgICAgZmllbGQxXyA9IG90aGVyLmZpZWxkMV87CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICAgICAgICBmaWVsZDFCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgICAgZ2V0RmllbGQxRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmaWVsZDFCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5maWVsZDFfKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGlmIChmaWVsZDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICghb3RoZXIuZmllbGQyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBpZiAoZmllbGQyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGZpZWxkMl8gPSBvdGhlci5maWVsZDJfOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBlbnN1cmVGaWVsZDJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGZpZWxkMl8uYWRkQWxsKG90aGVyLmZpZWxkMl8pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCFvdGhlci5maWVsZDJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGlmIChmaWVsZDJCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGZpZWxkMkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICAgIGZpZWxkMkJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICAgIGZpZWxkMl8gPSBvdGhlci5maWVsZDJfOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICAgICAgZmllbGQyQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICAgIGdldEZpZWxkMkZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZmllbGQyQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIuZmllbGQyXyk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoZmllbGQzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAoIW90aGVyLmZpZWxkM18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgaWYgKGZpZWxkM18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBmaWVsZDNfID0gb3RoZXIuZmllbGQzXzsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZW5zdXJlRmllbGQzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBmaWVsZDNfLmFkZEFsbChvdGhlci5maWVsZDNfKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICghb3RoZXIuZmllbGQzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBpZiAoZmllbGQzQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBmaWVsZDNCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgICBmaWVsZDNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgICBmaWVsZDNfID0gb3RoZXIuZmllbGQzXzsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICAgICAgICAgIGZpZWxkM0J1aWxkZXJfID0gCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgICBnZXRGaWVsZDNGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGZpZWxkM0J1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLmZpZWxkM18pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgaWYgKGdyb3VwMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCFvdGhlci5ncm91cDFfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGlmIChncm91cDFfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgZ3JvdXAxXyA9IG90aGVyLmdyb3VwMV87CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGVuc3VyZUdyb3VwMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZ3JvdXAxXy5hZGRBbGwob3RoZXIuZ3JvdXAxXyk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoIW90aGVyLmdyb3VwMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgaWYgKGdyb3VwMUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgZ3JvdXAxQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgICAgZ3JvdXAxQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgICAgZ3JvdXAxXyA9IG90aGVyLmdyb3VwMV87CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgICAgICAgICBncm91cDFCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgICAgZ2V0R3JvdXAxRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBncm91cDFCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5ncm91cDFfKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGlmIChncm91cDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICghb3RoZXIuZ3JvdXAyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBpZiAoZ3JvdXAyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGdyb3VwMl8gPSBvdGhlci5ncm91cDJfOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBlbnN1cmVHcm91cDJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGdyb3VwMl8uYWRkQWxsKG90aGVyLmdyb3VwMl8pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCFvdGhlci5ncm91cDJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGlmIChncm91cDJCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGdyb3VwMkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICAgIGdyb3VwMkJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICAgIGdyb3VwMl8gPSBvdGhlci5ncm91cDJfOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgICAgICAgICAgZ3JvdXAyQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICAgIGdldEdyb3VwMkZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ3JvdXAyQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIuZ3JvdXAyXyk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoZXh0MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCFvdGhlci5leHQxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBpZiAoZXh0MV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBleHQxXyA9IG90aGVyLmV4dDFfOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBlbnN1cmVFeHQxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBleHQxXy5hZGRBbGwob3RoZXIuZXh0MV8pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCFvdGhlci5leHQxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBpZiAoZXh0MUJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgZXh0MUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICAgIGV4dDFCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgICBleHQxXyA9IG90aGVyLmV4dDFfOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgICAgICAgICAgZXh0MUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgICBnZXRFeHQxRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBleHQxQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIuZXh0MV8pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgaWYgKGV4dDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICghb3RoZXIuZXh0Ml8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgaWYgKGV4dDJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgZXh0Ml8gPSBvdGhlci5leHQyXzsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZW5zdXJlRXh0MklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgZXh0Ml8uYWRkQWxsKG90aGVyLmV4dDJfKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICghb3RoZXIuZXh0Ml8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgaWYgKGV4dDJCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGV4dDJCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgICBleHQyQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgICAgZXh0Ml8gPSBvdGhlci5leHQyXzsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICAgICAgICAgIGV4dDJCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgICAgZ2V0RXh0MkZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZXh0MkJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLmV4dDJfKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgbSA9CiAgICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgICBpZiAoZmllbGQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIGZpZWxkMV8uYWRkKG0pOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGZpZWxkMUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgbSA9CiAgICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgICBpZiAoZmllbGQyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIGZpZWxkMl8uYWRkKG0pOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGZpZWxkMkJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgbSA9CiAgICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgICBpZiAoZmllbGQzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZUZpZWxkM0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIGZpZWxkM18uYWRkKG0pOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGZpZWxkM0J1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICAgIGNhc2UgODM6IHsKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSBtID0KICAgICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRHcm91cCgxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICAgIGlmIChncm91cDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlR3JvdXAxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgZ3JvdXAxXy5hZGQobSk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZ3JvdXAxQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA4MwogICAgICAgICAgICAgICAgY2FzZSAxNjM6IHsKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMiBtID0KICAgICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRHcm91cCgyMCwKICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICAgIGlmIChncm91cDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlR3JvdXAySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgZ3JvdXAyXy5hZGQobSk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZ3JvdXAyQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjMKICAgICAgICAgICAgICAgIGNhc2UgODAwMjogewogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBtID0KICAgICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICAgIGlmIChleHQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZUV4dDFJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICBleHQxXy5hZGQobSk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZXh0MUJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMgogICAgICAgICAgICAgICAgY2FzZSA4MDEwOiB7CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG0gPQogICAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgICAgaWYgKGV4dDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlRXh0MklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIGV4dDJfLmFkZChtKTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBleHQyQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDEwCiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBmaWVsZDFfID0KICAgICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGQxSXNNdXRhYmxlKCkgewogICAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICBmaWVsZDFfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+KGZpZWxkMV8pOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gZmllbGQxQnVpbGRlcl87CgogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBnZXRGaWVsZDFMaXN0KCkgewogICAgICAgICAgaWYgKGZpZWxkMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkMV8pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGZpZWxkMUJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGludCBnZXRGaWVsZDFDb3VudCgpIHsKICAgICAgICAgIGlmIChmaWVsZDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBmaWVsZDFfLnNpemUoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBmaWVsZDFCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRGaWVsZDEoaW50IGluZGV4KSB7CiAgICAgICAgICBpZiAoZmllbGQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZmllbGQxXy5nZXQoaW5kZXgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGZpZWxkMUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkMSgKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgICAgaWYgKGZpZWxkMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVGaWVsZDFJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGQxXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZDFCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZDEoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChmaWVsZDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDFfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkMUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkMShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgICAgaWYgKGZpZWxkMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVGaWVsZDFJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGQxXy5hZGQodmFsdWUpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkMUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGQxKAogICAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgICBpZiAoZmllbGQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVuc3VyZUZpZWxkMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDFfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkMUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkMSgKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChmaWVsZDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDFfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGQxQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZDEoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChmaWVsZDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDFfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkMUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkMSgKICAgICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gdmFsdWVzKSB7CiAgICAgICAgICBpZiAoZmllbGQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVGaWVsZDFJc011dGFibGUoKTsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgICAgdmFsdWVzLCBmaWVsZDFfKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZDFCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQxID0gMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZDEoKSB7CiAgICAgICAgICBpZiAoZmllbGQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBmaWVsZDFfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGQxQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkMShpbnQgaW5kZXgpIHsKICAgICAgICAgIGlmIChmaWVsZDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDFfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGQxQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldEZpZWxkMUJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgcmV0dXJuIGdldEZpZWxkMUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRGaWVsZDFPckJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgaWYgKGZpZWxkMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGZpZWxkMV8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBmaWVsZDFCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICAgIGdldEZpZWxkMU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgICBpZiAoZmllbGQxQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZmllbGQxQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChmaWVsZDFfKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBhZGRGaWVsZDFCdWlsZGVyKCkgewogICAgICAgICAgcmV0dXJuIGdldEZpZWxkMUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGFkZEZpZWxkMUJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgcmV0dXJuIGdldEZpZWxkMUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgICAgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlcj4gCiAgICAgICAgICAgICBnZXRGaWVsZDFCdWlsZGVyTGlzdCgpIHsKICAgICAgICAgIHJldHVybiBnZXRGaWVsZDFGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICAgZ2V0RmllbGQxRmllbGRCdWlsZGVyKCkgewogICAgICAgICAgaWYgKGZpZWxkMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZmllbGQxQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgICBmaWVsZDFfLAogICAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApLAogICAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgICAgZmllbGQxXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gZmllbGQxQnVpbGRlcl87CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBmaWVsZDJfID0KICAgICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGQySXNNdXRhYmxlKCkgewogICAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgICBmaWVsZDJfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+KGZpZWxkMl8pOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gZmllbGQyQnVpbGRlcl87CgogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQyID0gMjs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBnZXRGaWVsZDJMaXN0KCkgewogICAgICAgICAgaWYgKGZpZWxkMkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkMl8pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGZpZWxkMkJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQyID0gMjs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGludCBnZXRGaWVsZDJDb3VudCgpIHsKICAgICAgICAgIGlmIChmaWVsZDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBmaWVsZDJfLnNpemUoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBmaWVsZDJCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRGaWVsZDIoaW50IGluZGV4KSB7CiAgICAgICAgICBpZiAoZmllbGQyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZmllbGQyXy5nZXQoaW5kZXgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGZpZWxkMkJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkMigKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgICAgaWYgKGZpZWxkMkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVGaWVsZDJJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGQyXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZDJCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDIgPSAyOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZDIoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChmaWVsZDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkMklzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDJfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkMkJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkMihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgICAgaWYgKGZpZWxkMkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVGaWVsZDJJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGQyXy5hZGQodmFsdWUpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkMkJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQyID0gMjs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGQyKAogICAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgICBpZiAoZmllbGQyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVuc3VyZUZpZWxkMklzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDJfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkMkJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkMigKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChmaWVsZDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkMklzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDJfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGQyQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDIgPSAyOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZDIoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChmaWVsZDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkMklzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDJfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkMkJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkMigKICAgICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gdmFsdWVzKSB7CiAgICAgICAgICBpZiAoZmllbGQyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVGaWVsZDJJc011dGFibGUoKTsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgICAgdmFsdWVzLCBmaWVsZDJfKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZDJCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQyID0gMjs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZDIoKSB7CiAgICAgICAgICBpZiAoZmllbGQyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBmaWVsZDJfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGQyQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkMihpbnQgaW5kZXgpIHsKICAgICAgICAgIGlmIChmaWVsZDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkMklzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGQyQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldEZpZWxkMkJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgcmV0dXJuIGdldEZpZWxkMkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRGaWVsZDJPckJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgaWYgKGZpZWxkMkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGZpZWxkMl8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBmaWVsZDJCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDIgPSAyOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICAgIGdldEZpZWxkMk9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgICBpZiAoZmllbGQyQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZmllbGQyQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChmaWVsZDJfKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDIgPSAyOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBhZGRGaWVsZDJCdWlsZGVyKCkgewogICAgICAgICAgcmV0dXJuIGdldEZpZWxkMkZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGFkZEZpZWxkMkJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgcmV0dXJuIGdldEZpZWxkMkZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgICAgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDIgPSAyOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlcj4gCiAgICAgICAgICAgICBnZXRGaWVsZDJCdWlsZGVyTGlzdCgpIHsKICAgICAgICAgIHJldHVybiBnZXRGaWVsZDJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICAgZ2V0RmllbGQyRmllbGRCdWlsZGVyKCkgewogICAgICAgICAgaWYgKGZpZWxkMkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZmllbGQyQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgICBmaWVsZDJfLAogICAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApLAogICAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgICAgZmllbGQyXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gZmllbGQyQnVpbGRlcl87CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBmaWVsZDNfID0KICAgICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBwcml2YXRlIHZvaWQgZW5zdXJlRmllbGQzSXNNdXRhYmxlKCkgewogICAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgICBmaWVsZDNfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+KGZpZWxkM18pOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gZmllbGQzQnVpbGRlcl87CgogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQzID0gMzs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBnZXRGaWVsZDNMaXN0KCkgewogICAgICAgICAgaWYgKGZpZWxkM0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGZpZWxkM18pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGZpZWxkM0J1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQzID0gMzs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGludCBnZXRGaWVsZDNDb3VudCgpIHsKICAgICAgICAgIGlmIChmaWVsZDNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBmaWVsZDNfLnNpemUoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBmaWVsZDNCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRGaWVsZDMoaW50IGluZGV4KSB7CiAgICAgICAgICBpZiAoZmllbGQzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZmllbGQzXy5nZXQoaW5kZXgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGZpZWxkM0J1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkMygKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgICAgaWYgKGZpZWxkM0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVGaWVsZDNJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGQzXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZDNCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDMgPSAzOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZDMoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChmaWVsZDNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkM0lzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDNfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkM0J1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkMyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgICAgaWYgKGZpZWxkM0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVGaWVsZDNJc011dGFibGUoKTsKICAgICAgICAgICAgZmllbGQzXy5hZGQodmFsdWUpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkM0J1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQzID0gMzs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRmllbGQzKAogICAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgICBpZiAoZmllbGQzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVuc3VyZUZpZWxkM0lzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDNfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkM0J1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEZpZWxkMygKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChmaWVsZDNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkM0lzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDNfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGQzQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDMgPSAzOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRGaWVsZDMoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChmaWVsZDNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkM0lzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDNfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZpZWxkM0J1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEZpZWxkMygKICAgICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gdmFsdWVzKSB7CiAgICAgICAgICBpZiAoZmllbGQzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVGaWVsZDNJc011dGFibGUoKTsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgICAgdmFsdWVzLCBmaWVsZDNfKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmaWVsZDNCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZmllbGQzID0gMzs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZDMoKSB7CiAgICAgICAgICBpZiAoZmllbGQzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBmaWVsZDNfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGQzQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUZpZWxkMyhpbnQgaW5kZXgpIHsKICAgICAgICAgIGlmIChmaWVsZDNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUZpZWxkM0lzTXV0YWJsZSgpOwogICAgICAgICAgICBmaWVsZDNfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmllbGQzQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldEZpZWxkM0J1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgcmV0dXJuIGdldEZpZWxkM0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRGaWVsZDNPckJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgaWYgKGZpZWxkM0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGZpZWxkM18uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBmaWVsZDNCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDMgPSAzOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICAgIGdldEZpZWxkM09yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgICBpZiAoZmllbGQzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZmllbGQzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChmaWVsZDNfKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDMgPSAzOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBhZGRGaWVsZDNCdWlsZGVyKCkgewogICAgICAgICAgcmV0dXJuIGdldEZpZWxkM0ZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGFkZEZpZWxkM0J1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgcmV0dXJuIGdldEZpZWxkM0ZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgICAgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBmaWVsZDMgPSAzOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlcj4gCiAgICAgICAgICAgICBnZXRGaWVsZDNCdWlsZGVyTGlzdCgpIHsKICAgICAgICAgIHJldHVybiBnZXRGaWVsZDNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICAgZ2V0RmllbGQzRmllbGRCdWlsZGVyKCkgewogICAgICAgICAgaWYgKGZpZWxkM0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZmllbGQzQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgICBmaWVsZDNfLAogICAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApLAogICAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgICAgZmllbGQzXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gZmllbGQzQnVpbGRlcl87CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDE+IGdyb3VwMV8gPQogICAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVHcm91cDFJc011dGFibGUoKSB7CiAgICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICAgIGdyb3VwMV8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxPihncm91cDFfKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDFPckJ1aWxkZXI+IGdyb3VwMUJ1aWxkZXJfOwoKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDEgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxPiBnZXRHcm91cDFMaXN0KCkgewogICAgICAgICAgaWYgKGdyb3VwMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGdyb3VwMV8pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGdyb3VwMUJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMSA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGludCBnZXRHcm91cDFDb3VudCgpIHsKICAgICAgICAgIGlmIChncm91cDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBncm91cDFfLnNpemUoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBncm91cDFCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDEgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxIGdldEdyb3VwMShpbnQgaW5kZXgpIHsKICAgICAgICAgIGlmIChncm91cDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBncm91cDFfLmdldChpbmRleCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gZ3JvdXAxQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMSA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0R3JvdXAxKAogICAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEgdmFsdWUpIHsKICAgICAgICAgIGlmIChncm91cDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5zdXJlR3JvdXAxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGdyb3VwMV8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ3JvdXAxQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMSA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0R3JvdXAxKAogICAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChncm91cDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUdyb3VwMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBncm91cDFfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdyb3VwMUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDEgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEdyb3VwMShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxIHZhbHVlKSB7CiAgICAgICAgICBpZiAoZ3JvdXAxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVuc3VyZUdyb3VwMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBncm91cDFfLmFkZCh2YWx1ZSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ3JvdXAxQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAxID0gMTAgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRHcm91cDEoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMSB2YWx1ZSkgewogICAgICAgICAgaWYgKGdyb3VwMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVHcm91cDFJc011dGFibGUoKTsKICAgICAgICAgICAgZ3JvdXAxXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBncm91cDFCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAxID0gMTAgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRHcm91cDEoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChncm91cDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUdyb3VwMUlzTXV0YWJsZSgpOwogICAgICAgICAgICBncm91cDFfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ3JvdXAxQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAxID0gMTAgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRHcm91cDEoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKGdyb3VwMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlR3JvdXAxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGdyb3VwMV8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ3JvdXAxQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMSA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsR3JvdXAxKAogICAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDE+IHZhbHVlcykgewogICAgICAgICAgaWYgKGdyb3VwMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlR3JvdXAxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICAgIHZhbHVlcywgZ3JvdXAxXyk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ3JvdXAxQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDEgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyR3JvdXAxKCkgewogICAgICAgICAgaWYgKGdyb3VwMUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZ3JvdXAxXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdyb3VwMUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAxID0gMTAgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVHcm91cDEoaW50IGluZGV4KSB7CiAgICAgICAgICBpZiAoZ3JvdXAxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVHcm91cDFJc011dGFibGUoKTsKICAgICAgICAgICAgZ3JvdXAxXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdyb3VwMUJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAxID0gMTAgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5CdWlsZGVyIGdldEdyb3VwMUJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgcmV0dXJuIGdldEdyb3VwMUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDEgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxT3JCdWlsZGVyIGdldEdyb3VwMU9yQnVpbGRlcigKICAgICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgICBpZiAoZ3JvdXAxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZ3JvdXAxXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGdyb3VwMUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDEgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMU9yQnVpbGRlcj4gCiAgICAgICAgICAgICBnZXRHcm91cDFPckJ1aWxkZXJMaXN0KCkgewogICAgICAgICAgaWYgKGdyb3VwMUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGdyb3VwMUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZ3JvdXAxXyk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMSA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEuQnVpbGRlciBhZGRHcm91cDFCdWlsZGVyKCkgewogICAgICAgICAgcmV0dXJuIGdldEdyb3VwMUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMSA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDEuQnVpbGRlciBhZGRHcm91cDFCdWlsZGVyKAogICAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICAgIHJldHVybiBnZXRHcm91cDFGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICAgIGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAxID0gMTAgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMS5CdWlsZGVyPiAKICAgICAgICAgICAgIGdldEdyb3VwMUJ1aWxkZXJMaXN0KCkgewogICAgICAgICAgcmV0dXJuIGdldEdyb3VwMUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDFPckJ1aWxkZXI+IAogICAgICAgICAgICBnZXRHcm91cDFGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgICBpZiAoZ3JvdXAxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBncm91cDFCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAxLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDFPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICAgIGdyb3VwMV8sCiAgICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCksCiAgICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgICBncm91cDFfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBncm91cDFCdWlsZGVyXzsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMj4gZ3JvdXAyXyA9CiAgICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUdyb3VwMklzTXV0YWJsZSgpIHsKICAgICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgICAgZ3JvdXAyXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDI+KGdyb3VwMl8pOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMk9yQnVpbGRlcj4gZ3JvdXAyQnVpbGRlcl87CgogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMiA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDI+IGdldEdyb3VwMkxpc3QoKSB7CiAgICAgICAgICBpZiAoZ3JvdXAyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZ3JvdXAyXyk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gZ3JvdXAyQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAyID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgaW50IGdldEdyb3VwMkNvdW50KCkgewogICAgICAgICAgaWYgKGdyb3VwMkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGdyb3VwMl8uc2l6ZSgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGdyb3VwMkJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMiA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIgZ2V0R3JvdXAyKGludCBpbmRleCkgewogICAgICAgICAgaWYgKGdyb3VwMkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGdyb3VwMl8uZ2V0KGluZGV4KTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBncm91cDJCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAyID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRHcm91cDIoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMiB2YWx1ZSkgewogICAgICAgICAgaWYgKGdyb3VwMkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVHcm91cDJJc011dGFibGUoKTsKICAgICAgICAgICAgZ3JvdXAyXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBncm91cDJCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAyID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRHcm91cDIoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMi5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKGdyb3VwMkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlR3JvdXAySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGdyb3VwMl8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ3JvdXAyQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMiA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkR3JvdXAyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIgdmFsdWUpIHsKICAgICAgICAgIGlmIChncm91cDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5zdXJlR3JvdXAySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGdyb3VwMl8uYWRkKHZhbHVlKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBncm91cDJCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDIgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEdyb3VwMigKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyIHZhbHVlKSB7CiAgICAgICAgICBpZiAoZ3JvdXAyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVuc3VyZUdyb3VwMklzTXV0YWJsZSgpOwogICAgICAgICAgICBncm91cDJfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdyb3VwMkJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDIgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEdyb3VwMigKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMi5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKGdyb3VwMkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlR3JvdXAySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGdyb3VwMl8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBncm91cDJCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDIgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEdyb3VwMigKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgICBpZiAoZ3JvdXAyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVHcm91cDJJc011dGFibGUoKTsKICAgICAgICAgICAgZ3JvdXAyXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBncm91cDJCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAyID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxHcm91cDIoCiAgICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMj4gdmFsdWVzKSB7CiAgICAgICAgICBpZiAoZ3JvdXAyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVHcm91cDJJc011dGFibGUoKTsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgICAgdmFsdWVzLCBncm91cDJfKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBncm91cDJCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMiA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJHcm91cDIoKSB7CiAgICAgICAgICBpZiAoZ3JvdXAyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBncm91cDJfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ3JvdXAyQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDIgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUdyb3VwMihpbnQgaW5kZXgpIHsKICAgICAgICAgIGlmIChncm91cDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUdyb3VwMklzTXV0YWJsZSgpOwogICAgICAgICAgICBncm91cDJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ3JvdXAyQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDIgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyLkJ1aWxkZXIgZ2V0R3JvdXAyQnVpbGRlcigKICAgICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgICByZXR1cm4gZ2V0R3JvdXAyRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMiA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDJPckJ1aWxkZXIgZ2V0R3JvdXAyT3JCdWlsZGVyKAogICAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICAgIGlmIChncm91cDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBncm91cDJfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gZ3JvdXAyQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIEdyb3VwMiA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyT3JCdWlsZGVyPiAKICAgICAgICAgICAgIGdldEdyb3VwMk9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgICBpZiAoZ3JvdXAyQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZ3JvdXAyQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChncm91cDJfKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAyID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMi5CdWlsZGVyIGFkZEdyb3VwMkJ1aWxkZXIoKSB7CiAgICAgICAgICByZXR1cm4gZ2V0R3JvdXAyRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgR3JvdXAyID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMi5CdWlsZGVyIGFkZEdyb3VwMkJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgcmV0dXJuIGdldEdyb3VwMkZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgICAgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBHcm91cDIgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IuR3JvdXAyLkJ1aWxkZXI+IAogICAgICAgICAgICAgZ2V0R3JvdXAyQnVpbGRlckxpc3QoKSB7CiAgICAgICAgICByZXR1cm4gZ2V0R3JvdXAyRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMk9yQnVpbGRlcj4gCiAgICAgICAgICAgIGdldEdyb3VwMkZpZWxkQnVpbGRlcigpIHsKICAgICAgICAgIGlmIChncm91cDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGdyb3VwMkJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDIuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yLkdyb3VwMk9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgICAgZ3JvdXAyXywKICAgICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICAgIGdyb3VwMl8gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGdyb3VwMkJ1aWxkZXJfOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZXh0MV8gPQogICAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVFeHQxSXNNdXRhYmxlKCkgewogICAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgICBleHQxXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPihleHQxXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBleHQxQnVpbGRlcl87CgogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MSA9IDEwMDA7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0RXh0MUxpc3QoKSB7CiAgICAgICAgICBpZiAoZXh0MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGV4dDFfKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBleHQxQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQxID0gMTAwMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGludCBnZXRFeHQxQ291bnQoKSB7CiAgICAgICAgICBpZiAoZXh0MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGV4dDFfLnNpemUoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBleHQxQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQxID0gMTAwMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldEV4dDEoaW50IGluZGV4KSB7CiAgICAgICAgICBpZiAoZXh0MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGV4dDFfLmdldChpbmRleCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gZXh0MUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDEgPSAxMDAwOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRFeHQxKAogICAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgICBpZiAoZXh0MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVFeHQxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGV4dDFfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGV4dDFCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQxID0gMTAwMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RXh0MSgKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKGV4dDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUV4dDFJc011dGFibGUoKTsKICAgICAgICAgICAgZXh0MV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZXh0MUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDEgPSAxMDAwOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRFeHQxKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgICBpZiAoZXh0MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVFeHQxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGV4dDFfLmFkZCh2YWx1ZSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZXh0MUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MSA9IDEwMDA7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEV4dDEoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICAgIGlmIChleHQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVuc3VyZUV4dDFJc011dGFibGUoKTsKICAgICAgICAgICAgZXh0MV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZXh0MUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDEgPSAxMDAwOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRFeHQxKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKGV4dDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUV4dDFJc011dGFibGUoKTsKICAgICAgICAgICAgZXh0MV8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBleHQxQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQxID0gMTAwMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRXh0MSgKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKGV4dDFCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUV4dDFJc011dGFibGUoKTsKICAgICAgICAgICAgZXh0MV8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZXh0MUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDEgPSAxMDAwOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxFeHQxKAogICAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiB2YWx1ZXMpIHsKICAgICAgICAgIGlmIChleHQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVFeHQxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICAgIHZhbHVlcywgZXh0MV8pOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGV4dDFCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MSA9IDEwMDA7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRXh0MSgpIHsKICAgICAgICAgIGlmIChleHQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBleHQxXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGV4dDFCdWlsZGVyXy5jbGVhcigpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MSA9IDEwMDA7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUV4dDEoaW50IGluZGV4KSB7CiAgICAgICAgICBpZiAoZXh0MUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlRXh0MUlzTXV0YWJsZSgpOwogICAgICAgICAgICBleHQxXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGV4dDFCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MSA9IDEwMDA7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldEV4dDFCdWlsZGVyKAogICAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICAgIHJldHVybiBnZXRFeHQxRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MSA9IDEwMDA7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRFeHQxT3JCdWlsZGVyKAogICAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICAgIGlmIChleHQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZXh0MV8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBleHQxQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MSA9IDEwMDA7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgICAgZ2V0RXh0MU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgICBpZiAoZXh0MUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGV4dDFCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGV4dDFfKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQxID0gMTAwMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYWRkRXh0MUJ1aWxkZXIoKSB7CiAgICAgICAgICByZXR1cm4gZ2V0RXh0MUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDEgPSAxMDAwOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBhZGRFeHQxQnVpbGRlcigKICAgICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgICByZXR1cm4gZ2V0RXh0MUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgICAgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQxID0gMTAwMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXI+IAogICAgICAgICAgICAgZ2V0RXh0MUJ1aWxkZXJMaXN0KCkgewogICAgICAgICAgcmV0dXJuIGdldEV4dDFGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICAgZ2V0RXh0MUZpZWxkQnVpbGRlcigpIHsKICAgICAgICAgIGlmIChleHQxQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBleHQxQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgICBleHQxXywKICAgICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICAgIGV4dDFfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBleHQxQnVpbGRlcl87CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBleHQyXyA9CiAgICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUV4dDJJc011dGFibGUoKSB7CiAgICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICAgIGV4dDJfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+KGV4dDJfKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IGV4dDJCdWlsZGVyXzsKCiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQyID0gMTAwMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBnZXRFeHQyTGlzdCgpIHsKICAgICAgICAgIGlmIChleHQyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZXh0Ml8pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGV4dDJCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDIgPSAxMDAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgaW50IGdldEV4dDJDb3VudCgpIHsKICAgICAgICAgIGlmIChleHQyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZXh0Ml8uc2l6ZSgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGV4dDJCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDIgPSAxMDAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0RXh0MihpbnQgaW5kZXgpIHsKICAgICAgICAgIGlmIChleHQyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZXh0Ml8uZ2V0KGluZGV4KTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBleHQyQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MiA9IDEwMDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEV4dDIoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICAgIGlmIChleHQyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVuc3VyZUV4dDJJc011dGFibGUoKTsKICAgICAgICAgICAgZXh0Ml8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZXh0MkJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDIgPSAxMDAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRFeHQyKAogICAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgICBpZiAoZXh0MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlRXh0MklzTXV0YWJsZSgpOwogICAgICAgICAgICBleHQyXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBleHQyQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MiA9IDEwMDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEV4dDIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICAgIGlmIChleHQyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVuc3VyZUV4dDJJc011dGFibGUoKTsKICAgICAgICAgICAgZXh0Ml8uYWRkKHZhbHVlKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBleHQyQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQyID0gMTAwMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkRXh0MigKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgICAgaWYgKGV4dDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5zdXJlRXh0MklzTXV0YWJsZSgpOwogICAgICAgICAgICBleHQyXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBleHQyQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MiA9IDEwMDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEV4dDIoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgICBpZiAoZXh0MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlRXh0MklzTXV0YWJsZSgpOwogICAgICAgICAgICBleHQyXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGV4dDJCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDIgPSAxMDAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRFeHQyKAogICAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgICBpZiAoZXh0MkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlRXh0MklzTXV0YWJsZSgpOwogICAgICAgICAgICBleHQyXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBleHQyQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MiA9IDEwMDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbEV4dDIoCiAgICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IHZhbHVlcykgewogICAgICAgICAgaWYgKGV4dDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUV4dDJJc011dGFibGUoKTsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgICAgdmFsdWVzLCBleHQyXyk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZXh0MkJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQyID0gMTAwMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJFeHQyKCkgewogICAgICAgICAgaWYgKGV4dDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGV4dDJfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZXh0MkJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQyID0gMTAwMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlRXh0MihpbnQgaW5kZXgpIHsKICAgICAgICAgIGlmIChleHQyQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVFeHQySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGV4dDJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZXh0MkJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQyID0gMTAwMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0RXh0MkJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgcmV0dXJuIGdldEV4dDJGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQyID0gMTAwMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldEV4dDJPckJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgaWYgKGV4dDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBleHQyXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGV4dDJCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBleHQyID0gMTAwMTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICAgICBnZXRFeHQyT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICAgIGlmIChleHQyQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gZXh0MkJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QoZXh0Ml8pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDIgPSAxMDAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBhZGRFeHQyQnVpbGRlcigpIHsKICAgICAgICAgIHJldHVybiBnZXRFeHQyRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgZXh0MiA9IDEwMDE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGFkZEV4dDJCdWlsZGVyKAogICAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICAgIHJldHVybiBnZXRFeHQyRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIGV4dDIgPSAxMDAxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlcj4gCiAgICAgICAgICAgICBnZXRFeHQyQnVpbGRlckxpc3QoKSB7CiAgICAgICAgICByZXR1cm4gZ2V0RXh0MkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgICBnZXRFeHQyRmllbGRCdWlsZGVyKCkgewogICAgICAgICAgaWYgKGV4dDJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGV4dDJCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICAgIGV4dDJfLAogICAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApLAogICAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgICAgZXh0Ml8gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGV4dDJCdWlsZGVyXzsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvcikKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXBlYXRlZEZpZWxkc0dlbmVyYXRvcj4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFJlcGVhdGVkRmllbGRzR2VuZXJhdG9yPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIFJlcGVhdGVkRmllbGRzR2VuZXJhdG9yIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3I+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXBlYXRlZEZpZWxkc0dlbmVyYXRvcj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3IgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIE9wdGlvbmFsR3JvdXBPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXApCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2dyb3VwX2FsbF90eXBlcyA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEdyb3VwQWxsVHlwZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNPcHRpb25hbEdyb3VwQWxsVHlwZXMoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfZ3JvdXBfYWxsX3R5cGVzID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEdyb3VwQWxsVHlwZXMuCiAgICAgICAqLwogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRPcHRpb25hbEdyb3VwQWxsVHlwZXMoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfZ3JvdXBfYWxsX3R5cGVzID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0T3B0aW9uYWxHcm91cEFsbFR5cGVzT3JCdWlsZGVyKCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBPcHRpb25hbEdyb3VwIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXApCiAgICAgICAgT3B0aW9uYWxHcm91cE9yQnVpbGRlciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgLy8gVXNlIE9wdGlvbmFsR3JvdXAubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBPcHRpb25hbEdyb3VwKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgT3B0aW9uYWxHcm91cCgpIHsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBPcHRpb25hbEdyb3VwKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX09wdGlvbmFsR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9PcHRpb25hbEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfR1JPVVBfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUiA9IDExOwogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG9wdGlvbmFsR3JvdXBBbGxUeXBlc187CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2dyb3VwX2FsbF90eXBlcyA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEdyb3VwQWxsVHlwZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEdyb3VwQWxsVHlwZXMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2dyb3VwX2FsbF90eXBlcyA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxHcm91cEFsbFR5cGVzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0T3B0aW9uYWxHcm91cEFsbFR5cGVzKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEdyb3VwQWxsVHlwZXNfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsR3JvdXBBbGxUeXBlc187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfZ3JvdXBfYWxsX3R5cGVzID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0T3B0aW9uYWxHcm91cEFsbFR5cGVzT3JCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEdyb3VwQWxsVHlwZXNfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsR3JvdXBBbGxUeXBlc187CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDExLCBnZXRPcHRpb25hbEdyb3VwQWxsVHlwZXMoKSk7CiAgICAgICAgfQogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTEsIGdldE9wdGlvbmFsR3JvdXBBbGxUeXBlcygpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgIHJldHVybiBzaXplOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXApKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwKSBvYmo7CgogICAgICAgIGlmIChoYXNPcHRpb25hbEdyb3VwQWxsVHlwZXMoKSAhPSBvdGhlci5oYXNPcHRpb25hbEdyb3VwQWxsVHlwZXMoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNPcHRpb25hbEdyb3VwQWxsVHlwZXMoKSkgewogICAgICAgICAgaWYgKCFnZXRPcHRpb25hbEdyb3VwQWxsVHlwZXMoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxHcm91cEFsbFR5cGVzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzT3B0aW9uYWxHcm91cEFsbFR5cGVzKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0dST1VQX0FMTF9UWVBFU19GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEdyb3VwQWxsVHlwZXMoKS5oYXNoQ29kZSgpOwogICAgICAgIH0KICAgICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cCBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXB9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cCkKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfT3B0aW9uYWxHcm91cF9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9PcHRpb25hbEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxHcm91cEFsbFR5cGVzRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBBbGxUeXBlc18gPSBudWxsOwogICAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgb3B0aW9uYWxHcm91cEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICBvcHRpb25hbEdyb3VwQWxsVHlwZXNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfT3B0aW9uYWxHcm91cF9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cCBidWlsZCgpIHsKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cCByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQub3B0aW9uYWxHcm91cEFsbFR5cGVzXyA9IG9wdGlvbmFsR3JvdXBBbGxUeXBlc0J1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICAgID8gb3B0aW9uYWxHcm91cEFsbFR5cGVzXwogICAgICAgICAgICAgICAgOiBvcHRpb25hbEdyb3VwQWxsVHlwZXNCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXApIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXApb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAgb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxHcm91cEFsbFR5cGVzKCkpIHsKICAgICAgICAgICAgbWVyZ2VPcHRpb25hbEdyb3VwQWxsVHlwZXMob3RoZXIuZ2V0T3B0aW9uYWxHcm91cEFsbFR5cGVzKCkpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSA5MDogewogICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsR3JvdXBBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBvcHRpb25hbEdyb3VwQWxsVHlwZXNfOwogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBvcHRpb25hbEdyb3VwQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2dyb3VwX2FsbF90eXBlcyA9IDExOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsR3JvdXBBbGxUeXBlcyBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxHcm91cEFsbFR5cGVzKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2dyb3VwX2FsbF90eXBlcyA9IDExOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEdyb3VwQWxsVHlwZXMuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE9wdGlvbmFsR3JvdXBBbGxUeXBlcygpIHsKICAgICAgICAgIGlmIChvcHRpb25hbEdyb3VwQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBvcHRpb25hbEdyb3VwQWxsVHlwZXNfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsR3JvdXBBbGxUeXBlc187CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gb3B0aW9uYWxHcm91cEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2dyb3VwX2FsbF90eXBlcyA9IDExOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEdyb3VwQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICAgIGlmIChvcHRpb25hbEdyb3VwQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb3B0aW9uYWxHcm91cEFsbFR5cGVzXyA9IHZhbHVlOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxHcm91cEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2dyb3VwX2FsbF90eXBlcyA9IDExOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEdyb3VwQWxsVHlwZXMoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgICBpZiAob3B0aW9uYWxHcm91cEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBvcHRpb25hbEdyb3VwQWxsVHlwZXNfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbEdyb3VwQWxsVHlwZXNCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfZ3JvdXBfYWxsX3R5cGVzID0gMTE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxHcm91cEFsbFR5cGVzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgICBpZiAob3B0aW9uYWxHcm91cEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgICBvcHRpb25hbEdyb3VwQWxsVHlwZXNfICE9IG51bGwgJiYKICAgICAgICAgICAgICBvcHRpb25hbEdyb3VwQWxsVHlwZXNfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxHcm91cEFsbFR5cGVzQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgb3B0aW9uYWxHcm91cEFsbFR5cGVzXyA9IHZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbEdyb3VwQWxsVHlwZXNCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBBbGxUeXBlc18gIT0gbnVsbCkgewogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfZ3JvdXBfYWxsX3R5cGVzID0gMTE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxHcm91cEFsbFR5cGVzKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgb3B0aW9uYWxHcm91cEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgICBpZiAob3B0aW9uYWxHcm91cEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICBvcHRpb25hbEdyb3VwQWxsVHlwZXNCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIG9wdGlvbmFsR3JvdXBBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfZ3JvdXBfYWxsX3R5cGVzID0gMTE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldE9wdGlvbmFsR3JvdXBBbGxUeXBlc0J1aWxkZXIoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiBnZXRPcHRpb25hbEdyb3VwQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfZ3JvdXBfYWxsX3R5cGVzID0gMTE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPcHRpb25hbEdyb3VwQWxsVHlwZXNPckJ1aWxkZXIoKSB7CiAgICAgICAgICBpZiAob3B0aW9uYWxHcm91cEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gb3B0aW9uYWxHcm91cEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIG9wdGlvbmFsR3JvdXBBbGxUeXBlc18gPT0gbnVsbCA/CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsR3JvdXBBbGxUeXBlc187CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfZ3JvdXBfYWxsX3R5cGVzID0gMTE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICAgZ2V0T3B0aW9uYWxHcm91cEFsbFR5cGVzRmllbGRCdWlsZGVyKCkgewogICAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgb3B0aW9uYWxHcm91cEFsbFR5cGVzQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxHcm91cEFsbFR5cGVzKCksCiAgICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgICBvcHRpb25hbEdyb3VwQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBvcHRpb25hbEdyb3VwQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXApCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXApCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cCgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T3B0aW9uYWxHcm91cD4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE9wdGlvbmFsR3JvdXA+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgT3B0aW9uYWxHcm91cCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE9wdGlvbmFsR3JvdXA+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPcHRpb25hbEdyb3VwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBSZXBlYXRlZEdyb3VwT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwKQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9ncm91cF9hbGxfdHlwZXMgPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVwZWF0ZWRHcm91cEFsbFR5cGVzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzUmVwZWF0ZWRHcm91cEFsbFR5cGVzKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2dyb3VwX2FsbF90eXBlcyA9IDIxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRHcm91cEFsbFR5cGVzLgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0UmVwZWF0ZWRHcm91cEFsbFR5cGVzKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2dyb3VwX2FsbF90eXBlcyA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcGVhdGVkR3JvdXBBbGxUeXBlc09yQnVpbGRlcigpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXB9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgUmVwZWF0ZWRHcm91cCBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwKQogICAgICAgIFJlcGVhdGVkR3JvdXBPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBSZXBlYXRlZEdyb3VwLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgUmVwZWF0ZWRHcm91cChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIFJlcGVhdGVkR3JvdXAoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgUmVwZWF0ZWRHcm91cCgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9SZXBlYXRlZEdyb3VwX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRHcm91cF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0dST1VQX0FMTF9UWVBFU19GSUVMRF9OVU1CRVIgPSAyMTsKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyByZXBlYXRlZEdyb3VwQWxsVHlwZXNfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9ncm91cF9hbGxfdHlwZXMgPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVwZWF0ZWRHcm91cEFsbFR5cGVzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUmVwZWF0ZWRHcm91cEFsbFR5cGVzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9ncm91cF9hbGxfdHlwZXMgPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkR3JvdXBBbGxUeXBlcy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkR3JvdXBBbGxUeXBlcygpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRHcm91cEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXBlYXRlZEdyb3VwQWxsVHlwZXNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2dyb3VwX2FsbF90eXBlcyA9IDIxOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcGVhdGVkR3JvdXBBbGxUeXBlc09yQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRHcm91cEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXBlYXRlZEdyb3VwQWxsVHlwZXNfOwogICAgICB9CgogICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyMSwgZ2V0UmVwZWF0ZWRHcm91cEFsbFR5cGVzKCkpOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDIxLCBnZXRSZXBlYXRlZEdyb3VwQWxsVHlwZXMoKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwKSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICAgIH0KICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCkgb2JqOwoKICAgICAgICBpZiAoaGFzUmVwZWF0ZWRHcm91cEFsbFR5cGVzKCkgIT0gb3RoZXIuaGFzUmVwZWF0ZWRHcm91cEFsbFR5cGVzKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzUmVwZWF0ZWRHcm91cEFsbFR5cGVzKCkpIHsKICAgICAgICAgIGlmICghZ2V0UmVwZWF0ZWRHcm91cEFsbFR5cGVzKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkR3JvdXBBbGxUeXBlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaWYgKGhhc1JlcGVhdGVkR3JvdXBBbGxUeXBlcygpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9HUk9VUF9BTExfVFlQRVNfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRHcm91cEFsbFR5cGVzKCkuaGFzaENvZGUoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAgcHJvdG90eXBlKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgfQogICAgICAvKioKICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXApCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cE9yQnVpbGRlciB7CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX1JlcGVhdGVkR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRHcm91cF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICAgIGdldFJlcGVhdGVkR3JvdXBBbGxUeXBlc0ZpZWxkQnVpbGRlcigpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgICByZXBlYXRlZEdyb3VwQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICAgIHJlcGVhdGVkR3JvdXBBbGxUeXBlc0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgcmVwZWF0ZWRHcm91cEFsbFR5cGVzQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX1JlcGVhdGVkR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwKHRoaXMpOwogICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgIG9uQnVpbHQoKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0LnJlcGVhdGVkR3JvdXBBbGxUeXBlc18gPSByZXBlYXRlZEdyb3VwQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgICA/IHJlcGVhdGVkR3JvdXBBbGxUeXBlc18KICAgICAgICAgICAgICAgIDogcmVwZWF0ZWRHcm91cEFsbFR5cGVzQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc1JlcGVhdGVkR3JvdXBBbGxUeXBlcygpKSB7CiAgICAgICAgICAgIG1lcmdlUmVwZWF0ZWRHcm91cEFsbFR5cGVzKG90aGVyLmdldFJlcGVhdGVkR3JvdXBBbGxUeXBlcygpKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMTcwOiB7CiAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWRHcm91cEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDE3MAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyByZXBlYXRlZEdyb3VwQWxsVHlwZXNfOwogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiByZXBlYXRlZEdyb3VwQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2dyb3VwX2FsbF90eXBlcyA9IDIxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcGVhdGVkR3JvdXBBbGxUeXBlcyBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzUmVwZWF0ZWRHcm91cEFsbFR5cGVzKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2dyb3VwX2FsbF90eXBlcyA9IDIxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEdyb3VwQWxsVHlwZXMuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkR3JvdXBBbGxUeXBlcygpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiByZXBlYXRlZEdyb3VwQWxsVHlwZXNfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHJlcGVhdGVkR3JvdXBBbGxUeXBlc187CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRHcm91cEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2dyb3VwX2FsbF90eXBlcyA9IDIxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEdyb3VwQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVwZWF0ZWRHcm91cEFsbFR5cGVzXyA9IHZhbHVlOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVwZWF0ZWRHcm91cEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2dyb3VwX2FsbF90eXBlcyA9IDIxOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEdyb3VwQWxsVHlwZXMoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXBlYXRlZEdyb3VwQWxsVHlwZXNfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXBlYXRlZEdyb3VwQWxsVHlwZXNCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfZ3JvdXBfYWxsX3R5cGVzID0gMjE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlUmVwZWF0ZWRHcm91cEFsbFR5cGVzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgICByZXBlYXRlZEdyb3VwQWxsVHlwZXNfICE9IG51bGwgJiYKICAgICAgICAgICAgICByZXBlYXRlZEdyb3VwQWxsVHlwZXNfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWRHcm91cEFsbFR5cGVzQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRHcm91cEFsbFR5cGVzXyA9IHZhbHVlOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXBlYXRlZEdyb3VwQWxsVHlwZXNCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBBbGxUeXBlc18gIT0gbnVsbCkgewogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfZ3JvdXBfYWxsX3R5cGVzID0gMjE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRHcm91cEFsbFR5cGVzKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgcmVwZWF0ZWRHcm91cEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICByZXBlYXRlZEdyb3VwQWxsVHlwZXNCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkR3JvdXBBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfZ3JvdXBfYWxsX3R5cGVzID0gMjE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldFJlcGVhdGVkR3JvdXBBbGxUeXBlc0J1aWxkZXIoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEdyb3VwQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfZ3JvdXBfYWxsX3R5cGVzID0gMjE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRSZXBlYXRlZEdyb3VwQWxsVHlwZXNPckJ1aWxkZXIoKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRHcm91cEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHJlcGVhdGVkR3JvdXBBbGxUeXBlc18gPT0gbnVsbCA/CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IHJlcGVhdGVkR3JvdXBBbGxUeXBlc187CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfZ3JvdXBfYWxsX3R5cGVzID0gMjE7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICAgZ2V0UmVwZWF0ZWRHcm91cEFsbFR5cGVzRmllbGRCdWlsZGVyKCkgewogICAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmVwZWF0ZWRHcm91cEFsbFR5cGVzQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWRHcm91cEFsbFR5cGVzKCksCiAgICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgICByZXBlYXRlZEdyb3VwQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXBlYXRlZEdyb3VwQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXApCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXApCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8UmVwZWF0ZWRHcm91cD4KICAgICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFJlcGVhdGVkR3JvdXA+KCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUmVwZWF0ZWRHcm91cCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlcGVhdGVkR3JvdXA+IHBhcnNlcigpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZXBlYXRlZEdyb3VwPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUVVJUkVEX0FMTF9UWVBFU19GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyByZXF1aXJlZEFsbFR5cGVzXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXF1aXJlZF9hbGxfdHlwZXMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcmVxdWlyZWRBbGxUeXBlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1JlcXVpcmVkQWxsVHlwZXMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXF1aXJlZF9hbGxfdHlwZXMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkQWxsVHlwZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRSZXF1aXJlZEFsbFR5cGVzKCkgewogICAgICByZXR1cm4gcmVxdWlyZWRBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcmVxdWlyZWRBbGxUeXBlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVxdWlyZWRfYWxsX3R5cGVzID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRSZXF1aXJlZEFsbFR5cGVzT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gcmVxdWlyZWRBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogcmVxdWlyZWRBbGxUeXBlc187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG9wdGlvbmFsQWxsVHlwZXNfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEFsbFR5cGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxBbGxUeXBlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE9wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSAyOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldE9wdGlvbmFsQWxsVHlwZXNPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9BTExfVFlQRVNfRklFTERfTlVNQkVSID0gMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gcmVwZWF0ZWRBbGxUeXBlc187CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEFsbFR5cGVzQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAzOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMR1JPVVBfRklFTERfTlVNQkVSID0gMTA7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIG9wdGlvbmFsR3JvdXBfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTAgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxncm91cCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsR3JvdXAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbGdyb3VwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAgZ2V0T3B0aW9uYWxHcm91cCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsR3JvdXBfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsR3JvdXBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTAgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwT3JCdWlsZGVyIGdldE9wdGlvbmFsR3JvdXBPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEdyb3VwXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEdyb3VwXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFREdST1VQX0ZJRUxEX05VTUJFUiA9IDIwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwPiByZXBlYXRlZEdyb3VwXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cD4gZ2V0UmVwZWF0ZWRHcm91cExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEdyb3VwXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXBPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkR3JvdXBPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRHcm91cF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkR3JvdXBDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkR3JvdXBfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCBnZXRSZXBlYXRlZEdyb3VwKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRHcm91cF8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cE9yQnVpbGRlciBnZXRSZXBlYXRlZEdyb3VwT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRHcm91cF8uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWhhc1JlcXVpcmVkQWxsVHlwZXMoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLkV4dGVuZGFibGVNZXNzYWdlPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZT4uRXh0ZW5zaW9uV3JpdGVyCiAgICAgICAgICBleHRlbnNpb25Xcml0ZXIgPSBuZXdFeHRlbnNpb25Xcml0ZXIoKTsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxLCBnZXRSZXF1aXJlZEFsbFR5cGVzKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMiwgZ2V0T3B0aW9uYWxBbGxUeXBlcygpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgzLCByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUdyb3VwKDEwLCBnZXRPcHRpb25hbEdyb3VwKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRHcm91cF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVHcm91cCgyMCwgcmVwZWF0ZWRHcm91cF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCg1MzY4NzA5MTIsIG91dHB1dCk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMSwgZ2V0UmVxdWlyZWRBbGxUeXBlcygpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgZ2V0T3B0aW9uYWxBbGxUeXBlcygpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDMsIHJlcGVhdGVkQWxsVHlwZXNfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUdyb3VwU2l6ZSgxMCwgZ2V0T3B0aW9uYWxHcm91cCgpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkR3JvdXBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUdyb3VwU2l6ZSgyMCwgcmVwZWF0ZWRHcm91cF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UpIG9iajsKCiAgICAgIGlmIChoYXNSZXF1aXJlZEFsbFR5cGVzKCkgIT0gb3RoZXIuaGFzUmVxdWlyZWRBbGxUeXBlcygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNSZXF1aXJlZEFsbFR5cGVzKCkpIHsKICAgICAgICBpZiAoIWdldFJlcXVpcmVkQWxsVHlwZXMoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcXVpcmVkQWxsVHlwZXMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxBbGxUeXBlcygpICE9IG90aGVyLmhhc09wdGlvbmFsQWxsVHlwZXMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxBbGxUeXBlcygpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbEFsbFR5cGVzKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEFsbFR5cGVzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEdyb3VwKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxHcm91cCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEdyb3VwKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsR3JvdXAoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsR3JvdXAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFJlcGVhdGVkR3JvdXBMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRHcm91cExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzUmVxdWlyZWRBbGxUeXBlcygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVRVUlSRURfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXF1aXJlZEFsbFR5cGVzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxBbGxUeXBlcygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEFsbFR5cGVzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRBbGxUeXBlc0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsR3JvdXAoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMR1JPVVBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsR3JvdXAoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEdyb3VwQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFREdST1VQX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEdyb3VwTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9IGhhc2hGaWVsZHMoaGFzaCwgZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFRlc3QgdGhhdCBpZiBhbiBvcHRpb25hbCBvciByZXF1aXJlZCBtZXNzYWdlL2dyb3VwIGZpZWxkIGFwcGVhcnMgbXVsdGlwbGUKICAgICAqIHRpbWVzIGluIHRoZSBpbnB1dCwgdGhleSBuZWVkIHRvIGJlIG1lcmdlZC4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UsIEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyZ2UpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRSZXF1aXJlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbEFsbFR5cGVzRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbEdyb3VwRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZEdyb3VwRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICByZXF1aXJlZEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgaWYgKHJlcXVpcmVkQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXF1aXJlZEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgcmVxdWlyZWRBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb3B0aW9uYWxHcm91cF8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEdyb3VwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxHcm91cEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRHcm91cF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UodGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlIHJlc3VsdCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRBbGxUeXBlc18gPSByZXBlYXRlZEFsbFR5cGVzXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQWxsVHlwZXNfID0gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkR3JvdXBfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRHcm91cF8pOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRHcm91cF8gPSByZXBlYXRlZEdyb3VwXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkR3JvdXBfID0gcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucmVxdWlyZWRBbGxUeXBlc18gPSByZXF1aXJlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gcmVxdWlyZWRBbGxUeXBlc18KICAgICAgICAgICAgICA6IHJlcXVpcmVkQWxsVHlwZXNCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsQWxsVHlwZXNfID0gb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwKICAgICAgICAgICAgICA/IG9wdGlvbmFsQWxsVHlwZXNfCiAgICAgICAgICAgICAgOiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEdyb3VwXyA9IG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbEdyb3VwXwogICAgICAgICAgICAgIDogb3B0aW9uYWxHcm91cEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSwgVHlwZT4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBhZGRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UsIFQ+IGV4dGVuc2lvbikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckV4dGVuc2lvbihleHRlbnNpb24pOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNSZXF1aXJlZEFsbFR5cGVzKCkpIHsKICAgICAgICAgIG1lcmdlUmVxdWlyZWRBbGxUeXBlcyhvdGhlci5nZXRSZXF1aXJlZEFsbFR5cGVzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxBbGxUeXBlcygpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsQWxsVHlwZXMob3RoZXIuZ2V0T3B0aW9uYWxBbGxUeXBlcygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQWxsVHlwZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBvdGhlci5yZXBlYXRlZEFsbFR5cGVzXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZEFsbChvdGhlci5yZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRBbGxUeXBlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gb3RoZXIucmVwZWF0ZWRBbGxUeXBlc187CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsR3JvdXAoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbEdyb3VwKG90aGVyLmdldE9wdGlvbmFsR3JvdXAoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEdyb3VwXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkR3JvdXBfID0gb3RoZXIucmVwZWF0ZWRHcm91cF87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkR3JvdXBJc011dGFibGUoKTsKICAgICAgICAgICAgICByZXBlYXRlZEdyb3VwXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRHcm91cF8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkR3JvdXBfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRHcm91cEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICByZXBlYXRlZEdyb3VwXyA9IG90aGVyLnJlcGVhdGVkR3JvdXBfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICAgICAgICByZXBlYXRlZEdyb3VwQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWRHcm91cEZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZEdyb3VwQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIucmVwZWF0ZWRHcm91cF8pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VFeHRlbnNpb25GaWVsZHMob3RoZXIpOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWhhc1JlcXVpcmVkQWxsVHlwZXMoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0UmVxdWlyZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSA4MzogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZEdyb3VwKDEwLAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsR3JvdXBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgzCiAgICAgICAgICAgICAgY2FzZSAxNjM6IHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRHcm91cCgyMCwKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEdyb3VwXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEdyb3VwQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjMKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyByZXF1aXJlZEFsbFR5cGVzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiByZXF1aXJlZEFsbFR5cGVzQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcXVpcmVkX2FsbF90eXBlcyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJlcXVpcmVkQWxsVHlwZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzUmVxdWlyZWRBbGxUeXBlcygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVxdWlyZWRfYWxsX3R5cGVzID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHJlcXVpcmVkQWxsVHlwZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0UmVxdWlyZWRBbGxUeXBlcygpIHsKICAgICAgICBpZiAocmVxdWlyZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXF1aXJlZEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXF1aXJlZEFsbFR5cGVzXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcXVpcmVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcXVpcmVkX2FsbF90eXBlcyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVxdWlyZWRBbGxUeXBlcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChyZXF1aXJlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXF1aXJlZEFsbFR5cGVzXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXF1aXJlZEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVxdWlyZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXF1aXJlZF9hbGxfdHlwZXMgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcXVpcmVkQWxsVHlwZXMoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXF1aXJlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVxdWlyZWRBbGxUeXBlc18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVxdWlyZWRBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVxdWlyZWRfYWxsX3R5cGVzID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZVJlcXVpcmVkQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVxdWlyZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICByZXF1aXJlZEFsbFR5cGVzXyAhPSBudWxsICYmCiAgICAgICAgICAgIHJlcXVpcmVkQWxsVHlwZXNfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldFJlcXVpcmVkQWxsVHlwZXNCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlcXVpcmVkQWxsVHlwZXNfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcXVpcmVkQWxsVHlwZXNCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAocmVxdWlyZWRBbGxUeXBlc18gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXF1aXJlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcXVpcmVkX2FsbF90eXBlcyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXF1aXJlZEFsbFR5cGVzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICByZXF1aXJlZEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgaWYgKHJlcXVpcmVkQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXF1aXJlZEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgcmVxdWlyZWRBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVxdWlyZWRfYWxsX3R5cGVzID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRSZXF1aXJlZEFsbFR5cGVzQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldFJlcXVpcmVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVxdWlyZWRfYWxsX3R5cGVzID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UmVxdWlyZWRBbGxUeXBlc09yQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVxdWlyZWRBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXF1aXJlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVxdWlyZWRBbGxUeXBlc18gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiByZXF1aXJlZEFsbFR5cGVzXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcXVpcmVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVxdWlyZWRfYWxsX3R5cGVzID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVxdWlyZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVxdWlyZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcXVpcmVkQWxsVHlwZXNCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldFJlcXVpcmVkQWxsVHlwZXMoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcXVpcmVkQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcXVpcmVkQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQWxsVHlwZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0T3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxBbGxUeXBlcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQWxsVHlwZXMoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc18gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0T3B0aW9uYWxBbGxUeXBlc09yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXMoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gcmVwZWF0ZWRBbGxUeXBlc18gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4ocmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEFsbFR5cGVzQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQWxsVHlwZXMoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQWxsVHlwZXMoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIG9wdGlvbmFsR3JvdXBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXBPckJ1aWxkZXI+IG9wdGlvbmFsR3JvdXBCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsZ3JvdXAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxHcm91cCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbGdyb3VwLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIGdldE9wdGlvbmFsR3JvdXAoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxHcm91cF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxHcm91cF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEdyb3VwQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEdyb3VwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsR3JvdXBfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTAgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsR3JvdXAoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxHcm91cF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxHcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbEdyb3VwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxHcm91cF8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbEdyb3VwXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbEdyb3VwQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbEdyb3VwXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEdyb3VwQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsR3JvdXAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9wdGlvbmFsR3JvdXBfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxHcm91cEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEdyb3VwQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDEwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAuQnVpbGRlciBnZXRPcHRpb25hbEdyb3VwQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsR3JvdXBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSAxMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwT3JCdWlsZGVyIGdldE9wdGlvbmFsR3JvdXBPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsR3JvdXBfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxHcm91cF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gMTAgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuT3B0aW9uYWxHcm91cE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbEdyb3VwRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxHcm91cEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLk9wdGlvbmFsR3JvdXAsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxHcm91cCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxHcm91cF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxHcm91cEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwPiByZXBlYXRlZEdyb3VwXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEdyb3VwXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwPihyZXBlYXRlZEdyb3VwXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXBPckJ1aWxkZXI+IHJlcGVhdGVkR3JvdXBCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cD4gZ2V0UmVwZWF0ZWRHcm91cExpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRHcm91cF8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRHcm91cENvdW50KCkgewogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkR3JvdXBfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAgZ2V0UmVwZWF0ZWRHcm91cChpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEdyb3VwXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEdyb3VwKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEdyb3VwXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEdyb3VwQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEdyb3VwKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRHcm91cF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRHcm91cChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEdyb3VwXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRHcm91cCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRHcm91cF8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRHcm91cCgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEdyb3VwXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRHcm91cCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkR3JvdXBJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkR3JvdXAoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkR3JvdXBJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkR3JvdXBfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEdyb3VwQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEdyb3VwKCkgewogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRHcm91cF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkR3JvdXAoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEdyb3VwXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAuQnVpbGRlciBnZXRSZXBlYXRlZEdyb3VwQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEdyb3VwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIFJlcGVhdGVkR3JvdXAgPSAyMCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwT3JCdWlsZGVyIGdldFJlcGVhdGVkR3JvdXBPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEdyb3VwXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEdyb3VwQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBSZXBlYXRlZEdyb3VwID0gMjAgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXBPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkR3JvdXBPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkR3JvdXBCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRHcm91cF8pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAuQnVpbGRlciBhZGRSZXBlYXRlZEdyb3VwQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRHcm91cEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAuQnVpbGRlciBhZGRSZXBlYXRlZEdyb3VwQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEdyb3VwRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgUmVwZWF0ZWRHcm91cCA9IDIwIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRHcm91cEJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEdyb3VwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZS5SZXBlYXRlZEdyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZEdyb3VwRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRHcm91cEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLlJlcGVhdGVkR3JvdXBPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZEdyb3VwXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXBlYXRlZEdyb3VwXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZEdyb3VwQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhcnNpbmdNZXJnZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhcnNpbmdNZXJnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQYXJzaW5nTWVyZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFBhcnNpbmdNZXJnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RQYXJzaW5nTWVyZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UGFyc2luZ01lcmdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQYXJzaW5nTWVyZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhcnNpbmdNZXJnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9FWFRfRklFTERfTlVNQkVSID0gMTAwMDsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFyc2luZ01lcmdlIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IG9wdGlvbmFsRXh0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMCwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmNsYXNzLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfRVhUX0ZJRUxEX05VTUJFUiA9IDEwMDE7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhcnNpbmdNZXJnZSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFyc2luZ01lcmdlLAogICAgICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPj4gcmVwZWF0ZWRFeHQgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYXJzaW5nTWVyZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAxLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuY2xhc3MsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RNZXJnZUV4Y2VwdGlvbk9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVyZ2VFeGNlcHRpb24pCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgYWxsX2V4dGVuc2lvbnMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYWxsRXh0ZW5zaW9ucyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQWxsRXh0ZW5zaW9ucygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgYWxsX2V4dGVuc2lvbnMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGFsbEV4dGVuc2lvbnMuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgZ2V0QWxsRXh0ZW5zaW9ucygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgYWxsX2V4dGVuc2lvbnMgPSAxOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9uc09yQnVpbGRlciBnZXRBbGxFeHRlbnNpb25zT3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVGVzdCB0aGF0IHRoZSBjb3JyZWN0IGV4Y2VwdGlvbiBpcyB0aHJvd24gYnkgcGFyc2VGcm9tIGluIGEgY29ybmVyIGNhc2UKICAgKiBpbnZvbHZpbmcgbWVyZ2luZywgZXh0ZW5zaW9ucywgYW5kIHJlcXVpcmVkIGZpZWxkcy4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXJnZUV4Y2VwdGlvbn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RNZXJnZUV4Y2VwdGlvbiBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVyZ2VFeGNlcHRpb24pCiAgICAgIFRlc3RNZXJnZUV4Y2VwdGlvbk9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE1lcmdlRXhjZXB0aW9uLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNZXJnZUV4Y2VwdGlvbihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RNZXJnZUV4Y2VwdGlvbigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TWVyZ2VFeGNlcHRpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVyZ2VFeGNlcHRpb25fZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVyZ2VFeGNlcHRpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24uQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEFMTF9FWFRFTlNJT05TX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgYWxsRXh0ZW5zaW9uc187CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyBhbGxfZXh0ZW5zaW9ucyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhbGxFeHRlbnNpb25zIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQWxsRXh0ZW5zaW9ucygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgYWxsX2V4dGVuc2lvbnMgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGFsbEV4dGVuc2lvbnMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIGdldEFsbEV4dGVuc2lvbnMoKSB7CiAgICAgIHJldHVybiBhbGxFeHRlbnNpb25zXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGFsbEV4dGVuc2lvbnNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgYWxsX2V4dGVuc2lvbnMgPSAxOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnNPckJ1aWxkZXIgZ2V0QWxsRXh0ZW5zaW9uc09yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIGFsbEV4dGVuc2lvbnNfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpIDogYWxsRXh0ZW5zaW9uc187CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKGhhc0FsbEV4dGVuc2lvbnMoKSkgewogICAgICAgIGlmICghZ2V0QWxsRXh0ZW5zaW9ucygpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEsIGdldEFsbEV4dGVuc2lvbnMoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRBbGxFeHRlbnNpb25zKCkpOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lcmdlRXhjZXB0aW9uKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbiBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbikgb2JqOwoKICAgICAgaWYgKGhhc0FsbEV4dGVuc2lvbnMoKSAhPSBvdGhlci5oYXNBbGxFeHRlbnNpb25zKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0FsbEV4dGVuc2lvbnMoKSkgewogICAgICAgIGlmICghZ2V0QWxsRXh0ZW5zaW9ucygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0QWxsRXh0ZW5zaW9ucygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0FsbEV4dGVuc2lvbnMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFMTF9FWFRFTlNJT05TX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBbGxFeHRlbnNpb25zKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lcmdlRXhjZXB0aW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24gcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbiBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lcmdlRXhjZXB0aW9uIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbiBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbiBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdCB0aGF0IHRoZSBjb3JyZWN0IGV4Y2VwdGlvbiBpcyB0aHJvd24gYnkgcGFyc2VGcm9tIGluIGEgY29ybmVyIGNhc2UKICAgICAqIGludm9sdmluZyBtZXJnaW5nLCBleHRlbnNpb25zLCBhbmQgcmVxdWlyZWQgZmllbGRzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lcmdlRXhjZXB0aW9ufQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lcmdlRXhjZXB0aW9uKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lcmdlRXhjZXB0aW9uT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXJnZUV4Y2VwdGlvbl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVyZ2VFeGNlcHRpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24uY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lcmdlRXhjZXB0aW9uLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24ubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0QWxsRXh0ZW5zaW9uc0ZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgYWxsRXh0ZW5zaW9uc18gPSBudWxsOwogICAgICAgIGlmIChhbGxFeHRlbnNpb25zQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgYWxsRXh0ZW5zaW9uc0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGFsbEV4dGVuc2lvbnNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVyZ2VFeGNlcHRpb25fZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lcmdlRXhjZXB0aW9uIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lcmdlRXhjZXB0aW9uIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24gYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lcmdlRXhjZXB0aW9uIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbiByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5hbGxFeHRlbnNpb25zXyA9IGFsbEV4dGVuc2lvbnNCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBhbGxFeHRlbnNpb25zXwogICAgICAgICAgICAgIDogYWxsRXh0ZW5zaW9uc0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24pb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24gb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNBbGxFeHRlbnNpb25zKCkpIHsKICAgICAgICAgIG1lcmdlQWxsRXh0ZW5zaW9ucyhvdGhlci5nZXRBbGxFeHRlbnNpb25zKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKGhhc0FsbEV4dGVuc2lvbnMoKSkgewogICAgICAgICAgaWYgKCFnZXRBbGxFeHRlbnNpb25zKCkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRBbGxFeHRlbnNpb25zRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgYWxsRXh0ZW5zaW9uc187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9uc09yQnVpbGRlcj4gYWxsRXh0ZW5zaW9uc0J1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIGFsbF9leHRlbnNpb25zID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYWxsRXh0ZW5zaW9ucyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNBbGxFeHRlbnNpb25zKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIGFsbF9leHRlbnNpb25zID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGFsbEV4dGVuc2lvbnMuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucyBnZXRBbGxFeHRlbnNpb25zKCkgewogICAgICAgIGlmIChhbGxFeHRlbnNpb25zQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGFsbEV4dGVuc2lvbnNfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpIDogYWxsRXh0ZW5zaW9uc187CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBhbGxFeHRlbnNpb25zQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIGFsbF9leHRlbnNpb25zID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRBbGxFeHRlbnNpb25zKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMgdmFsdWUpIHsKICAgICAgICBpZiAoYWxsRXh0ZW5zaW9uc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgYWxsRXh0ZW5zaW9uc18gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYWxsRXh0ZW5zaW9uc0J1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyBhbGxfZXh0ZW5zaW9ucyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QWxsRXh0ZW5zaW9ucygKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAoYWxsRXh0ZW5zaW9uc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGFsbEV4dGVuc2lvbnNfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGFsbEV4dGVuc2lvbnNCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgYWxsX2V4dGVuc2lvbnMgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlQWxsRXh0ZW5zaW9ucyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zIHZhbHVlKSB7CiAgICAgICAgaWYgKGFsbEV4dGVuc2lvbnNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgYWxsRXh0ZW5zaW9uc18gIT0gbnVsbCAmJgogICAgICAgICAgICBhbGxFeHRlbnNpb25zXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldEFsbEV4dGVuc2lvbnNCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGFsbEV4dGVuc2lvbnNfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGFsbEV4dGVuc2lvbnNCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoYWxsRXh0ZW5zaW9uc18gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgYWxsX2V4dGVuc2lvbnMgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQWxsRXh0ZW5zaW9ucygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgYWxsRXh0ZW5zaW9uc18gPSBudWxsOwogICAgICAgIGlmIChhbGxFeHRlbnNpb25zQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgYWxsRXh0ZW5zaW9uc0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGFsbEV4dGVuc2lvbnNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgYWxsX2V4dGVuc2lvbnMgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLkJ1aWxkZXIgZ2V0QWxsRXh0ZW5zaW9uc0J1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRBbGxFeHRlbnNpb25zRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgYWxsX2V4dGVuc2lvbnMgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zT3JCdWlsZGVyIGdldEFsbEV4dGVuc2lvbnNPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGFsbEV4dGVuc2lvbnNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gYWxsRXh0ZW5zaW9uc0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGFsbEV4dGVuc2lvbnNfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBhbGxFeHRlbnNpb25zXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyBhbGxfZXh0ZW5zaW9ucyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zT3JCdWlsZGVyPiAKICAgICAgICAgIGdldEFsbEV4dGVuc2lvbnNGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGFsbEV4dGVuc2lvbnNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBhbGxFeHRlbnNpb25zQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRBbGxFeHRlbnNpb25zKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBhbGxFeHRlbnNpb25zXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBhbGxFeHRlbnNpb25zQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lcmdlRXhjZXB0aW9uKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVyZ2VFeGNlcHRpb24pCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbiBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXJnZUV4Y2VwdGlvbigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24gZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVyZ2VFeGNlcHRpb24+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdE1lcmdlRXhjZXB0aW9uPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE1lcmdlRXhjZXB0aW9uIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lcmdlRXhjZXB0aW9uPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXJnZUV4Y2VwdGlvbj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVyZ2VFeGNlcHRpb24gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIComIzQ3OyAmbHQ7LSBUaGlzIHNob3VsZCBub3QgY2xvc2UgdGhlIGdlbmVyYXRlZCBkb2MgY29tbWVudAogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGEgPSAxIFtkZWZhdWx0ID0gIiomIzQ3OyAmbHQ7LSBOZWl0aGVyIHNob3VsZCB0aGlzLiJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzQSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogKiYjNDc7ICZsdDstIFRoaXMgc2hvdWxkIG5vdCBjbG9zZSB0aGUgZ2VuZXJhdGVkIGRvYyBjb21tZW50CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYSA9IDEgW2RlZmF1bHQgPSAiKiYjNDc7ICZsdDstIE5laXRoZXIgc2hvdWxkIHRoaXMuIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRBKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiAqJiM0NzsgJmx0Oy0gVGhpcyBzaG91bGQgbm90IGNsb3NlIHRoZSBnZW5lcmF0ZWQgZG9jIGNvbW1lbnQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhID0gMSBbZGVmYXVsdCA9ICIqJiM0NzsgJmx0Oy0gTmVpdGhlciBzaG91bGQgdGhpcy4iXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYS4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0QUJ5dGVzKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UpCiAgICAgIFRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSgpIHsKICAgICAgYV8gPSAiKi8gPC0gTmVpdGhlciBzaG91bGQgdGhpcy4iOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQV9GSUVMRF9OVU1CRVIgPSAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgYV8gPSAiKi8gPC0gTmVpdGhlciBzaG91bGQgdGhpcy4iOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogKiYjNDc7ICZsdDstIFRoaXMgc2hvdWxkIG5vdCBjbG9zZSB0aGUgZ2VuZXJhdGVkIGRvYyBjb21tZW50CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYSA9IDEgW2RlZmF1bHQgPSAiKiYjNDc7ICZsdDstIE5laXRoZXIgc2hvdWxkIHRoaXMuIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogKiYjNDc7ICZsdDstIFRoaXMgc2hvdWxkIG5vdCBjbG9zZSB0aGUgZ2VuZXJhdGVkIGRvYyBjb21tZW50CiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYSA9IDEgW2RlZmF1bHQgPSAiKiYjNDc7ICZsdDstIE5laXRoZXIgc2hvdWxkIHRoaXMuIl07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0QSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBhXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBhXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiAqJiM0NzsgJmx0Oy0gVGhpcyBzaG91bGQgbm90IGNsb3NlIHRoZSBnZW5lcmF0ZWQgZG9jIGNvbW1lbnQKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhID0gMSBbZGVmYXVsdCA9ICIqJiM0NzsgJmx0Oy0gTmVpdGhlciBzaG91bGQgdGhpcy4iXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldEFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBhXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgYV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMSwgYV8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDEsIGFfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UpIG9iajsKCiAgICAgIGlmIChoYXNBKCkgIT0gb3RoZXIuaGFzQSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBpZiAoIWdldEEoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldEEoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBBX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRBKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2VPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgYV8gPSAiKi8gPC0gTmVpdGhlciBzaG91bGQgdGhpcy4iOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5hXyA9IGFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzQSgpKSB7CiAgICAgICAgICBhXyA9IG90aGVyLmFfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGFfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGFfID0gIiovIDwtIE5laXRoZXIgc2hvdWxkIHRoaXMuIjsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIComIzQ3OyAmbHQ7LSBUaGlzIHNob3VsZCBub3QgY2xvc2UgdGhlIGdlbmVyYXRlZCBkb2MgY29tbWVudAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGEgPSAxIFtkZWZhdWx0ID0gIiomIzQ3OyAmbHQ7LSBOZWl0aGVyIHNob3VsZCB0aGlzLiJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiAqJiM0NzsgJmx0Oy0gVGhpcyBzaG91bGQgbm90IGNsb3NlIHRoZSBnZW5lcmF0ZWQgZG9jIGNvbW1lbnQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhID0gMSBbZGVmYXVsdCA9ICIqJiM0NzsgJmx0Oy0gTmVpdGhlciBzaG91bGQgdGhpcy4iXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGEuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRBKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYV87CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBhXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiAqJiM0NzsgJmx0Oy0gVGhpcyBzaG91bGQgbm90IGNsb3NlIHRoZSBnZW5lcmF0ZWQgZG9jIGNvbW1lbnQKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhID0gMSBbZGVmYXVsdCA9ICIqJiM0NzsgJmx0Oy0gTmVpdGhlciBzaG91bGQgdGhpcy4iXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBhLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0QUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIGFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogKiYjNDc7ICZsdDstIFRoaXMgc2hvdWxkIG5vdCBjbG9zZSB0aGUgZ2VuZXJhdGVkIGRvYyBjb21tZW50CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYSA9IDEgW2RlZmF1bHQgPSAiKiYjNDc7ICZsdDstIE5laXRoZXIgc2hvdWxkIHRoaXMuIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRBKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgYV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIComIzQ3OyAmbHQ7LSBUaGlzIHNob3VsZCBub3QgY2xvc2UgdGhlIGdlbmVyYXRlZCBkb2MgY29tbWVudAogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGEgPSAxIFtkZWZhdWx0ID0gIiomIzQ3OyAmbHQ7LSBOZWl0aGVyIHNob3VsZCB0aGlzLiJdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJBKCkgewogICAgICAgIGFfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0QSgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogKiYjNDc7ICZsdDstIFRoaXMgc2hvdWxkIG5vdCBjbG9zZSB0aGUgZ2VuZXJhdGVkIGRvYyBjb21tZW50CiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYSA9IDEgW2RlZmF1bHQgPSAiKiYjNDc7ICZsdDstIE5laXRoZXIgc2hvdWxkIHRoaXMuIl07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBhIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2U+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2U+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RNZXNzYWdlU2l6ZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNpemUpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG0xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG0xIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNNMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG0xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtMS4KICAgICAqLwogICAgYm9vbGVhbiBnZXRNMSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgbTIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbTIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc00yKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG0yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtMi4KICAgICAqLwogICAgbG9uZyBnZXRNMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBtMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTTMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBtMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbTMuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0TTMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBtNCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTTQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG00ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtNC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRNNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbTQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBtNC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0TTRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbTUgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc001KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG01ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtNS4KICAgICAqLwogICAgaW50IGdldE01KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBtNiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzTTYoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgbTYgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG02LgogICAgICovCiAgICBsb25nIGdldE02KCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVXNlZCB0byBjaGVjayB0aGF0IHRoZSBjKysgY29kZSBnZW5lcmF0b3IgcmUtb3JkZXJzIG1lc3NhZ2VzIHRvIHJlZHVjZQogICAqIHBhZGRpbmcuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVNpemV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0TWVzc2FnZVNpemUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTaXplKQogICAgICBUZXN0TWVzc2FnZVNpemVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RNZXNzYWdlU2l6ZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TWVzc2FnZVNpemUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TWVzc2FnZVNpemUoKSB7CiAgICAgIG00XyA9ICIiOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNZXNzYWdlU2l6ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2l6ZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2l6ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlU2l6ZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTTFfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgYm9vbGVhbiBtMV8gPSBmYWxzZTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBtMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc00xKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgbTEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG0xLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRNMSgpIHsKICAgICAgcmV0dXJuIG0xXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNMl9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBsb25nIG0yXyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBtMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc00yKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG0yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBtMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0TTIoKSB7CiAgICAgIHJldHVybiBtMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTTNfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgYm9vbGVhbiBtM18gPSBmYWxzZTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBtMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc00zKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgbTMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG0zLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRNMygpIHsKICAgICAgcmV0dXJuIG0zXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNNF9GSUVMRF9OVU1CRVIgPSA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgbTRfID0gIiI7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBtNCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc000KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBtNCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE00KCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG00XzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBtNF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbTQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBtNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE00Qnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gbTRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICBtNF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNNV9GSUVMRF9OVU1CRVIgPSA1OwogICAgcHJpdmF0ZSBpbnQgbTVfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgbTUgPSA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNNNSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBtNSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbTUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0TTUoKSB7CiAgICAgIHJldHVybiBtNV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTTZfRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgbG9uZyBtNl8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgbTYgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNNNigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBtNiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE02KCkgewogICAgICByZXR1cm4gbTZfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgxLCBtMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDIsIG0yXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgzLCBtM18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNCwgbTRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig1LCBtNV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDYsIG02Xyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSgxLCBtMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemUoMiwgbTJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQm9vbFNpemUoMywgbTNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDQsIG00Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg1LCBtNV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemUoNiwgbTZfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlU2l6ZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVNpemUgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVNpemUpIG9iajsKCiAgICAgIGlmIChoYXNNMSgpICE9IG90aGVyLmhhc00xKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc00xKCkpIHsKICAgICAgICBpZiAoZ2V0TTEoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRNMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc00yKCkgIT0gb3RoZXIuaGFzTTIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTTIoKSkgewogICAgICAgIGlmIChnZXRNMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldE0yKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzTTMoKSAhPSBvdGhlci5oYXNNMygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNNMygpKSB7CiAgICAgICAgaWYgKGdldE0zKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0TTMoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNNNCgpICE9IG90aGVyLmhhc000KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc000KCkpIHsKICAgICAgICBpZiAoIWdldE00KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRNNCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNNNSgpICE9IG90aGVyLmhhc001KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc001KCkpIHsKICAgICAgICBpZiAoZ2V0TTUoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRNNSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc002KCkgIT0gb3RoZXIuaGFzTTYoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTTYoKSkgewogICAgICAgIGlmIChnZXRNNigpCiAgICAgICAgICAgICE9IG90aGVyLmdldE02KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNNMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTTFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldE0xKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNNMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldE0yKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNNMygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTTNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldE0zKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNNNCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTTRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE00KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzTTUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE01X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRNNSgpOwogICAgICB9CiAgICAgIGlmIChoYXNNNigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTTZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldE02KCkpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVNpemUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlU2l6ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVNpemUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlU2l6ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBVc2VkIHRvIGNoZWNrIHRoYXQgdGhlIGMrKyBjb2RlIGdlbmVyYXRvciByZS1vcmRlcnMgbWVzc2FnZXMgdG8gcmVkdWNlCiAgICAgKiBwYWRkaW5nLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTaXplfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTaXplKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2l6ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNpemVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVNpemUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVNpemUubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIG0xXyA9IGZhbHNlOwogICAgICAgIG0yXyA9IDBMOwogICAgICAgIG0zXyA9IGZhbHNlOwogICAgICAgIG00XyA9ICIiOwogICAgICAgIG01XyA9IDA7CiAgICAgICAgbTZfID0gMEw7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2l6ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlU2l6ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlU2l6ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVNpemUgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVNpemUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlU2l6ZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVNpemUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm0xXyA9IG0xXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5tMl8gPSBtMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubTNfID0gbTNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm00XyA9IG00XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5tNV8gPSBtNV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQubTZfID0gbTZfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVNpemUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzTTEoKSkgewogICAgICAgICAgc2V0TTEob3RoZXIuZ2V0TTEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNNMigpKSB7CiAgICAgICAgICBzZXRNMihvdGhlci5nZXRNMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc00zKCkpIHsKICAgICAgICAgIHNldE0zKG90aGVyLmdldE0zKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzTTQoKSkgewogICAgICAgICAgbTRfID0gb3RoZXIubTRfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNNNSgpKSB7CiAgICAgICAgICBzZXRNNShvdGhlci5nZXRNNSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc002KCkpIHsKICAgICAgICAgIHNldE02KG90aGVyLmdldE02KCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIG0xXyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIG0yXyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgbTNfID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIG00XyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDM0CiAgICAgICAgICAgICAgY2FzZSA0MDogewogICAgICAgICAgICAgICAgbTVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDAKICAgICAgICAgICAgICBjYXNlIDQ4OiB7CiAgICAgICAgICAgICAgICBtNl8gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGJvb2xlYW4gbTFfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgbTEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc00xKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBtMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBtMS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0TTEoKSB7CiAgICAgICAgcmV0dXJuIG0xXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBtMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG0xIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TTEoYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBtMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgbTEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNMSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgbTFfID0gZmFsc2U7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBtMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgbTIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBtMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc00yKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgbTIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbTIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE0yKCkgewogICAgICAgIHJldHVybiBtMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG0yID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNMihsb25nIHZhbHVlKSB7CgogICAgICAgIG0yXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgbTIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJNMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgbTJfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYm9vbGVhbiBtM18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBtMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG0zIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzTTMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG0zID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG0zLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRNMygpIHsKICAgICAgICByZXR1cm4gbTNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG0zID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbTMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNMyhib29sZWFuIHZhbHVlKSB7CgogICAgICAgIG0zXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBtMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck0zKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBtM18gPSBmYWxzZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG00XyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG00ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbTQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzTTQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbTQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRNNCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG00XzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIG00XyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgbTQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG00LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0TTRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG00XzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgbTRfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG00ID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbTQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG00XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG00ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTTQoKSB7CiAgICAgICAgbTRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0TTQoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBtNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBtNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE00Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG00XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgbTVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG01ID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbTUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG01ID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG01LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE01KCkgewogICAgICAgIHJldHVybiBtNV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG01ID0gNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbTUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRNNShpbnQgdmFsdWUpIHsKCiAgICAgICAgbTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBtNSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck01KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBtNV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgbTZfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG02ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNNNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG02ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG02LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRNNigpIHsKICAgICAgICByZXR1cm4gbTZfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBtNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG02IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TTYobG9uZyB2YWx1ZSkgewoKICAgICAgICBtNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG02ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTTYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG02XyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlU2l6ZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VTaXplKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVNpemUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVNpemUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2VTaXplPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RNZXNzYWdlU2l6ZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RNZXNzYWdlU2l6ZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlU2l6ZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZVNpemU+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VTaXplIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgRm9vUmVxdWVzdE9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5Gb29SZXF1ZXN0KQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFRlc3QgdGhhdCBSUEMgc2VydmljZXMgd29yay4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkZvb1JlcXVlc3R9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBGb29SZXF1ZXN0IGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkZvb1JlcXVlc3QpCiAgICAgIEZvb1JlcXVlc3RPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEZvb1JlcXVlc3QubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgRm9vUmVxdWVzdChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEZvb1JlcXVlc3QoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgRm9vUmVxdWVzdCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Zvb1JlcXVlc3RfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29SZXF1ZXN0X2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0LmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1JlcXVlc3QuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0KSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1JlcXVlc3Qgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0KSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1JlcXVlc3QgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0IHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1JlcXVlc3QgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1JlcXVlc3QgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0IHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0IHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1JlcXVlc3QgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1JlcXVlc3QgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0IHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGVzdCB0aGF0IFJQQyBzZXJ2aWNlcyB3b3JrLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuRm9vUmVxdWVzdH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkZvb1JlcXVlc3QpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0T3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Zvb1JlcXVlc3RfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRm9vUmVxdWVzdF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1JlcXVlc3QuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdC5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Zvb1JlcXVlc3RfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0IGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0IHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1JlcXVlc3QodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1JlcXVlc3QpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1JlcXVlc3Qgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0LmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5Gb29SZXF1ZXN0KQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5Gb29SZXF1ZXN0KQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0IERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0IGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Rm9vUmVxdWVzdD4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxGb29SZXF1ZXN0PigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgRm9vUmVxdWVzdCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvb1JlcXVlc3Q+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Rm9vUmVxdWVzdD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0IGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgRm9vUmVzcG9uc2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuRm9vUmVzcG9uc2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkZvb1Jlc3BvbnNlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgRm9vUmVzcG9uc2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuRm9vUmVzcG9uc2UpCiAgICAgIEZvb1Jlc3BvbnNlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBGb29SZXNwb25zZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBGb29SZXNwb25zZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIEZvb1Jlc3BvbnNlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEZvb1Jlc3BvbnNlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRm9vUmVzcG9uc2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29SZXNwb25zZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlKSBvYmo7CgogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuRm9vUmVzcG9uc2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5Gb29SZXNwb25zZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Zvb1Jlc3BvbnNlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Zvb1Jlc3BvbnNlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRm9vUmVzcG9uc2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkZvb1Jlc3BvbnNlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5Gb29SZXNwb25zZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvb1Jlc3BvbnNlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEZvb1Jlc3BvbnNlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgRm9vUmVzcG9uc2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb29SZXNwb25zZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb29SZXNwb25zZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEZvb0NsaWVudE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuRm9vQ2xpZW50TWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuRm9vQ2xpZW50TWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEZvb0NsaWVudE1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuRm9vQ2xpZW50TWVzc2FnZSkKICAgICAgRm9vQ2xpZW50TWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgRm9vQ2xpZW50TWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBGb29DbGllbnRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgRm9vQ2xpZW50TWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBGb29DbGllbnRNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRm9vQ2xpZW50TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Zvb0NsaWVudE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29DbGllbnRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29DbGllbnRNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29DbGllbnRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkZvb0NsaWVudE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5Gb29DbGllbnRNZXNzYWdlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29DbGllbnRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Zvb0NsaWVudE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29DbGllbnRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29DbGllbnRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29DbGllbnRNZXNzYWdlKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29DbGllbnRNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29DbGllbnRNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuRm9vQ2xpZW50TWVzc2FnZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuRm9vQ2xpZW50TWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb0NsaWVudE1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvb0NsaWVudE1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Rm9vQ2xpZW50TWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEZvb0NsaWVudE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb29DbGllbnRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvb0NsaWVudE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vQ2xpZW50TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEZvb1NlcnZlck1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuRm9vU2VydmVyTWVzc2FnZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuRm9vU2VydmVyTWVzc2FnZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEZvb1NlcnZlck1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuRm9vU2VydmVyTWVzc2FnZSkKICAgICAgRm9vU2VydmVyTWVzc2FnZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgRm9vU2VydmVyTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBGb29TZXJ2ZXJNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgRm9vU2VydmVyTWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBGb29TZXJ2ZXJNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRm9vU2VydmVyTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Zvb1NlcnZlck1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29TZXJ2ZXJNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29TZXJ2ZXJNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29TZXJ2ZXJNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkZvb1NlcnZlck1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5Gb29TZXJ2ZXJNZXNzYWdlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29TZXJ2ZXJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Zvb1NlcnZlck1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29TZXJ2ZXJNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29TZXJ2ZXJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29TZXJ2ZXJNZXNzYWdlKHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29TZXJ2ZXJNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29TZXJ2ZXJNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuRm9vU2VydmVyTWVzc2FnZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuRm9vU2VydmVyTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1NlcnZlck1lc3NhZ2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvb1NlcnZlck1lc3NhZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8Rm9vU2VydmVyTWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEZvb1NlcnZlck1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxGb29TZXJ2ZXJNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEZvb1NlcnZlck1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vU2VydmVyTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEJhclJlcXVlc3RPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuQmFyUmVxdWVzdCkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQmFyUmVxdWVzdH0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJhclJlcXVlc3QgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQmFyUmVxdWVzdCkKICAgICAgQmFyUmVxdWVzdE9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgQmFyUmVxdWVzdC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBCYXJSZXF1ZXN0KGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgQmFyUmVxdWVzdCgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBCYXJSZXF1ZXN0KCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQmFyUmVxdWVzdF9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0JhclJlcXVlc3RfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QpIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXF1ZXN0IHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXF1ZXN0IHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXF1ZXN0IHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkJhclJlcXVlc3R9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5CYXJSZXF1ZXN0KQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdE9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9CYXJSZXF1ZXN0X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0JhclJlcXVlc3RfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXF1ZXN0LmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9CYXJSZXF1ZXN0X2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXF1ZXN0KHRoaXMpOwogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXF1ZXN0KSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3Qpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXF1ZXN0IG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQmFyUmVxdWVzdCkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQmFyUmVxdWVzdCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJhclJlcXVlc3Q+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8QmFyUmVxdWVzdD4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJhclJlcXVlc3QgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxCYXJSZXF1ZXN0PiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJhclJlcXVlc3Q+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEJhclJlc3BvbnNlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkJhclJlc3BvbnNlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5CYXJSZXNwb25zZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJhclJlc3BvbnNlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkJhclJlc3BvbnNlKQogICAgICBCYXJSZXNwb25zZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgQmFyUmVzcG9uc2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgQmFyUmVzcG9uc2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBCYXJSZXNwb25zZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBCYXJSZXNwb25zZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0JhclJlc3BvbnNlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQmFyUmVzcG9uc2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2UpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZSkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkJhclJlc3BvbnNlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQmFyUmVzcG9uc2UpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9CYXJSZXNwb25zZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9CYXJSZXNwb25zZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0JhclJlc3BvbnNlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZSh0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5CYXJSZXNwb25zZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQmFyUmVzcG9uc2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2UoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxCYXJSZXNwb25zZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxCYXJSZXNwb25zZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJhclJlc3BvbnNlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8QmFyUmVzcG9uc2U+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8QmFyUmVzcG9uc2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0SnNvbk5hbWVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEpzb25OYW1lKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfbmFtZTEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGROYW1lMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGROYW1lMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9uYW1lMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGROYW1lMS4KICAgICAqLwogICAgaW50IGdldEZpZWxkTmFtZTEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkTmFtZTIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGROYW1lMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGROYW1lMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZE5hbWUyID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE5hbWUyLgogICAgICovCiAgICBpbnQgZ2V0RmllbGROYW1lMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgRmllbGROYW1lMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE5hbWUzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZE5hbWUzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIEZpZWxkTmFtZTMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTmFtZTMuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZE5hbWUzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfZmllbGRfbmFtZTQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGROYW1lNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGROYW1lNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfZmllbGRfbmFtZTQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTmFtZTQuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZE5hbWU0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBGSUVMRF9OQU1FNSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmSUVMRE5BTUU1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGSUVMRE5BTUU1KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIEZJRUxEX05BTUU1ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmSUVMRE5BTUU1LgogICAgICovCiAgICBpbnQgZ2V0RklFTEROQU1FNSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfbmFtZTYgPSA2IFtqc29uX25hbWUgPSAiJiM2NDt0eXBlIl07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE5hbWU2IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZE5hbWU2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX25hbWU2ID0gNiBbanNvbl9uYW1lID0gIiYjNjQ7dHlwZSJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTmFtZTYuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZE5hbWU2KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZG5hbWU3ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkbmFtZTcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkbmFtZTcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRuYW1lNyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGRuYW1lNy4KICAgICAqLwogICAgaW50IGdldEZpZWxkbmFtZTcoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEpzb25OYW1lfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdEpzb25OYW1lIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RKc29uTmFtZSkKICAgICAgVGVzdEpzb25OYW1lT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0SnNvbk5hbWUubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdEpzb25OYW1lKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdEpzb25OYW1lKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RKc29uTmFtZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RKc29uTmFtZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RKc29uTmFtZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEpzb25OYW1lLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RKc29uTmFtZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTERfTkFNRTFfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IGZpZWxkTmFtZTFfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfbmFtZTEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGROYW1lMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkTmFtZTEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfbmFtZTEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTmFtZTEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGROYW1lMSgpIHsKICAgICAgcmV0dXJuIGZpZWxkTmFtZTFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxETkFNRTJfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgaW50IGZpZWxkTmFtZTJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGROYW1lMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE5hbWUyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGROYW1lMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZE5hbWUyID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE5hbWUyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkTmFtZTIoKSB7CiAgICAgIHJldHVybiBmaWVsZE5hbWUyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRE5BTUUzX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIGludCBmaWVsZE5hbWUzXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIEZpZWxkTmFtZTMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGROYW1lMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkTmFtZTMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgRmllbGROYW1lMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGROYW1lMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZE5hbWUzKCkgewogICAgICByZXR1cm4gZmllbGROYW1lM187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgX0ZJRUxEX05BTUU0X0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBwcml2YXRlIGludCBGaWVsZE5hbWU0XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF9maWVsZF9uYW1lNCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE5hbWU0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGROYW1lNCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfZmllbGRfbmFtZTQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTmFtZTQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGROYW1lNCgpIHsKICAgICAgcmV0dXJuIEZpZWxkTmFtZTRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX05BTUU1X0ZJRUxEX05VTUJFUiA9IDU7CiAgICBwcml2YXRlIGludCBmSUVMRE5BTUU1XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIEZJRUxEX05BTUU1ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZJRUxETkFNRTUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGSUVMRE5BTUU1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIEZJRUxEX05BTUU1ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmSUVMRE5BTUU1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZJRUxETkFNRTUoKSB7CiAgICAgIHJldHVybiBmSUVMRE5BTUU1XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRF9OQU1FNl9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBpbnQgZmllbGROYW1lNl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9uYW1lNiA9IDYgW2pzb25fbmFtZSA9ICImIzY0O3R5cGUiXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTmFtZTYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZE5hbWU2KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX25hbWU2ID0gNiBbanNvbl9uYW1lID0gIiYjNjQ7dHlwZSJdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkTmFtZTYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGROYW1lNigpIHsKICAgICAgcmV0dXJuIGZpZWxkTmFtZTZfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxETkFNRTdfRklFTERfTlVNQkVSID0gNzsKICAgIHByaXZhdGUgaW50IGZpZWxkbmFtZTdfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRuYW1lNyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZG5hbWU3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGRuYW1lNygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZG5hbWU3ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZG5hbWU3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkbmFtZTcoKSB7CiAgICAgIHJldHVybiBmaWVsZG5hbWU3XzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGZpZWxkTmFtZTFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyLCBmaWVsZE5hbWUyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMywgZmllbGROYW1lM18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDQsIEZpZWxkTmFtZTRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig1LCBmSUVMRE5BTUU1Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNiwgZmllbGROYW1lNl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDcsIGZpZWxkbmFtZTdfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBmaWVsZE5hbWUxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgyLCBmaWVsZE5hbWUyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgzLCBmaWVsZE5hbWUzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg0LCBGaWVsZE5hbWU0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg1LCBmSUVMRE5BTUU1Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg2LCBmaWVsZE5hbWU2Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg3LCBmaWVsZG5hbWU3Xyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWUpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEpzb25OYW1lIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEpzb25OYW1lKSBvYmo7CgogICAgICBpZiAoaGFzRmllbGROYW1lMSgpICE9IG90aGVyLmhhc0ZpZWxkTmFtZTEoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGROYW1lMSgpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkTmFtZTEoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZE5hbWUxKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGROYW1lMigpICE9IG90aGVyLmhhc0ZpZWxkTmFtZTIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGROYW1lMigpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkTmFtZTIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZE5hbWUyKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGROYW1lMygpICE9IG90aGVyLmhhc0ZpZWxkTmFtZTMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGROYW1lMygpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkTmFtZTMoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZE5hbWUzKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGROYW1lNCgpICE9IG90aGVyLmhhc0ZpZWxkTmFtZTQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGROYW1lNCgpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkTmFtZTQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZE5hbWU0KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRklFTEROQU1FNSgpICE9IG90aGVyLmhhc0ZJRUxETkFNRTUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRklFTEROQU1FNSgpKSB7CiAgICAgICAgaWYgKGdldEZJRUxETkFNRTUoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGSUVMRE5BTUU1KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGROYW1lNigpICE9IG90aGVyLmhhc0ZpZWxkTmFtZTYoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGROYW1lNigpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkTmFtZTYoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZE5hbWU2KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGRuYW1lNygpICE9IG90aGVyLmhhc0ZpZWxkbmFtZTcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGRuYW1lNygpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkbmFtZTcoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZG5hbWU3KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNGaWVsZE5hbWUxKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRF9OQU1FMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGROYW1lMSgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZE5hbWUyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRE5BTUUyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZE5hbWUyKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkTmFtZTMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxETkFNRTNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkTmFtZTMoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGROYW1lNCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgX0ZJRUxEX05BTUU0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZE5hbWU0KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZJRUxETkFNRTUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX05BTUU1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGSUVMRE5BTUU1KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkTmFtZTYoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEX05BTUU2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZE5hbWU2KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkbmFtZTcoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxETkFNRTdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkbmFtZTcoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEpzb25OYW1lIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RKc29uTmFtZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RKc29uTmFtZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RKc29uTmFtZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEpzb25OYW1lIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RKc29uTmFtZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RKc29uTmFtZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RKc29uTmFtZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0SnNvbk5hbWV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0SnNvbk5hbWUpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEpzb25OYW1lX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RKc29uTmFtZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RKc29uTmFtZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWUuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RKc29uTmFtZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgZmllbGROYW1lMV8gPSAwOwogICAgICAgIGZpZWxkTmFtZTJfID0gMDsKICAgICAgICBmaWVsZE5hbWUzXyA9IDA7CiAgICAgICAgRmllbGROYW1lNF8gPSAwOwogICAgICAgIGZJRUxETkFNRTVfID0gMDsKICAgICAgICBmaWVsZE5hbWU2XyA9IDA7CiAgICAgICAgZmllbGRuYW1lN18gPSAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SnNvbk5hbWVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEpzb25OYW1lIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEpzb25OYW1lIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEpzb25OYW1lIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RKc29uTmFtZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RKc29uTmFtZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZE5hbWUxXyA9IGZpZWxkTmFtZTFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZpZWxkTmFtZTJfID0gZmllbGROYW1lMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGROYW1lM18gPSBmaWVsZE5hbWUzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5GaWVsZE5hbWU0XyA9IEZpZWxkTmFtZTRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZJRUxETkFNRTVfID0gZklFTEROQU1FNV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGROYW1lNl8gPSBmaWVsZE5hbWU2XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maWVsZG5hbWU3XyA9IGZpZWxkbmFtZTdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEpzb25OYW1lKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEpzb25OYW1lIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEpzb25OYW1lLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzRmllbGROYW1lMSgpKSB7CiAgICAgICAgICBzZXRGaWVsZE5hbWUxKG90aGVyLmdldEZpZWxkTmFtZTEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZE5hbWUyKCkpIHsKICAgICAgICAgIHNldEZpZWxkTmFtZTIob3RoZXIuZ2V0RmllbGROYW1lMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkTmFtZTMoKSkgewogICAgICAgICAgc2V0RmllbGROYW1lMyhvdGhlci5nZXRGaWVsZE5hbWUzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGROYW1lNCgpKSB7CiAgICAgICAgICBzZXRGaWVsZE5hbWU0KG90aGVyLmdldEZpZWxkTmFtZTQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGSUVMRE5BTUU1KCkpIHsKICAgICAgICAgIHNldEZJRUxETkFNRTUob3RoZXIuZ2V0RklFTEROQU1FNSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkTmFtZTYoKSkgewogICAgICAgICAgc2V0RmllbGROYW1lNihvdGhlci5nZXRGaWVsZE5hbWU2KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGRuYW1lNygpKSB7CiAgICAgICAgICBzZXRGaWVsZG5hbWU3KG90aGVyLmdldEZpZWxkbmFtZTcoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgZmllbGROYW1lMV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgZmllbGROYW1lMl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMjQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkTmFtZTNfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQKICAgICAgICAgICAgICBjYXNlIDMyOiB7CiAgICAgICAgICAgICAgICBGaWVsZE5hbWU0XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyCiAgICAgICAgICAgICAgY2FzZSA0MDogewogICAgICAgICAgICAgICAgZklFTEROQU1FNV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MAogICAgICAgICAgICAgIGNhc2UgNDg6IHsKICAgICAgICAgICAgICAgIGZpZWxkTmFtZTZfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDgKICAgICAgICAgICAgICBjYXNlIDU2OiB7CiAgICAgICAgICAgICAgICBmaWVsZG5hbWU3XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDU2CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGZpZWxkTmFtZTFfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkX25hbWUxID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGROYW1lMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkTmFtZTEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9uYW1lMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE5hbWUxLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTmFtZTEoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkTmFtZTFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9uYW1lMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkTmFtZTEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZE5hbWUxKGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZE5hbWUxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfbmFtZTEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZE5hbWUxKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBmaWVsZE5hbWUxXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkTmFtZTJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkTmFtZTIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE5hbWUyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGROYW1lMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkTmFtZTIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGROYW1lMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZE5hbWUyKCkgewogICAgICAgIHJldHVybiBmaWVsZE5hbWUyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGROYW1lMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkTmFtZTIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZE5hbWUyKGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZE5hbWUyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGROYW1lMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTmFtZTIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGZpZWxkTmFtZTJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGROYW1lM18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgRmllbGROYW1lMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTmFtZTMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZE5hbWUzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgRmllbGROYW1lMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE5hbWUzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTmFtZTMoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkTmFtZTNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBGaWVsZE5hbWUzID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGROYW1lMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkTmFtZTMoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkTmFtZTNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBGaWVsZE5hbWUzID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGROYW1lMygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgZmllbGROYW1lM18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBGaWVsZE5hbWU0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfZmllbGRfbmFtZTQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZE5hbWU0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGROYW1lNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF9maWVsZF9uYW1lNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE5hbWU0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTmFtZTQoKSB7CiAgICAgICAgcmV0dXJuIEZpZWxkTmFtZTRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBfZmllbGRfbmFtZTQgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZE5hbWU0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGROYW1lNChpbnQgdmFsdWUpIHsKCiAgICAgICAgRmllbGROYW1lNF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIF9maWVsZF9uYW1lNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkTmFtZTQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIEZpZWxkTmFtZTRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZklFTEROQU1FNV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgRklFTERfTkFNRTUgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmSUVMRE5BTUU1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRklFTEROQU1FNSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIEZJRUxEX05BTUU1ID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZJRUxETkFNRTUuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RklFTEROQU1FNSgpIHsKICAgICAgICByZXR1cm4gZklFTEROQU1FNV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIEZJRUxEX05BTUU1ID0gNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZklFTEROQU1FNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZJRUxETkFNRTUoaW50IHZhbHVlKSB7CgogICAgICAgIGZJRUxETkFNRTVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBGSUVMRF9OQU1FNSA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZJRUxETkFNRTUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIGZJRUxETkFNRTVfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGROYW1lNl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfbmFtZTYgPSA2IFtqc29uX25hbWUgPSAiJiM2NDt0eXBlIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkTmFtZTYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZE5hbWU2KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGRfbmFtZTYgPSA2IFtqc29uX25hbWUgPSAiJiM2NDt0eXBlIl07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZE5hbWU2LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkTmFtZTYoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkTmFtZTZfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9uYW1lNiA9IDYgW2pzb25fbmFtZSA9ICImIzY0O3R5cGUiXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGROYW1lNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkTmFtZTYoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkTmFtZTZfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZF9uYW1lNiA9IDYgW2pzb25fbmFtZSA9ICImIzY0O3R5cGUiXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGROYW1lNigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgZmllbGROYW1lNl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmaWVsZG5hbWU3XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZG5hbWU3ID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGRuYW1lNyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkbmFtZTcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZG5hbWU3ID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkbmFtZTcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGRuYW1lNygpIHsKICAgICAgICByZXR1cm4gZmllbGRuYW1lN187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkbmFtZTcgPSA3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZG5hbWU3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGRuYW1lNyhpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGRuYW1lN18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkbmFtZTcgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZG5hbWU3KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBmaWVsZG5hbWU3XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEpzb25OYW1lKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0SnNvbk5hbWUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RKc29uTmFtZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RKc29uTmFtZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0SnNvbk5hbWU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEpzb25OYW1lPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdEpzb25OYW1lIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEpzb25OYW1lPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RKc29uTmFtZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SnNvbk5hbWUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0SHVnZUZpZWxkTnVtYmVyc09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0SHVnZUZpZWxkTnVtYmVycykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxUZXN0SHVnZUZpZWxkTnVtYmVycz4gewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSA1MzY4NzAwMDA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gNTM2ODcwMDAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaXhlZF8zMiA9IDUzNjg3MDAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpeGVkMzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpeGVkMzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZml4ZWRfMzIgPSA1MzY4NzAwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZml4ZWQzMi4KICAgICAqLwogICAgaW50IGdldEZpeGVkMzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gNTM2ODcwMDAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkSW50MzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gNTM2ODcwMDAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW50MzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDUzNjg3MDAwMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDMyKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA1MzY4NzAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDMyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkSW50MzJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDUzNjg3MDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50MzIuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRJbnQzMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDUzNjg3MDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRJbnQzMihpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2VudW0gPSA1MzY4NzAwMDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEVudW0gZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsRW51bSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZW51bSA9IDUzNjg3MDAwNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEVudW0uCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0T3B0aW9uYWxFbnVtKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gNTM2ODcwMDA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSA1MzY4NzAwMDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDUzNjg3MDAwNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsU3RyaW5nQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gNTM2ODcwMDA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxCeXRlcygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHRpb25hbF9ieXRlcyA9IDUzNjg3MDAwNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJ5dGVzLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T3B0aW9uYWxCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX21lc3NhZ2UgPSA1MzY4NzAwMDc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfbWVzc2FnZSA9IDUzNjg3MDAwNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgZ2V0T3B0aW9uYWxNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9tZXNzYWdlID0gNTM2ODcwMDA3OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSA1MzY4NzAwMDggeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxncm91cCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxHcm91cCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gNTM2ODcwMDA4IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbGdyb3VwLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAgZ2V0T3B0aW9uYWxHcm91cCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gNTM2ODcwMDA4IHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cE9yQnVpbGRlciBnZXRPcHRpb25hbEdyb3VwT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IHN0cmluZ19zdHJpbmdfbWFwID0gNTM2ODcwMDEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFN0cmluZ1N0cmluZ01hcENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgc3RyaW5nX3N0cmluZ19tYXAgPSA1MzY4NzAwMTA7PC9jb2RlPgogICAgICovCiAgICBib29sZWFuIGNvbnRhaW5zU3RyaW5nU3RyaW5nTWFwKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0U3RyaW5nU3RyaW5nTWFwTWFwKCl9IGluc3RlYWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgZ2V0U3RyaW5nU3RyaW5nTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgc3RyaW5nX3N0cmluZ19tYXAgPSA1MzY4NzAwMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRTdHJpbmdTdHJpbmdNYXBNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBzdHJpbmdfc3RyaW5nX21hcCA9IDUzNjg3MDAxMDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nU3RyaW5nTWFwT3JEZWZhdWx0KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZGVmYXVsdFZhbHVlKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBzdHJpbmdfc3RyaW5nX21hcCA9IDUzNjg3MDAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nU3RyaW5nTWFwT3JUaHJvdygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gNTM2ODcwMDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZVaW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09uZW9mVWludDMyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSA1MzY4NzAwMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb25lb2ZVaW50MzIuCiAgICAgKi8KICAgIGludCBnZXRPbmVvZlVpbnQzMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvbmVvZl90ZXN0X2FsbF90eXBlcyA9IDUzNjg3MDAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mVGVzdEFsbFR5cGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPbmVvZlRlc3RBbGxUeXBlcygpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9uZW9mX3Rlc3RfYWxsX3R5cGVzID0gNTM2ODcwMDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mVGVzdEFsbFR5cGVzLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRPbmVvZlRlc3RBbGxUeXBlcygpOwogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9uZW9mX3Rlc3RfYWxsX3R5cGVzID0gNTM2ODcwMDEyOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0T25lb2ZUZXN0QWxsVHlwZXNPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSA1MzY4NzAwMTM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT25lb2ZTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDUzNjg3MDAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZlN0cmluZy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRPbmVvZlN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gNTM2ODcwMDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvbmVvZlN0cmluZy4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T25lb2ZTdHJpbmdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSA1MzY4NzAwMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZkJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPbmVvZkJ5dGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gNTM2ODcwMDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mQnl0ZXMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPbmVvZkJ5dGVzKCk7CgogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PbmVvZkZpZWxkQ2FzZSBnZXRPbmVvZkZpZWxkQ2FzZSgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0SHVnZUZpZWxkTnVtYmVyc30KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RIdWdlRmllbGROdW1iZXJzIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZU1lc3NhZ2U8CiAgICAgICAgVGVzdEh1Z2VGaWVsZE51bWJlcnM+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0SHVnZUZpZWxkTnVtYmVycykKICAgICAgVGVzdEh1Z2VGaWVsZE51bWJlcnNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RIdWdlRmllbGROdW1iZXJzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RIdWdlRmllbGROdW1iZXJzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMsID8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RIdWdlRmllbGROdW1iZXJzKCkgewogICAgICByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgb3B0aW9uYWxFbnVtXyA9IDQ7CiAgICAgIG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgICBvcHRpb25hbEJ5dGVzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0SHVnZUZpZWxkTnVtYmVycygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RIdWdlRmllbGROdW1iZXJzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgNTM2ODcwMDEwOgogICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nU3RyaW5nTWFwKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICJJbnZhbGlkIG1hcCBmaWVsZCBudW1iZXI6ICIgKyBudW1iZXIpOwogICAgICB9CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SHVnZUZpZWxkTnVtYmVyc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBPcHRpb25hbEdyb3VwT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cCkKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGdyb3VwX2EgPSA1MzY4NzAwMDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGdyb3VwQSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc0dyb3VwQSgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZ3JvdXBfYSA9IDUzNjg3MDAwOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGdyb3VwQS4KICAgICAgICovCiAgICAgIGludCBnZXRHcm91cEEoKTsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBPcHRpb25hbEdyb3VwIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwKQogICAgICAgIE9wdGlvbmFsR3JvdXBPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBPcHRpb25hbEdyb3VwLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICAgIHByaXZhdGUgT3B0aW9uYWxHcm91cChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgfQogICAgICBwcml2YXRlIE9wdGlvbmFsR3JvdXAoKSB7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICAgIHJldHVybiBuZXcgT3B0aW9uYWxHcm91cCgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEh1Z2VGaWVsZE51bWJlcnNfT3B0aW9uYWxHcm91cF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SHVnZUZpZWxkTnVtYmVyc19PcHRpb25hbEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBHUk9VUF9BX0ZJRUxEX05VTUJFUiA9IDUzNjg3MDAwOTsKICAgICAgcHJpdmF0ZSBpbnQgZ3JvdXBBXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBncm91cF9hID0gNTM2ODcwMDA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBncm91cEEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNHcm91cEEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBncm91cF9hID0gNTM2ODcwMDA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZ3JvdXBBLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEdyb3VwQSgpIHsKICAgICAgICByZXR1cm4gZ3JvdXBBXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZUludDMyKDUzNjg3MDAwOSwgZ3JvdXBBXyk7CiAgICAgICAgfQogICAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgIHNpemUgPSAwOwogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDUzNjg3MDAwOSwgZ3JvdXBBXyk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cCkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cCkgb2JqOwoKICAgICAgICBpZiAoaGFzR3JvdXBBKCkgIT0gb3RoZXIuaGFzR3JvdXBBKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzR3JvdXBBKCkpIHsKICAgICAgICAgIGlmIChnZXRHcm91cEEoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEdyb3VwQSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICB9CiAgICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICBpZiAoaGFzR3JvdXBBKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEdST1VQX0FfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0R3JvdXBBKCk7CiAgICAgICAgfQogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cCBwcm90b3R5cGUpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgIHJldHVybiBidWlsZGVyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwKQogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RIdWdlRmllbGROdW1iZXJzX09wdGlvbmFsR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RIdWdlRmllbGROdW1iZXJzX09wdGlvbmFsR3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cC5uZXdCdWlsZGVyKCkKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIGdyb3VwQV8gPSAwOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SHVnZUZpZWxkTnVtYmVyc19PcHRpb25hbEdyb3VwX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIGJ1aWxkKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAodGhpcyk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cCByZXN1bHQpIHsKICAgICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0Lmdyb3VwQV8gPSBncm91cEFfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cClvdGhlcik7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAgb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgaWYgKG90aGVyLmhhc0dyb3VwQSgpKSB7CiAgICAgICAgICAgIHNldEdyb3VwQShvdGhlci5nZXRHcm91cEEoKSk7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIC03MjI0OiB7CiAgICAgICAgICAgICAgICAgIGdyb3VwQV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSAtNzIyNAogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBpbnQgZ3JvdXBBXyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZ3JvdXBfYSA9IDUzNjg3MDAwOTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBncm91cEEgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNHcm91cEEoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGdyb3VwX2EgPSA1MzY4NzAwMDk7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGdyb3VwQS4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRHcm91cEEoKSB7CiAgICAgICAgICByZXR1cm4gZ3JvdXBBXzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZ3JvdXBfYSA9IDUzNjg3MDAwOTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBncm91cEEgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRHcm91cEEoaW50IHZhbHVlKSB7CgogICAgICAgICAgZ3JvdXBBXyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZ3JvdXBfYSA9IDUzNjg3MDAwOTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyR3JvdXBBKCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgZ3JvdXBBXyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCgogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXApCiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAgREVGQVVMVF9JTlNUQU5DRTsKICAgICAgc3RhdGljIHsKICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cCgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE9wdGlvbmFsR3JvdXA+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxPcHRpb25hbEdyb3VwPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE9wdGlvbmFsR3JvdXAgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPcHRpb25hbEdyb3VwPiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8T3B0aW9uYWxHcm91cD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHJpdmF0ZSBpbnQgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9uZW9mRmllbGRfOwogICAgcHVibGljIGVudW0gT25lb2ZGaWVsZENhc2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGUsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlLkludGVybmFsT25lT2ZFbnVtIHsKICAgICAgT05FT0ZfVUlOVDMyKDUzNjg3MDAxMSksCiAgICAgIE9ORU9GX1RFU1RfQUxMX1RZUEVTKDUzNjg3MDAxMiksCiAgICAgIE9ORU9GX1NUUklORyg1MzY4NzAwMTMpLAogICAgICBPTkVPRl9CWVRFUyg1MzY4NzAwMTQpLAogICAgICBPTkVPRkZJRUxEX05PVF9TRVQoMCk7CiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwogICAgICBwcml2YXRlIE9uZW9mRmllbGRDYXNlKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1iZXIgb2YgdGhlIGVudW0gdG8gbG9vayBmb3IuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1iZXIuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgT25lb2ZGaWVsZENhc2UgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBPbmVvZkZpZWxkQ2FzZSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSA1MzY4NzAwMTE6IHJldHVybiBPTkVPRl9VSU5UMzI7CiAgICAgICAgICBjYXNlIDUzNjg3MDAxMjogcmV0dXJuIE9ORU9GX1RFU1RfQUxMX1RZUEVTOwogICAgICAgICAgY2FzZSA1MzY4NzAwMTM6IHJldHVybiBPTkVPRl9TVFJJTkc7CiAgICAgICAgICBjYXNlIDUzNjg3MDAxNDogcmV0dXJuIE9ORU9GX0JZVEVTOwogICAgICAgICAgY2FzZSAwOiByZXR1cm4gT05FT0ZGSUVMRF9OT1RfU0VUOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB0aGlzLnZhbHVlOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBPbmVvZkZpZWxkQ2FzZQogICAgZ2V0T25lb2ZGaWVsZENhc2UoKSB7CiAgICAgIHJldHVybiBPbmVvZkZpZWxkQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8pOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyX0ZJRUxEX05VTUJFUiA9IDUzNjg3MDAwMDsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSA1MzY4NzAwMDA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMiA9IDUzNjg3MDAwMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDMyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSVhFRF8zMl9GSUVMRF9OVU1CRVIgPSA1MzY4NzAwMDE7CiAgICBwcml2YXRlIGludCBmaXhlZDMyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpeGVkXzMyID0gNTM2ODcwMDAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZml4ZWQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpeGVkMzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZml4ZWRfMzIgPSA1MzY4NzAwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZml4ZWQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaXhlZDMyKCkgewogICAgICByZXR1cm4gZml4ZWQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSID0gNTM2ODcwMDAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEludDMyXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gNTM2ODcwMDAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgIGdldFJlcGVhdGVkSW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gNTM2ODcwMDAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gNTM2ODcwMDAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfSU5UMzJfRklFTERfTlVNQkVSID0gNTM2ODcwMDAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRJbnQzMl8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA1MzY4NzAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UGFja2VkSW50MzJMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkSW50MzJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA1MzY4NzAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMyQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQzMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA1MzY4NzAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkSW50MzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkSW50MzJfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRJbnQzMk1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9FTlVNX0ZJRUxEX05VTUJFUiA9IDUzNjg3MDAwNDsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsRW51bV8gPSA0OwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZW51bSA9IDUzNjg3MDAwNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsRW51bSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxFbnVtKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9lbnVtID0gNTM2ODcwMDA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRW51bS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bSBnZXRPcHRpb25hbEVudW0oKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIob3B0aW9uYWxFbnVtXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uRk9SRUlHTl9GT08gOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDUzNjg3MDAwNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gNTM2ODcwMDA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFN0cmluZygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gNTM2ODcwMDA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDUzNjg3MDAwNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmcuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFN0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQllURVNfRklFTERfTlVNQkVSID0gNTM2ODcwMDA2OwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgb3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gNTM2ODcwMDA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQnl0ZXMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXMgPSA1MzY4NzAwMDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxCeXRlc187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSA1MzY4NzAwMDc7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxNZXNzYWdlXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX21lc3NhZ2UgPSA1MzY4NzAwMDc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX21lc3NhZ2UgPSA1MzY4NzAwMDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBnZXRPcHRpb25hbE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX21lc3NhZ2UgPSA1MzY4NzAwMDc7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxNZXNzYWdlXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTEdST1VQX0ZJRUxEX05VTUJFUiA9IDUzNjg3MDAwODsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIG9wdGlvbmFsR3JvdXBfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gNTM2ODcwMDA4IHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsZ3JvdXAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEdyb3VwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSA1MzY4NzAwMDggeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsZ3JvdXAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAgZ2V0T3B0aW9uYWxHcm91cCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsR3JvdXBfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEdyb3VwXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDUzNjg3MDAwOCB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwT3JCdWlsZGVyIGdldE9wdGlvbmFsR3JvdXBPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEdyb3VwXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxHcm91cF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU1RSSU5HX1NUUklOR19NQVBfRklFTERfTlVNQkVSID0gNTM2ODcwMDEwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgU3RyaW5nU3RyaW5nTWFwRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SHVnZUZpZWxkTnVtYmVyc19TdHJpbmdTdHJpbmdNYXBFbnRyeV9kZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5XaXJlRm9ybWF0LkZpZWxkVHlwZS5TVFJJTkcsCiAgICAgICAgICAgICAgICAgICIiLAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIpOwogICAgfQogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gc3RyaW5nU3RyaW5nTWFwXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRTdHJpbmdTdHJpbmdNYXAoKSB7CiAgICAgIGlmIChzdHJpbmdTdHJpbmdNYXBfID09IG51bGwpIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZC5lbXB0eU1hcEZpZWxkKAogICAgICAgICAgICBTdHJpbmdTdHJpbmdNYXBEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gc3RyaW5nU3RyaW5nTWFwXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nU3RyaW5nTWFwQ291bnQoKSB7CiAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1N0cmluZ01hcCgpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBzdHJpbmdfc3RyaW5nX21hcCA9IDUzNjg3MDAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zU3RyaW5nU3RyaW5nTWFwKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdTdHJpbmdNYXAoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRTdHJpbmdTdHJpbmdNYXBNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRTdHJpbmdTdHJpbmdNYXAoKSB7CiAgICAgIHJldHVybiBnZXRTdHJpbmdTdHJpbmdNYXBNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBzdHJpbmdfc3RyaW5nX21hcCA9IDUzNjg3MDAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldFN0cmluZ1N0cmluZ01hcE1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nU3RyaW5nTWFwKCkuZ2V0TWFwKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgc3RyaW5nX3N0cmluZ19tYXAgPSA1MzY4NzAwMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRTdHJpbmdTdHJpbmdNYXBPckRlZmF1bHQoCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nU3RyaW5nTWFwKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBzdHJpbmdfc3RyaW5nX21hcCA9IDUzNjg3MDAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ1N0cmluZ01hcE9yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nU3RyaW5nTWFwKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FT0ZfVUlOVDMyX0ZJRUxEX05VTUJFUiA9IDUzNjg3MDAxMTsKICAgIC8qKgogICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDUzNjg3MDAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mVWludDMyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZVaW50MzIoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDExOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT51aW50MzIgb25lb2ZfdWludDMyID0gNTM2ODcwMDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mVWludDMyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9uZW9mVWludDMyKCkgewogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDUzNjg3MDAxMSkgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX1RFU1RfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUiA9IDUzNjg3MDAxMjsKICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvbmVvZl90ZXN0X2FsbF90eXBlcyA9IDUzNjg3MDAxMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9uZW9mVGVzdEFsbFR5cGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZUZXN0QWxsVHlwZXMoKSB7CiAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEyOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9uZW9mX3Rlc3RfYWxsX3R5cGVzID0gNTM2ODcwMDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mVGVzdEFsbFR5cGVzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0T25lb2ZUZXN0QWxsVHlwZXMoKSB7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEyKSB7CiAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMpIG9uZW9mRmllbGRfOwogICAgICB9CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvbmVvZl90ZXN0X2FsbF90eXBlcyA9IDUzNjg3MDAxMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPbmVvZlRlc3RBbGxUeXBlc09yQnVpbGRlcigpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTIpIHsKICAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcykgb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX1NUUklOR19GSUVMRF9OVU1CRVIgPSA1MzY4NzAwMTM7CiAgICAvKioKICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSA1MzY4NzAwMTM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mU3RyaW5nKCkgewogICAgICByZXR1cm4gb25lb2ZGaWVsZENhc2VfID09IDUzNjg3MDAxMzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+c3RyaW5nIG9uZW9mX3N0cmluZyA9IDUzNjg3MDAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZlN0cmluZy4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T25lb2ZTdHJpbmcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEzKSB7CiAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpICYmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEzKSkgewogICAgICAgICAgb25lb2ZGaWVsZF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gNTM2ODcwMDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvbmVvZlN0cmluZy4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9uZW9mU3RyaW5nQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEzKSB7CiAgICAgICAgcmVmID0gb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTMpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gYjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX0JZVEVTX0ZJRUxEX05VTUJFUiA9IDUzNjg3MDAxNDsKICAgIC8qKgogICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSA1MzY4NzAwMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZkJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZCeXRlcygpIHsKICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTQ7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gNTM2ODcwMDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9uZW9mQnl0ZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T25lb2ZCeXRlcygpIHsKICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTQpIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgb25lb2ZGaWVsZF87CiAgICAgIH0KICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5FeHRlbmRhYmxlTWVzc2FnZTxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzPi5FeHRlbnNpb25Xcml0ZXIKICAgICAgICAgIGV4dGVuc2lvbldyaXRlciA9IG5ld0V4dGVuc2lvbldyaXRlcigpOwogICAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCg1MzY4NzAwMDAsIG91dHB1dCk7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDUzNjg3MDAwMCwgb3B0aW9uYWxJbnQzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDUzNjg3MDAwMSwgZml4ZWQzMl8pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig1MzY4NzAwMDIsIHJlcGVhdGVkSW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEludDMyTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygtNzI3MCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkSW50MzJNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyTm9UYWcocGFja2VkSW50MzJfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSg1MzY4NzAwMDQsIG9wdGlvbmFsRW51bV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNTM2ODcwMDA1LCBvcHRpb25hbFN0cmluZ18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDUzNjg3MDAwNiwgb3B0aW9uYWxCeXRlc18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNTM2ODcwMDA3LCBnZXRPcHRpb25hbE1lc3NhZ2UoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlR3JvdXAoNTM2ODcwMDA4LCBnZXRPcHRpb25hbEdyb3VwKCkpOwogICAgICB9CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLnNlcmlhbGl6ZVN0cmluZ01hcFRvKAogICAgICAgICAgb3V0cHV0LAogICAgICAgICAgaW50ZXJuYWxHZXRTdHJpbmdTdHJpbmdNYXAoKSwKICAgICAgICAgIFN0cmluZ1N0cmluZ01hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICA1MzY4NzAwMTApOwogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDUzNjg3MDAxMSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigKICAgICAgICAgICAgNTM2ODcwMDExLCAoaW50KSgoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfKSk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTIpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDUzNjg3MDAxMiwgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzKSBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTMpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDUzNjg3MDAxMywgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDE0KSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoCiAgICAgICAgICAgIDUzNjg3MDAxNCwgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDUzNjg3MDAwMCwgb3B0aW9uYWxJbnQzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNTM2ODcwMDAxLCBmaXhlZDMyXyk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDMyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKHJlcGVhdGVkSW50MzJfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSA1ICogZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRJbnQzMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhwYWNrZWRJbnQzMl8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEludDMyTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSA1OwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEludDMyTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSg1MzY4NzAwMDQsIG9wdGlvbmFsRW51bV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoNTM2ODcwMDA1LCBvcHRpb25hbFN0cmluZ18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemUoNTM2ODcwMDA2LCBvcHRpb25hbEJ5dGVzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUzNjg3MDAwNywgZ2V0T3B0aW9uYWxNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVHcm91cFNpemUoNTM2ODcwMDA4LCBnZXRPcHRpb25hbEdyb3VwKCkpOwogICAgICB9CiAgICAgIGZvciAoamF2YS51dGlsLk1hcC5FbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBlbnRyeQogICAgICAgICAgIDogaW50ZXJuYWxHZXRTdHJpbmdTdHJpbmdNYXAoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIHN0cmluZ1N0cmluZ01hcF9fID0gU3RyaW5nU3RyaW5nTWFwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5uZXdCdWlsZGVyRm9yVHlwZSgpCiAgICAgICAgICAgIC5zZXRLZXkoZW50cnkuZ2V0S2V5KCkpCiAgICAgICAgICAgIC5zZXRWYWx1ZShlbnRyeS5nZXRWYWx1ZSgpKQogICAgICAgICAgICAuYnVpbGQoKTsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg1MzY4NzAwMTAsIHN0cmluZ1N0cmluZ01hcF9fKTsKICAgICAgfQogICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDUzNjg3MDAxMSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKAogICAgICAgICAgICAgIDUzNjg3MDAxMSwgKGludCkoKGphdmEubGFuZy5JbnRlZ2VyKSBvbmVvZkZpZWxkXykpOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEyKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUzNjg3MDAxMiwgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzKSBvbmVvZkZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTMpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDUzNjg3MDAxMywgb25lb2ZGaWVsZF8pOwogICAgICB9CiAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDE0KSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgKICAgICAgICAgICAgICA1MzY4NzAwMTQsIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIG9uZW9mRmllbGRfKTsKICAgICAgfQogICAgICBzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMpIG9iajsKCiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaXhlZDMyKCkgIT0gb3RoZXIuaGFzRml4ZWQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaXhlZDMyKCkpIHsKICAgICAgICBpZiAoZ2V0Rml4ZWQzMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpeGVkMzIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQzMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEludDMyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEludDMyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxFbnVtKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxFbnVtKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsRW51bSgpKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsRW51bV8gIT0gb3RoZXIub3B0aW9uYWxFbnVtXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFN0cmluZygpICE9IG90aGVyLmhhc09wdGlvbmFsU3RyaW5nKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsU3RyaW5nKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsU3RyaW5nKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbFN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEJ5dGVzKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxCeXRlcygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEJ5dGVzKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsQnl0ZXMoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsQnl0ZXMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTWVzc2FnZSgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbE1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEdyb3VwKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxHcm91cCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEdyb3VwKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsR3JvdXAoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsR3JvdXAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0U3RyaW5nU3RyaW5nTWFwKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRTdHJpbmdTdHJpbmdNYXAoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRPbmVvZkZpZWxkQ2FzZSgpLmVxdWFscyhvdGhlci5nZXRPbmVvZkZpZWxkQ2FzZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBzd2l0Y2ggKG9uZW9mRmllbGRDYXNlXykgewogICAgICAgIGNhc2UgNTM2ODcwMDExOgogICAgICAgICAgaWYgKGdldE9uZW9mVWludDMyKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRPbmVvZlVpbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDUzNjg3MDAxMjoKICAgICAgICAgIGlmICghZ2V0T25lb2ZUZXN0QWxsVHlwZXMoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T25lb2ZUZXN0QWxsVHlwZXMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNTM2ODcwMDEzOgogICAgICAgICAgaWYgKCFnZXRPbmVvZlN0cmluZygpCiAgICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPbmVvZlN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSA1MzY4NzAwMTQ6CiAgICAgICAgICBpZiAoIWdldE9uZW9mQnl0ZXMoKQogICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T25lb2ZCeXRlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzIoKTsKICAgICAgfQogICAgICBpZiAoaGFzRml4ZWQzMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklYRURfMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpeGVkMzIoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkSW50MzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9JTlQzMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkSW50MzJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxFbnVtKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9FTlVNX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBvcHRpb25hbEVudW1fOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFN0cmluZygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsQnl0ZXMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0JZVEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEJ5dGVzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxNZXNzYWdlKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbE1lc3NhZ2UoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEdyb3VwKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTEdST1VQX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEdyb3VwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoIWludGVybmFsR2V0U3RyaW5nU3RyaW5nTWFwKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU1RSSU5HX1NUUklOR19NQVBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0U3RyaW5nU3RyaW5nTWFwKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBzd2l0Y2ggKG9uZW9mRmllbGRDYXNlXykgewogICAgICAgIGNhc2UgNTM2ODcwMDExOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfVUlOVDMyX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mVWludDMyKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDUzNjg3MDAxMjoKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9ORU9GX1RFU1RfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mVGVzdEFsbFR5cGVzKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNTM2ODcwMDEzOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9uZW9mU3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgNTM2ODcwMDE0OgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT05FT0ZfQllURVNfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T25lb2ZCeXRlcygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdEh1Z2VGaWVsZE51bWJlcnN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLCBCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0SHVnZUZpZWxkTnVtYmVycykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RIdWdlRmllbGROdW1iZXJzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgNTM2ODcwMDEwOgogICAgICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdTdHJpbmdNYXAoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDUzNjg3MDAxMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1N0cmluZ01hcCgpOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgICAiSW52YWxpZCBtYXAgZmllbGQgbnVtYmVyOiAiICsgbnVtYmVyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEh1Z2VGaWVsZE51bWJlcnNfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0T3B0aW9uYWxNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbEdyb3VwRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyXyA9IDA7CiAgICAgICAgZml4ZWQzMl8gPSAwOwogICAgICAgIHJlcGVhdGVkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcGFja2VkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgb3B0aW9uYWxFbnVtXyA9IDQ7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gIiI7CiAgICAgICAgb3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb3B0aW9uYWxHcm91cF8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEdyb3VwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxHcm91cEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1N0cmluZ01hcCgpLmNsZWFyKCk7CiAgICAgICAgaWYgKG9uZW9mVGVzdEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb25lb2ZUZXN0QWxsVHlwZXNCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEh1Z2VGaWVsZE51bWJlcnNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgYnVpbGRQYXJ0aWFsT25lb2ZzKHJlc3VsdCk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMl8gPSBvcHRpb25hbEludDMyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5maXhlZDMyXyA9IGZpeGVkMzJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW50MzJfID0gcmVwZWF0ZWRJbnQzMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZEludDMyXyA9IHBhY2tlZEludDMyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEVudW1fID0gb3B0aW9uYWxFbnVtXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFN0cmluZ18gPSBvcHRpb25hbFN0cmluZ187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxCeXRlc18gPSBvcHRpb25hbEJ5dGVzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbE1lc3NhZ2VfID0gb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxNZXNzYWdlXwogICAgICAgICAgICAgIDogb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEdyb3VwXyA9IG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbEdyb3VwXwogICAgICAgICAgICAgIDogb3B0aW9uYWxHcm91cEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyaW5nU3RyaW5nTWFwXyA9IGludGVybmFsR2V0U3RyaW5nU3RyaW5nTWFwKCk7CiAgICAgICAgICByZXN1bHQuc3RyaW5nU3RyaW5nTWFwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxPbmVvZnMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycyByZXN1bHQpIHsKICAgICAgICByZXN1bHQub25lb2ZGaWVsZENhc2VfID0gb25lb2ZGaWVsZENhc2VfOwogICAgICAgIHJlc3VsdC5vbmVvZkZpZWxkXyA9IHRoaXMub25lb2ZGaWVsZF87CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTIgJiYKICAgICAgICAgICAgb25lb2ZUZXN0QWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXN1bHQub25lb2ZGaWVsZF8gPSBvbmVvZlRlc3RBbGxUeXBlc0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLCBUeXBlPiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBhZGRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VD4gQnVpbGRlciBjbGVhckV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycywgVD4gZXh0ZW5zaW9uKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRXh0ZW5zaW9uKGV4dGVuc2lvbik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzIob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpeGVkMzIoKSkgewogICAgICAgICAgc2V0Rml4ZWQzMihvdGhlci5nZXRGaXhlZDMyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkSW50MzJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEludDMyXyA9IG90aGVyLnJlcGVhdGVkSW50MzJfOwogICAgICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW50MzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEludDMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRJbnQzMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEludDMyXyA9IG90aGVyLnBhY2tlZEludDMyXzsKICAgICAgICAgICAgcGFja2VkSW50MzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkSW50MzJfLmFkZEFsbChvdGhlci5wYWNrZWRJbnQzMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEVudW0oKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxFbnVtKG90aGVyLmdldE9wdGlvbmFsRW51bSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsU3RyaW5nKCkpIHsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IG90aGVyLm9wdGlvbmFsU3RyaW5nXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxCeXRlcygpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEJ5dGVzKG90aGVyLmdldE9wdGlvbmFsQnl0ZXMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbE1lc3NhZ2UoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbE1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxHcm91cCgpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsR3JvdXAob3RoZXIuZ2V0T3B0aW9uYWxHcm91cCgpKTsKICAgICAgICB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nU3RyaW5nTWFwKCkubWVyZ2VGcm9tKAogICAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldFN0cmluZ1N0cmluZ01hcCgpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgc3dpdGNoIChvdGhlci5nZXRPbmVvZkZpZWxkQ2FzZSgpKSB7CiAgICAgICAgICBjYXNlIE9ORU9GX1VJTlQzMjogewogICAgICAgICAgICBzZXRPbmVvZlVpbnQzMihvdGhlci5nZXRPbmVvZlVpbnQzMigpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GX1RFU1RfQUxMX1RZUEVTOiB7CiAgICAgICAgICAgIG1lcmdlT25lb2ZUZXN0QWxsVHlwZXMob3RoZXIuZ2V0T25lb2ZUZXN0QWxsVHlwZXMoKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2FzZSBPTkVPRl9TVFJJTkc6IHsKICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gNTM2ODcwMDEzOwogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IG90aGVyLm9uZW9mRmllbGRfOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GX0JZVEVTOiB7CiAgICAgICAgICAgIHNldE9uZW9mQnl0ZXMob3RoZXIuZ2V0T25lb2ZCeXRlcygpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBjYXNlIE9ORU9GRklFTERfTk9UX1NFVDogewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIC03Mjk2OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIC03Mjk2CiAgICAgICAgICAgICAgY2FzZSAtNzI4ODogewogICAgICAgICAgICAgICAgZml4ZWQzMl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAtNzI4OAogICAgICAgICAgICAgIGNhc2UgLTcyODA6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgLTcyODAKICAgICAgICAgICAgICBjYXNlIC03Mjc4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMl8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAtNzI3OAogICAgICAgICAgICAgIGNhc2UgLTcyNzI6IHsKICAgICAgICAgICAgICAgIGludCB2ID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkSW50MzJfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAtNzI3MgogICAgICAgICAgICAgIGNhc2UgLTcyNzA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50MzJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkSW50MzJfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgLTcyNzAKICAgICAgICAgICAgICBjYXNlIC03MjY0OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg1MzY4NzAwMDQsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBvcHRpb25hbEVudW1fID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgLTcyNjQKICAgICAgICAgICAgICBjYXNlIC03MjU0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFN0cmluZ18gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAtNzI1NAogICAgICAgICAgICAgIGNhc2UgLTcyNDY6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsQnl0ZXNfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgLTcyNDYKICAgICAgICAgICAgICBjYXNlIC03MjM4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIC03MjM4CiAgICAgICAgICAgICAgY2FzZSAtNzIyOTogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZEdyb3VwKDUzNjg3MDAwOCwKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEdyb3VwRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAtNzIyOQogICAgICAgICAgICAgIGNhc2UgLTcyMTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIHN0cmluZ1N0cmluZ01hcF9fID0gaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgU3RyaW5nU3RyaW5nTWFwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeS5nZXRQYXJzZXJGb3JUeXBlKCksIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1N0cmluZ01hcCgpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgc3RyaW5nU3RyaW5nTWFwX18uZ2V0S2V5KCksIHN0cmluZ1N0cmluZ01hcF9fLmdldFZhbHVlKCkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIC03MjE0CiAgICAgICAgICAgICAgY2FzZSAtNzIwODogewogICAgICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA1MzY4NzAwMTE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgLTcyMDgKICAgICAgICAgICAgICBjYXNlIC03MTk4OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPbmVvZlRlc3RBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA1MzY4NzAwMTI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgLTcxOTgKICAgICAgICAgICAgICBjYXNlIC03MTkwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDUzNjg3MDAxMzsKICAgICAgICAgICAgICAgIG9uZW9mRmllbGRfID0gYnM7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgLTcxOTAKICAgICAgICAgICAgICBjYXNlIC03MTgyOiB7CiAgICAgICAgICAgICAgICBvbmVvZkZpZWxkXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gNTM2ODcwMDE0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIC03MTgyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgb25lb2ZGaWVsZENhc2VfID0gMDsKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9uZW9mRmllbGRfOwogICAgICBwdWJsaWMgT25lb2ZGaWVsZENhc2UKICAgICAgICAgIGdldE9uZW9mRmllbGRDYXNlKCkgewogICAgICAgIHJldHVybiBPbmVvZkZpZWxkQ2FzZS5mb3JOdW1iZXIoCiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2ZGaWVsZCgpIHsKICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gNTM2ODcwMDAwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyID0gNTM2ODcwMDAwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDMyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSA1MzY4NzAwMDA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDMyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzIgPSA1MzY4NzAwMDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9wdGlvbmFsSW50MzJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZml4ZWQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZml4ZWRfMzIgPSA1MzY4NzAwMDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpeGVkMzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaXhlZDMyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZml4ZWRfMzIgPSA1MzY4NzAwMDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaXhlZDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpeGVkMzIoKSB7CiAgICAgICAgcmV0dXJuIGZpeGVkMzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaXhlZF8zMiA9IDUzNjg3MDAwMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZml4ZWQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpeGVkMzIoaW50IHZhbHVlKSB7CgogICAgICAgIGZpeGVkMzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaXhlZF8zMiA9IDUzNjg3MDAwMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRml4ZWQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgZml4ZWQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkSW50MzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEludDMyXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzIgPSA1MzY4NzAwMDIgW3BhY2tlZCA9IGZhbHNlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRSZXBlYXRlZEludDMyTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEludDMyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDUzNjg3MDAwMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkNvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gNTM2ODcwMDAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzIoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gNTM2ODcwMDAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW50MzIoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDUzNjg3MDAwMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRJbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50MzJfLmFkZEludCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMiA9IDUzNjg3MDAwMiBbcGFja2VkID0gZmFsc2VdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW50MzJfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyID0gNTM2ODcwMDAyIFtwYWNrZWQgPSBmYWxzZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkSW50MzIoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMl8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHBhY2tlZEludDMyXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkSW50MzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRJbnQzMl8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEludDMyXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRJbnQzMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDUzNjg3MDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFBhY2tlZEludDMyTGlzdCgpIHsKICAgICAgICBwYWNrZWRJbnQzMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRJbnQzMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMiA9IDUzNjg3MDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50MzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkSW50MzJfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gNTM2ODcwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQzMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRJbnQzMl8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gNTM2ODcwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEludDMyKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50MzJJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRJbnQzMl8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzIgPSA1MzY4NzAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRJbnQzMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEludDMyKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEludDMyXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gNTM2ODcwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZEludDMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkSW50MzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRJbnQzMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyID0gNTM2ODcwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkSW50MzIoKSB7CiAgICAgICAgcGFja2VkSW50MzJfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEVudW1fID0gNDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bSBvcHRpb25hbF9lbnVtID0gNTM2ODcwMDA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEVudW0gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEVudW0oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZW51bSA9IDUzNjg3MDAwNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsRW51bS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gZ2V0T3B0aW9uYWxFbnVtKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5mb3JOdW1iZXIob3B0aW9uYWxFbnVtXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5GT1JFSUdOX0ZPTyA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtIG9wdGlvbmFsX2VudW0gPSA1MzY4NzAwMDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsRW51bSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsRW51bShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb3B0aW9uYWxFbnVtXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW0gb3B0aW9uYWxfZW51bSA9IDUzNjg3MDAwNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxFbnVtKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvcHRpb25hbEVudW1fID0gNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsU3RyaW5nXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDUzNjg3MDAwNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gNTM2ODcwMDA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nID0gNTM2ODcwMDA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDUzNjg3MDAwNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZyA9IDUzNjg3MDAwNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTdHJpbmcoKSB7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0T3B0aW9uYWxTdHJpbmcoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmcgPSA1MzY4NzAwMDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgb3B0aW9uYWxCeXRlc18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHRpb25hbF9ieXRlcyA9IDUzNjg3MDAwNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxCeXRlcyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQnl0ZXMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHRpb25hbF9ieXRlcyA9IDUzNjg3MDAwNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQnl0ZXMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T3B0aW9uYWxCeXRlcygpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxCeXRlc187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzID0gNTM2ODcwMDA2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEJ5dGVzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxCeXRlcyhjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsQnl0ZXNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHRpb25hbF9ieXRlcyA9IDUzNjg3MDAwNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxCeXRlcygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb3B0aW9uYWxCeXRlc18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbEJ5dGVzKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbE1lc3NhZ2VfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+IG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX21lc3NhZ2UgPSA1MzY4NzAwMDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfbWVzc2FnZSA9IDUzNjg3MDAwNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTWVzc2FnZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIGdldE9wdGlvbmFsTWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTWVzc2FnZV8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX21lc3NhZ2UgPSA1MzY4NzAwMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9tZXNzYWdlID0gNTM2ODcwMDA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfbWVzc2FnZSA9IDUzNjg3MDAwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTWVzc2FnZShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsTWVzc2FnZUJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZSBvcHRpb25hbF9tZXNzYWdlID0gNTM2ODcwMDA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxNZXNzYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvcHRpb25hbE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX21lc3NhZ2UgPSA1MzY4NzAwMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2Ugb3B0aW9uYWxfbWVzc2FnZSA9IDUzNjg3MDAwNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZU9yQnVpbGRlciBnZXRPcHRpb25hbE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE1lc3NhZ2VfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE1lc3NhZ2VfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIG9wdGlvbmFsX21lc3NhZ2UgPSA1MzY4NzAwMDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZSwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2VPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbE1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIG9wdGlvbmFsR3JvdXBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXBPckJ1aWxkZXI+IG9wdGlvbmFsR3JvdXBCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSA1MzY4NzAwMDggeyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbGdyb3VwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsR3JvdXAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gNTM2ODcwMDA4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsZ3JvdXAuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIGdldE9wdGlvbmFsR3JvdXAoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxHcm91cF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsR3JvdXBfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSA1MzY4NzAwMDggeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsR3JvdXAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsR3JvdXBfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gNTM2ODcwMDA4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEdyb3VwKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEdyb3VwXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEdyb3VwQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDUzNjg3MDAwOCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbEdyb3VwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cCB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsR3JvdXBfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxHcm91cF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsR3JvdXBCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsR3JvdXBfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxHcm91cF8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBPcHRpb25hbEdyb3VwID0gNTM2ODcwMDA4IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsR3JvdXAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9wdGlvbmFsR3JvdXBfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxHcm91cEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsR3JvdXBCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEdyb3VwQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDUzNjg3MDAwOCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cC5CdWlsZGVyIGdldE9wdGlvbmFsR3JvdXBCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxHcm91cEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgT3B0aW9uYWxHcm91cCA9IDUzNjg3MDAwOCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cE9yQnVpbGRlciBnZXRPcHRpb25hbEdyb3VwT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEdyb3VwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsR3JvdXBCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEdyb3VwXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEdyb3VwXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIE9wdGlvbmFsR3JvdXAgPSA1MzY4NzAwMDggeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEh1Z2VGaWVsZE51bWJlcnMuT3B0aW9uYWxHcm91cE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbEdyb3VwRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxHcm91cEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLk9wdGlvbmFsR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpb25hbEdyb3VwT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxHcm91cCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxHcm91cF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxHcm91cEJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBzdHJpbmdTdHJpbmdNYXBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nU3RyaW5nTWFwKCkgewogICAgICAgIGlmIChzdHJpbmdTdHJpbmdNYXBfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgU3RyaW5nU3RyaW5nTWFwRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzdHJpbmdTdHJpbmdNYXBfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlU3RyaW5nU3RyaW5nTWFwKCkgewogICAgICAgIGlmIChzdHJpbmdTdHJpbmdNYXBfID09IG51bGwpIHsKICAgICAgICAgIHN0cmluZ1N0cmluZ01hcF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIFN0cmluZ1N0cmluZ01hcERlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIXN0cmluZ1N0cmluZ01hcF8uaXNNdXRhYmxlKCkpIHsKICAgICAgICAgIHN0cmluZ1N0cmluZ01hcF8gPSBzdHJpbmdTdHJpbmdNYXBfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBzdHJpbmdTdHJpbmdNYXBfOwogICAgICB9CiAgICAgIHB1YmxpYyBpbnQgZ2V0U3RyaW5nU3RyaW5nTWFwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0U3RyaW5nU3RyaW5nTWFwKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IHN0cmluZ19zdHJpbmdfbWFwID0gNTM2ODcwMDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNTdHJpbmdTdHJpbmdNYXAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIHJldHVybiBpbnRlcm5hbEdldFN0cmluZ1N0cmluZ01hcCgpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSB7QGxpbmsgI2dldFN0cmluZ1N0cmluZ01hcE1hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0U3RyaW5nU3RyaW5nTWFwKCkgewogICAgICAgIHJldHVybiBnZXRTdHJpbmdTdHJpbmdNYXBNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBzdHJpbmdfc3RyaW5nX21hcCA9IDUzNjg3MDAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldFN0cmluZ1N0cmluZ01hcE1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRTdHJpbmdTdHJpbmdNYXAoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBzdHJpbmdfc3RyaW5nX21hcCA9IDUzNjg3MDAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGdldFN0cmluZ1N0cmluZ01hcE9yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0U3RyaW5nU3RyaW5nTWFwKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IHN0cmluZ19zdHJpbmdfbWFwID0gNTM2ODcwMDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyaW5nU3RyaW5nTWFwT3JUaHJvdygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgICBpbnRlcm5hbEdldFN0cmluZ1N0cmluZ01hcCgpLmdldE1hcCgpOwogICAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICAgIH0KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJTdHJpbmdTdHJpbmdNYXAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1N0cmluZ01hcCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBzdHJpbmdfc3RyaW5nX21hcCA9IDUzNjg3MDAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVTdHJpbmdTdHJpbmdNYXAoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1N0cmluZ01hcCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVTdHJpbmdTdHJpbmdNYXAoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVTdHJpbmdTdHJpbmdNYXAoKS5nZXRNdXRhYmxlTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgc3RyaW5nX3N0cmluZ19tYXAgPSA1MzY4NzAwMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0U3RyaW5nU3RyaW5nTWFwKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1N0cmluZ01hcCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0KGtleSwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBzdHJpbmdfc3RyaW5nX21hcCA9IDUzNjg3MDAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRBbGxTdHJpbmdTdHJpbmdNYXAoCiAgICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGludGVybmFsR2V0TXV0YWJsZVN0cmluZ1N0cmluZ01hcCgpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDUzNjg3MDAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb25lb2ZVaW50MzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT25lb2ZVaW50MzIoKSB7CiAgICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTE7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSA1MzY4NzAwMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvbmVvZlVpbnQzMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0T25lb2ZVaW50MzIoKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTEpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkludGVnZXIpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+dWludDMyIG9uZW9mX3VpbnQzMiA9IDUzNjg3MDAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb25lb2ZVaW50MzIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZlVpbnQzMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gNTM2ODcwMDExOwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnVpbnQzMiBvbmVvZl91aW50MzIgPSA1MzY4NzAwMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mVWludDMyKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDExKSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IG9uZW9mVGVzdEFsbFR5cGVzQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9uZW9mX3Rlc3RfYWxsX3R5cGVzID0gNTM2ODcwMDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlRlc3RBbGxUeXBlcyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mVGVzdEFsbFR5cGVzKCkgewogICAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9uZW9mX3Rlc3RfYWxsX3R5cGVzID0gNTM2ODcwMDEyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb25lb2ZUZXN0QWxsVHlwZXMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRPbmVvZlRlc3RBbGxUeXBlcygpIHsKICAgICAgICBpZiAob25lb2ZUZXN0QWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDUzNjg3MDAxMikgewogICAgICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzKSBvbmVvZkZpZWxkXzsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTIpIHsKICAgICAgICAgICAgcmV0dXJuIG9uZW9mVGVzdEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvbmVvZl90ZXN0X2FsbF90eXBlcyA9IDUzNjg3MDAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZlRlc3RBbGxUeXBlcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChvbmVvZlRlc3RBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvbmVvZlRlc3RBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA1MzY4NzAwMTI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb25lb2ZfdGVzdF9hbGxfdHlwZXMgPSA1MzY4NzAwMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T25lb2ZUZXN0QWxsVHlwZXMoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvbmVvZlRlc3RBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9uZW9mRmllbGRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb25lb2ZUZXN0QWxsVHlwZXNCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gNTM2ODcwMDEyOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9uZW9mX3Rlc3RfYWxsX3R5cGVzID0gNTM2ODcwMDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT25lb2ZUZXN0QWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAob25lb2ZUZXN0QWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDUzNjg3MDAxMiAmJgogICAgICAgICAgICAgIG9uZW9mRmllbGRfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMubmV3QnVpbGRlcigocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMpIG9uZW9mRmllbGRfKQogICAgICAgICAgICAgICAgLm1lcmdlRnJvbSh2YWx1ZSkuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvbmVvZkZpZWxkXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEyKSB7CiAgICAgICAgICAgIG9uZW9mVGVzdEFsbFR5cGVzQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9uZW9mVGVzdEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDUzNjg3MDAxMjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvbmVvZl90ZXN0X2FsbF90eXBlcyA9IDUzNjg3MDAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mVGVzdEFsbFR5cGVzKCkgewogICAgICAgIGlmIChvbmVvZlRlc3RBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEyKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEyKSB7CiAgICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICAgIG9uZW9mRmllbGRfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIG9uZW9mVGVzdEFsbFR5cGVzQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb25lb2ZfdGVzdF9hbGxfdHlwZXMgPSA1MzY4NzAwMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0T25lb2ZUZXN0QWxsVHlwZXNCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRPbmVvZlRlc3RBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvbmVvZl90ZXN0X2FsbF90eXBlcyA9IDUzNjg3MDAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPbmVvZlRlc3RBbGxUeXBlc09yQnVpbGRlcigpIHsKICAgICAgICBpZiAoKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTIpICYmIChvbmVvZlRlc3RBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpKSB7CiAgICAgICAgICByZXR1cm4gb25lb2ZUZXN0QWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEyKSB7CiAgICAgICAgICAgIHJldHVybiAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMpIG9uZW9mRmllbGRfOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvbmVvZl90ZXN0X2FsbF90eXBlcyA9IDUzNjg3MDAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T25lb2ZUZXN0QWxsVHlwZXNGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9uZW9mVGVzdEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCEob25lb2ZGaWVsZENhc2VfID09IDUzNjg3MDAxMikpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uZW9mVGVzdEFsbFR5cGVzQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMpIG9uZW9mRmllbGRfLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA1MzY4NzAwMTI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG9uZW9mVGVzdEFsbFR5cGVzQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gNTM2ODcwMDEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZlN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mU3RyaW5nKCkgewogICAgICAgIHJldHVybiBvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gNTM2ODcwMDEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb25lb2ZTdHJpbmcuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9uZW9mU3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTMpIHsKICAgICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEzKSB7CiAgICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBzOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gNTM2ODcwMDEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9uZW9mU3RyaW5nLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRPbmVvZlN0cmluZ0J5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gIiI7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTMpIHsKICAgICAgICAgIHJlZiA9IG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTMpIHsKICAgICAgICAgICAgb25lb2ZGaWVsZF8gPSBiOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gNTM2ODcwMDEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvbmVvZlN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb25lb2ZGaWVsZENhc2VfID0gNTM2ODcwMDEzOwogICAgICAgIG9uZW9mRmllbGRfID0gdmFsdWU7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnN0cmluZyBvbmVvZl9zdHJpbmcgPSA1MzY4NzAwMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mU3RyaW5nKCkgewogICAgICAgIGlmIChvbmVvZkZpZWxkQ2FzZV8gPT0gNTM2ODcwMDEzKSB7CiAgICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSAwOwogICAgICAgICAgb25lb2ZGaWVsZF8gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5zdHJpbmcgb25lb2Zfc3RyaW5nID0gNTM2ODcwMDEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb25lb2ZTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPbmVvZlN0cmluZ0J5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA1MzY4NzAwMTM7CiAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gNTM2ODcwMDE0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvbmVvZkJ5dGVzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09uZW9mQnl0ZXMoKSB7CiAgICAgICAgcmV0dXJuIG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmJ5dGVzIG9uZW9mX2J5dGVzID0gNTM2ODcwMDE0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb25lb2ZCeXRlcy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T25lb2ZCeXRlcygpIHsKICAgICAgICBpZiAob25lb2ZGaWVsZENhc2VfID09IDUzNjg3MDAxNCkgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIG9uZW9mRmllbGRfOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ieXRlcyBvbmVvZl9ieXRlcyA9IDUzNjg3MDAxNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb25lb2ZCeXRlcyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9uZW9mQnl0ZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvbmVvZkZpZWxkQ2FzZV8gPSA1MzY4NzAwMTQ7CiAgICAgICAgb25lb2ZGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+Ynl0ZXMgb25lb2ZfYnl0ZXMgPSA1MzY4NzAwMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mQnl0ZXMoKSB7CiAgICAgICAgaWYgKG9uZW9mRmllbGRDYXNlXyA9PSA1MzY4NzAwMTQpIHsKICAgICAgICAgIG9uZW9mRmllbGRDYXNlXyA9IDA7CiAgICAgICAgICBvbmVvZkZpZWxkXyA9IG51bGw7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEh1Z2VGaWVsZE51bWJlcnMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RIdWdlRmllbGROdW1iZXJzKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0SHVnZUZpZWxkTnVtYmVycyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEh1Z2VGaWVsZE51bWJlcnM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEh1Z2VGaWVsZE51bWJlcnM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0SHVnZUZpZWxkTnVtYmVycyBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RIdWdlRmllbGROdW1iZXJzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RIdWdlRmllbGROdW1iZXJzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxUZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGU+IHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkMS4KICAgICAqLwogICAgaW50IGdldEZpZWxkMSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQyID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGQyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGQyLgogICAgICovCiAgICBpbnQgZ2V0RmllbGQyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZDMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQzID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDMuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZDMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkNCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkNC4KICAgICAqLwogICAgaW50IGdldEZpZWxkNCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQ2ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkNiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGQ2KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkNiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGQ2LgogICAgICovCiAgICBpbnQgZ2V0RmllbGQ2KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDcgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQ3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZDcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQ3ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDcuCiAgICAgKi8KICAgIGludCBnZXRGaWVsZDcoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkOCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDggZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZpZWxkOCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDggPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkOC4KICAgICAqLwogICAgaW50IGdldEZpZWxkOCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQ5ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkOSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRmllbGQ5KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkOSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGQ5LgogICAgICovCiAgICBpbnQgZ2V0RmllbGQ5KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDEwID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGaWVsZDEwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDEwLgogICAgICovCiAgICBpbnQgZ2V0RmllbGQxMCgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgICBUZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGU+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUpCiAgICAgIFRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSwgPz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25JbnNpZGVUYWJsZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25JbnNpZGVUYWJsZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTEQxX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBmaWVsZDFfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZDEoKSB7CiAgICAgIHJldHVybiBmaWVsZDFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEMl9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBpbnQgZmllbGQyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZDIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQyID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGQyKCkgewogICAgICByZXR1cm4gZmllbGQyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRDNfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgaW50IGZpZWxkM18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGQzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGQzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkMygpIHsKICAgICAgcmV0dXJuIGZpZWxkM187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTEQ0X0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBwcml2YXRlIGludCBmaWVsZDRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQ0ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkNCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkNCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZDQoKSB7CiAgICAgIHJldHVybiBmaWVsZDRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxENl9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBpbnQgZmllbGQ2XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkNiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDYgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZDYoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQ2ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGQ2KCkgewogICAgICByZXR1cm4gZmllbGQ2XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRDdfRklFTERfTlVNQkVSID0gNzsKICAgIHByaXZhdGUgaW50IGZpZWxkN18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDcgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQ3IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGQ3KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkNyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGQ3LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldEZpZWxkNygpIHsKICAgICAgcmV0dXJuIGZpZWxkN187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRklFTEQ4X0ZJRUxEX05VTUJFUiA9IDg7CiAgICBwcml2YXRlIGludCBmaWVsZDhfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQ4ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkOCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkOCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDggPSA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZpZWxkOC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZDgoKSB7CiAgICAgIHJldHVybiBmaWVsZDhfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEOV9GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBpbnQgZmllbGQ5XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkOSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZDkoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQ5ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0RmllbGQ5KCkgewogICAgICByZXR1cm4gZmllbGQ5XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUVMRDEwX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgcHJpdmF0ZSBpbnQgZmllbGQxMF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDEwID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDEwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGQxMCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDEwID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZmllbGQxMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGaWVsZDEwKCkgewogICAgICByZXR1cm4gZmllbGQxMF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuRXh0ZW5kYWJsZU1lc3NhZ2U8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGU+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGZpZWxkMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIGZpZWxkMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDMsIGZpZWxkM18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDQsIGZpZWxkNF8pOwogICAgICB9CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDYsIG91dHB1dCk7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDYsIGZpZWxkNl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDcsIGZpZWxkN18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDgsIGZpZWxkOF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDksIGZpZWxkOV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEwLCBmaWVsZDEwXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMSwgZmllbGQxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgyLCBmaWVsZDJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDMsIGZpZWxkM18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNCwgZmllbGQ0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg2LCBmaWVsZDZfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDcsIGZpZWxkN18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoOCwgZmllbGQ4Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg5LCBmaWVsZDlfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEwLCBmaWVsZDEwXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBleHRlbnNpb25zU2VyaWFsaXplZFNpemUoKTsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlKSBvYmo7CgogICAgICBpZiAoaGFzRmllbGQxKCkgIT0gb3RoZXIuaGFzRmllbGQxKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkMSgpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkMSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkMigpICE9IG90aGVyLmhhc0ZpZWxkMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZDIoKSkgewogICAgICAgIGlmIChnZXRGaWVsZDIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZDIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZDMoKSAhPSBvdGhlci5oYXNGaWVsZDMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGQzKCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGQzKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGQzKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGQ0KCkgIT0gb3RoZXIuaGFzRmllbGQ0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkNCgpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkNCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkNCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkNigpICE9IG90aGVyLmhhc0ZpZWxkNigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZDYoKSkgewogICAgICAgIGlmIChnZXRGaWVsZDYoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZDYoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZDcoKSAhPSBvdGhlci5oYXNGaWVsZDcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRmllbGQ3KCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGQ3KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0RmllbGQ3KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGQ4KCkgIT0gb3RoZXIuaGFzRmllbGQ4KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0ZpZWxkOCgpKSB7CiAgICAgICAgaWYgKGdldEZpZWxkOCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkOCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkOSgpICE9IG90aGVyLmhhc0ZpZWxkOSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZDkoKSkgewogICAgICAgIGlmIChnZXRGaWVsZDkoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGaWVsZDkoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZDEwKCkgIT0gb3RoZXIuaGFzRmllbGQxMCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGaWVsZDEwKCkpIHsKICAgICAgICBpZiAoZ2V0RmllbGQxMCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZpZWxkMTAoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RXh0ZW5zaW9uRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldEV4dGVuc2lvbkZpZWxkcygpKSkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0ZpZWxkMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTEQxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZDEoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGQyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRDJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkMigpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZDMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGQzKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkNCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTEQ0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZDQoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGQ2KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRDZfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkNigpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZDcoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZJRUxEN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0RmllbGQ3KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZpZWxkOCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRklFTEQ4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZDgoKTsKICAgICAgfQogICAgICBpZiAoaGFzRmllbGQ5KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRDlfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZpZWxkOSgpOwogICAgICB9CiAgICAgIGlmIChoYXNGaWVsZDEwKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGSUVMRDEwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGaWVsZDEwKCk7CiAgICAgIH0KICAgICAgaGFzaCA9IGhhc2hGaWVsZHMoaGFzaCwgZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGV9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSwgQnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25JbnNpZGVUYWJsZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGZpZWxkMV8gPSAwOwogICAgICAgIGZpZWxkMl8gPSAwOwogICAgICAgIGZpZWxkM18gPSAwOwogICAgICAgIGZpZWxkNF8gPSAwOwogICAgICAgIGZpZWxkNl8gPSAwOwogICAgICAgIGZpZWxkN18gPSAwOwogICAgICAgIGZpZWxkOF8gPSAwOwogICAgICAgIGZpZWxkOV8gPSAwOwogICAgICAgIGZpZWxkMTBfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGQxXyA9IGZpZWxkMV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGQyXyA9IGZpZWxkMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGQzXyA9IGZpZWxkM187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGQ0XyA9IGZpZWxkNF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGQ2XyA9IGZpZWxkNl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGQ3XyA9IGZpZWxkN187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGQ4XyA9IGZpZWxkOF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGQ5XyA9IGZpZWxkOV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZmllbGQxMF8gPSBmaWVsZDEwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUsIFR5cGU+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBhZGRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFQ+IEJ1aWxkZXIgY2xlYXJFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlLCBUPiBleHRlbnNpb24pIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZDEoKSkgewogICAgICAgICAgc2V0RmllbGQxKG90aGVyLmdldEZpZWxkMSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkMigpKSB7CiAgICAgICAgICBzZXRGaWVsZDIob3RoZXIuZ2V0RmllbGQyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGQzKCkpIHsKICAgICAgICAgIHNldEZpZWxkMyhvdGhlci5nZXRGaWVsZDMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZDQoKSkgewogICAgICAgICAgc2V0RmllbGQ0KG90aGVyLmdldEZpZWxkNCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkNigpKSB7CiAgICAgICAgICBzZXRGaWVsZDYob3RoZXIuZ2V0RmllbGQ2KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGQ3KCkpIHsKICAgICAgICAgIHNldEZpZWxkNyhvdGhlci5nZXRGaWVsZDcoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGaWVsZDgoKSkgewogICAgICAgICAgc2V0RmllbGQ4KG90aGVyLmdldEZpZWxkOCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0ZpZWxkOSgpKSB7CiAgICAgICAgICBzZXRGaWVsZDkob3RoZXIuZ2V0RmllbGQ5KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRmllbGQxMCgpKSB7CiAgICAgICAgICBzZXRGaWVsZDEwKG90aGVyLmdldEZpZWxkMTAoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VFeHRlbnNpb25GaWVsZHMob3RoZXIpOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBmaWVsZDFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIGZpZWxkMl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMjQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkM18gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgMzI6IHsKICAgICAgICAgICAgICAgIGZpZWxkNF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMgogICAgICAgICAgICAgIGNhc2UgNDg6IHsKICAgICAgICAgICAgICAgIGZpZWxkNl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OAogICAgICAgICAgICAgIGNhc2UgNTY6IHsKICAgICAgICAgICAgICAgIGZpZWxkN18gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NgogICAgICAgICAgICAgIGNhc2UgNjQ6IHsKICAgICAgICAgICAgICAgIGZpZWxkOF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NAogICAgICAgICAgICAgIGNhc2UgNzI6IHsKICAgICAgICAgICAgICAgIGZpZWxkOV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MgogICAgICAgICAgICAgIGNhc2UgODA6IHsKICAgICAgICAgICAgICAgIGZpZWxkMTBfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGQxXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZDEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGQxLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkMSgpIHsKICAgICAgICByZXR1cm4gZmllbGQxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQxID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGQxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQxKGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZDEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGZpZWxkMV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmaWVsZDJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGQyKCkgewogICAgICAgIHJldHVybiBmaWVsZDJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDIgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZDIgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZDIoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgZmllbGQyXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkM18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQzID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGQzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQzID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkMy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZDMoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkM187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkMyhpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGQzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQzID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBmaWVsZDNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGQ0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZDQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGQ0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkNCgpIHsKICAgICAgICByZXR1cm4gZmllbGQ0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQ0ID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGQ0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQ0KGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZDRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZDQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGZpZWxkNF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmaWVsZDZfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkNiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkNigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDYuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGQ2KCkgewogICAgICAgIHJldHVybiBmaWVsZDZfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDYgPSA2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZDYgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZDYoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkNl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkNigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgZmllbGQ2XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkN18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQ3ID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQ3IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRmllbGQ3KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQ3ID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZpZWxkNy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGaWVsZDcoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkN187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkNyA9IDc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkNyhpbnQgdmFsdWUpIHsKCiAgICAgICAgZmllbGQ3XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQ3ID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQ3KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBmaWVsZDdfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgZmllbGQ4XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDggPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmaWVsZDggZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGaWVsZDgoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDggPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgZmllbGQ4LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkOCgpIHsKICAgICAgICByZXR1cm4gZmllbGQ4XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQ4ID0gODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZmllbGQ4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQ4KGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZDhfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDggPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZDgoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIGZpZWxkOF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmaWVsZDlfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZpZWxkOSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkOSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDkuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0RmllbGQ5KCkgewogICAgICAgIHJldHVybiBmaWVsZDlfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDkgPSA5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmaWVsZDkgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZDkoaW50IHZhbHVlKSB7CgogICAgICAgIGZpZWxkOV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkOSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgZmllbGQ5XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGZpZWxkMTBfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZpZWxkMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZmllbGQxMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZpZWxkMTAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDEwID0gMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmaWVsZDEwLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZpZWxkMTAoKSB7CiAgICAgICAgcmV0dXJuIGZpZWxkMTBfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmaWVsZDEwID0gMTA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZpZWxkMTAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZDEwKGludCB2YWx1ZSkgewoKICAgICAgICBmaWVsZDEwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZmllbGQxMCA9IDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZDEwKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBmaWVsZDEwXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFeHRlbnNpb25JbnNpZGVUYWJsZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlck9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIExheWVyMU9wdGlvbmFsR3JvdXAgPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGxheWVyMW9wdGlvbmFsZ3JvdXAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0xheWVyMU9wdGlvbmFsR3JvdXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgTGF5ZXIxT3B0aW9uYWxHcm91cCA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGxheWVyMW9wdGlvbmFsZ3JvdXAuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cCBnZXRMYXllcjFPcHRpb25hbEdyb3VwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIExheWVyMU9wdGlvbmFsR3JvdXAgPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cE9yQnVpbGRlciBnZXRMYXllcjFPcHRpb25hbEdyb3VwT3JCdWlsZGVyKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogTk9URTogSW50ZW50aW9uYWxseSBuZXN0ZWQgdG8gbWlycm9yIGdvL2dsZXAuCiAgICogPC9wcmU+CiAgICoKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyKQogICAgICBUZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlck9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcigpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHB1YmxpYyBpbnRlcmZhY2UgTGF5ZXIxT3B0aW9uYWxHcm91cE9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXApCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJSZXBlYXRlZEdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXA+IAogICAgICAgICAgZ2V0TGF5ZXIyUmVwZWF0ZWRHcm91cExpc3QoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMlJlcGVhdGVkR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCBnZXRMYXllcjJSZXBlYXRlZEdyb3VwKGludCBpbmRleCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJSZXBlYXRlZEdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgaW50IGdldExheWVyMlJlcGVhdGVkR3JvdXBDb3VudCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyUmVwZWF0ZWRHcm91cCA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRMYXllcjJSZXBlYXRlZEdyb3VwT3JCdWlsZGVyTGlzdCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyUmVwZWF0ZWRHcm91cCA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwT3JCdWlsZGVyIGdldExheWVyMlJlcGVhdGVkR3JvdXBPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cD4gCiAgICAgICAgICBnZXRMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwTGlzdCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwIGdldExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAoaW50IGluZGV4KTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBpbnQgZ2V0TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cENvdW50KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwT3JCdWlsZGVyPiAKICAgICAgICAgIGdldExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBPckJ1aWxkZXJMaXN0KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBPckJ1aWxkZXIgZ2V0TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cE9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXB9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTGF5ZXIxT3B0aW9uYWxHcm91cCBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cCkKICAgICAgICBMYXllcjFPcHRpb25hbEdyb3VwT3JCdWlsZGVyIHsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgICAvLyBVc2UgTGF5ZXIxT3B0aW9uYWxHcm91cC5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgICBwcml2YXRlIExheWVyMU9wdGlvbmFsR3JvdXAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBMYXllcjFPcHRpb25hbEdyb3VwKCkgewogICAgICAgIGxheWVyMlJlcGVhdGVkR3JvdXBfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IExheWVyMU9wdGlvbmFsR3JvdXAoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyX0xheWVyMU9wdGlvbmFsR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHVibGljIGludGVyZmFjZSBMYXllcjJSZXBlYXRlZEdyb3VwT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXApCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy4KICAgICAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxMYXllcjJSZXBlYXRlZEdyb3VwPiB7CgogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhbm90aGVyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhbm90aGVyRmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIGJvb2xlYW4gaGFzQW5vdGhlckZpZWxkKCk7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGFub3RoZXJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBhbm90aGVyRmllbGQuCiAgICAgICAgICovCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBnZXRBbm90aGVyRmllbGQoKTsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYW5vdGhlcl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBhbm90aGVyRmllbGQuCiAgICAgICAgICovCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICAgIGdldEFub3RoZXJGaWVsZEJ5dGVzKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cH0KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTGF5ZXIyUmVwZWF0ZWRHcm91cCBleHRlbmRzCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgICAgICAgTGF5ZXIyUmVwZWF0ZWRHcm91cD4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXApCiAgICAgICAgICBMYXllcjJSZXBlYXRlZEdyb3VwT3JCdWlsZGVyIHsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgICAgLy8gVXNlIExheWVyMlJlcGVhdGVkR3JvdXAubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgICBwcml2YXRlIExheWVyMlJlcGVhdGVkR3JvdXAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAsID8+IGJ1aWxkZXIpIHsKICAgICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIExheWVyMlJlcGVhdGVkR3JvdXAoKSB7CiAgICAgICAgICBhbm90aGVyRmllbGRfID0gIiI7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICAgIHJldHVybiBuZXcgTGF5ZXIyUmVwZWF0ZWRHcm91cCgpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcl9MYXllcjFPcHRpb25hbEdyb3VwX0xheWVyMlJlcGVhdGVkR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyX0xheWVyMU9wdGlvbmFsR3JvdXBfTGF5ZXIyUmVwZWF0ZWRHcm91cF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBTk9USEVSX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDY7CiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICAgICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IGFub3RoZXJGaWVsZF8gPSAiIjsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYW5vdGhlcl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYW5vdGhlckZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzQW5vdGhlckZpZWxkKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYW5vdGhlcl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIGFub3RoZXJGaWVsZC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0QW5vdGhlckZpZWxkKCkgewogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBhbm90aGVyRmllbGRfOwogICAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgICAgYW5vdGhlckZpZWxkXyA9IHM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhbm90aGVyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIGFub3RoZXJGaWVsZC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgICBnZXRBbm90aGVyRmllbGRCeXRlcygpIHsKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYW5vdGhlckZpZWxkXzsKICAgICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgICBhbm90aGVyRmllbGRfID0gYjsKICAgICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5FeHRlbmRhYmxlTWVzc2FnZTxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cD4uRXh0ZW5zaW9uV3JpdGVyCiAgICAgICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgICAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCg0LCBvdXRwdXQpOwogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgNiwgYW5vdGhlckZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgICAgICBzaXplID0gMDsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDYsIGFub3RoZXJGaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgc2l6ZSArPSBleHRlbnNpb25zU2VyaWFsaXplZFNpemUoKTsKICAgICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwKSkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgICB9CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCkgb2JqOwoKICAgICAgICAgIGlmIChoYXNBbm90aGVyRmllbGQoKSAhPSBvdGhlci5oYXNBbm90aGVyRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgaWYgKGhhc0Fub3RoZXJGaWVsZCgpKSB7CiAgICAgICAgICAgIGlmICghZ2V0QW5vdGhlckZpZWxkKCkKICAgICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0QW5vdGhlckZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgICAgIH0KICAgICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgICAgIGlmIChoYXNBbm90aGVyRmllbGQoKSkgewogICAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBBTk9USEVSX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0QW5vdGhlckZpZWxkKCkuaGFzaENvZGUoKTsKICAgICAgICAgIH0KICAgICAgICAgIGhhc2ggPSBoYXNoRmllbGRzKGhhc2gsIGdldEV4dGVuc2lvbkZpZWxkcygpKTsKICAgICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIHByb3RvdHlwZSkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cH0KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCwgQnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCkKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXBPckJ1aWxkZXIgewogICAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9MYXllcjJSZXBlYXRlZEdyb3VwX2Rlc2NyaXB0b3I7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9MYXllcjJSZXBlYXRlZEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cC5uZXdCdWlsZGVyKCkKICAgICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgICB9CgogICAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgICBhbm90aGVyRmllbGRfID0gIiI7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyX0xheWVyMU9wdGlvbmFsR3JvdXBfTGF5ZXIyUmVwZWF0ZWRHcm91cF9kZXNjcmlwdG9yOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIGJ1aWxkKCkgewogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCh0aGlzKTsKICAgICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgfQoKICAgICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIHJlc3VsdCkgewogICAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICAgIHJlc3VsdC5hbm90aGVyRmllbGRfID0gYW5vdGhlckZpZWxkXzsKICAgICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwLCBUeXBlPiBleHRlbnNpb24sCiAgICAgICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgYWRkRXh0ZW5zaW9uKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyA8VD4gQnVpbGRlciBjbGVhckV4dGVuc2lvbigKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCwgVD4gZXh0ZW5zaW9uKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhckV4dGVuc2lvbihleHRlbnNpb24pOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCkgewogICAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwKW90aGVyKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIG90aGVyKSB7CiAgICAgICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIGlmIChvdGhlci5oYXNBbm90aGVyRmllbGQoKSkgewogICAgICAgICAgICAgIGFub3RoZXJGaWVsZF8gPSBvdGhlci5hbm90aGVyRmllbGRfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLm1lcmdlRXh0ZW5zaW9uRmllbGRzKG90aGVyKTsKICAgICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICBjYXNlIDUwOiB7CiAgICAgICAgICAgICAgICAgICAgYW5vdGhlckZpZWxkXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIH0gLy8gZmluYWxseQogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IGFub3RoZXJGaWVsZF8gPSAiIjsKICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGFub3RoZXJfZmllbGQgPSA2OzwvY29kZT4KICAgICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYW5vdGhlckZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzQW5vdGhlckZpZWxkKCkgewogICAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhbm90aGVyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAgICAgKiBAcmV0dXJuIFRoZSBhbm90aGVyRmllbGQuCiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEFub3RoZXJGaWVsZCgpIHsKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBhbm90aGVyRmllbGRfOwogICAgICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICAgICAgYW5vdGhlckZpZWxkXyA9IHM7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhbm90aGVyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYW5vdGhlckZpZWxkLgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICAgICAgZ2V0QW5vdGhlckZpZWxkQnl0ZXMoKSB7CiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYW5vdGhlckZpZWxkXzsKICAgICAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgICAgICBhbm90aGVyRmllbGRfID0gYjsKICAgICAgICAgICAgICByZXR1cm4gYjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhbm90aGVyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGFub3RoZXJGaWVsZCB0byBzZXQuCiAgICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEFub3RoZXJGaWVsZCgKICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgICAgIGFub3RoZXJGaWVsZF8gPSB2YWx1ZTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBhbm90aGVyX2ZpZWxkID0gNjs8L2NvZGU+CiAgICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyQW5vdGhlckZpZWxkKCkgewogICAgICAgICAgICBhbm90aGVyRmllbGRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0QW5vdGhlckZpZWxkKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgICAgLyoqCiAgICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYW5vdGhlcl9maWVsZCA9IDY7PC9jb2RlPgogICAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3IgYW5vdGhlckZpZWxkIHRvIHNldC4KICAgICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0QW5vdGhlckZpZWxkQnl0ZXMoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgICAgIGFub3RoZXJGaWVsZF8gPSB2YWx1ZTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICAgIH0KCgogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwKQogICAgICAgIH0KCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCkKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCBERUZBVUxUX0lOU1RBTkNFOwogICAgICAgIHN0YXRpYyB7CiAgICAgICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TGF5ZXIyUmVwZWF0ZWRHcm91cD4KICAgICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TGF5ZXIyUmVwZWF0ZWRHcm91cD4oKSB7CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgTGF5ZXIyUmVwZWF0ZWRHcm91cCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPExheWVyMlJlcGVhdGVkR3JvdXA+IHBhcnNlcigpIHsKICAgICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPExheWVyMlJlcGVhdGVkR3JvdXA+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgICAgfQoKICAgICAgfQoKICAgICAgcHVibGljIGludGVyZmFjZSBMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXApCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYnV0X3doeV90aG8gPSA1OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGJ1dFdoeVRobyBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgYm9vbGVhbiBoYXNCdXRXaHlUaG8oKTsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYnV0X3doeV90aG8gPSA1OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBidXRXaHlUaG8uCiAgICAgICAgICovCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBnZXRCdXRXaHlUaG8oKTsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYnV0X3doeV90aG8gPSA1OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYnV0V2h5VGhvLgogICAgICAgICAqLwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgICBnZXRCdXRXaHlUaG9CeXRlcygpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXB9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXApCiAgICAgICAgICBMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwT3JCdWlsZGVyIHsKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgICAgLy8gVXNlIExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgICBwcml2YXRlIExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgICBzdXBlcihidWlsZGVyKTsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwKCkgewogICAgICAgICAgYnV0V2h5VGhvXyA9ICIiOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgICByZXR1cm4gbmV3IExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwX2Rlc2NyaXB0b3I7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcl9MYXllcjFPcHRpb25hbEdyb3VwX0xheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cC5CdWlsZGVyLmNsYXNzKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQlVUX1dIWV9USE9fRklFTERfTlVNQkVSID0gNTsKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgICAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgYnV0V2h5VGhvXyA9ICIiOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBidXRfd2h5X3RobyA9IDU7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYnV0V2h5VGhvIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzQnV0V2h5VGhvKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYnV0X3doeV90aG8gPSA1OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBidXRXaHlUaG8uCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEJ1dFdoeVRobygpIHsKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYnV0V2h5VGhvXzsKICAgICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICAgIGJ1dFdoeVRob18gPSBzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYnV0X3doeV90aG8gPSA1OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgYnV0V2h5VGhvLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICAgIGdldEJ1dFdoeVRob0J5dGVzKCkgewogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBidXRXaHlUaG9fOwogICAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICAgIGJ1dFdoeVRob18gPSBiOwogICAgICAgICAgICByZXR1cm4gYjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDUsIGJ1dFdoeVRob18pOwogICAgICAgICAgfQogICAgICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICAgICAgc2l6ZSA9IDA7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSg1LCBidXRXaHlUaG9fKTsKICAgICAgICAgIH0KICAgICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwKSkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgICB9CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCkgb2JqOwoKICAgICAgICAgIGlmIChoYXNCdXRXaHlUaG8oKSAhPSBvdGhlci5oYXNCdXRXaHlUaG8oKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgaWYgKGhhc0J1dFdoeVRobygpKSB7CiAgICAgICAgICAgIGlmICghZ2V0QnV0V2h5VGhvKCkKICAgICAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0QnV0V2h5VGhvKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgICB9CiAgICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgICBpZiAoaGFzQnV0V2h5VGhvKCkpIHsKICAgICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgQlVUX1dIWV9USE9fRklFTERfTlVNQkVSOwogICAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRCdXRXaHlUaG8oKS5oYXNoQ29kZSgpOwogICAgICAgICAgfQogICAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgICAgIHJldHVybiBoYXNoOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KICAgICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgICAgfQogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgICAgICB9CiAgICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgcHJvdG90eXBlKSB7CiAgICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgICByZXR1cm4gYnVpbGRlcjsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwfQogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCkKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBPckJ1aWxkZXIgewogICAgICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwX2Rlc2NyaXB0b3I7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwLkJ1aWxkZXIuY2xhc3MpOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cC5uZXdCdWlsZGVyKCkKICAgICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgICB9CgogICAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgICBidXRXaHlUaG9fID0gIiI7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyX0xheWVyMU9wdGlvbmFsR3JvdXBfTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF9kZXNjcmlwdG9yOwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgICB9CgogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwIGJ1aWxkKCkgewogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgfQoKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCh0aGlzKTsKICAgICAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgfQoKICAgICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwIHJlc3VsdCkgewogICAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICAgIHJlc3VsdC5idXRXaHlUaG9fID0gYnV0V2h5VGhvXzsKICAgICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwKSB7CiAgICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXApb3RoZXIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgb3RoZXIpIHsKICAgICAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgICAgaWYgKG90aGVyLmhhc0J1dFdoeVRobygpKSB7CiAgICAgICAgICAgICAgYnV0V2h5VGhvXyA9IG90aGVyLmJ1dFdoeVRob187CiAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgICAgICBidXRXaHlUaG9fID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3QgYnV0V2h5VGhvXyA9ICIiOwogICAgICAgICAgLyoqCiAgICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYnV0X3doeV90aG8gPSA1OzwvY29kZT4KICAgICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYnV0V2h5VGhvIGZpZWxkIGlzIHNldC4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzQnV0V2h5VGhvKCkgewogICAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBidXRfd2h5X3RobyA9IDU7PC9jb2RlPgogICAgICAgICAgICogQHJldHVybiBUaGUgYnV0V2h5VGhvLgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRCdXRXaHlUaG8oKSB7CiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gYnV0V2h5VGhvXzsKICAgICAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgICAgIGJ1dFdoeVRob18gPSBzOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gczsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgLyoqCiAgICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgYnV0X3doeV90aG8gPSA1OzwvY29kZT4KICAgICAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBidXRXaHlUaG8uCiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgICAgICBnZXRCdXRXaHlUaG9CeXRlcygpIHsKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBidXRXaHlUaG9fOwogICAgICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgICAgIGJ1dFdoeVRob18gPSBiOwogICAgICAgICAgICAgIHJldHVybiBiOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGJ1dF93aHlfdGhvID0gNTs8L2NvZGU+CiAgICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ1dFdoeVRobyB0byBzZXQuCiAgICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEJ1dFdoeVRobygKICAgICAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgICAgIGJ1dFdoeVRob18gPSB2YWx1ZTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgICAvKioKICAgICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBidXRfd2h5X3RobyA9IDU7PC9jb2RlPgogICAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckJ1dFdoeVRobygpIHsKICAgICAgICAgICAgYnV0V2h5VGhvXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldEJ1dFdoeVRobygpOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICAgIC8qKgogICAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGJ1dF93aHlfdGhvID0gNTs8L2NvZGU+CiAgICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBidXRXaHlUaG8gdG8gc2V0LgogICAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRCdXRXaHlUaG9CeXRlcygKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICAgICAgYnV0V2h5VGhvXyA9IHZhbHVlOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgICAgfQoKCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXApCiAgICAgICAgfQoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwKQogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgICAgc3RhdGljIHsKICAgICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwPgogICAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwPigpIHsKICAgICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgICAgfQogICAgICAgIH07CgogICAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cD4gcGFyc2VyKCkgewogICAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgICB9CgogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMQVlFUjJSRVBFQVRFREdST1VQX0ZJRUxEX05VTUJFUiA9IDI7CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwPiBsYXllcjJSZXBlYXRlZEdyb3VwXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMlJlcGVhdGVkR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cD4gZ2V0TGF5ZXIyUmVwZWF0ZWRHcm91cExpc3QoKSB7CiAgICAgICAgcmV0dXJuIGxheWVyMlJlcGVhdGVkR3JvdXBfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJSZXBlYXRlZEdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwT3JCdWlsZGVyPiAKICAgICAgICAgIGdldExheWVyMlJlcGVhdGVkR3JvdXBPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBsYXllcjJSZXBlYXRlZEdyb3VwXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyUmVwZWF0ZWRHcm91cCA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRMYXllcjJSZXBlYXRlZEdyb3VwQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGxheWVyMlJlcGVhdGVkR3JvdXBfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyUmVwZWF0ZWRHcm91cCA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIGdldExheWVyMlJlcGVhdGVkR3JvdXAoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGxheWVyMlJlcGVhdGVkR3JvdXBfLmdldChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMlJlcGVhdGVkR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cE9yQnVpbGRlciBnZXRMYXllcjJSZXBlYXRlZEdyb3VwT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGxheWVyMlJlcGVhdGVkR3JvdXBfLmdldChpbmRleCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExBWUVSMkFOT1RIRVJPUFRJT05BTFJFUEVBVEVER1JPVVBfRklFTERfTlVNQkVSID0gNDsKICAgICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXA+IGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwPiBnZXRMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwTGlzdCgpIHsKICAgICAgICByZXR1cm4gbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cE9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBDb3VudCgpIHsKICAgICAgICByZXR1cm4gbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgZ2V0TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwT3JCdWlsZGVyIGdldExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8uZ2V0KGluZGV4KTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBnZXRMYXllcjJSZXBlYXRlZEdyb3VwQ291bnQoKTsgaSsrKSB7CiAgICAgICAgICBpZiAoIWdldExheWVyMlJlcGVhdGVkR3JvdXAoaSkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxheWVyMlJlcGVhdGVkR3JvdXBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVHcm91cCgyLCBsYXllcjJSZXBlYXRlZEdyb3VwXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVHcm91cCg0LCBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxheWVyMlJlcGVhdGVkR3JvdXBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVHcm91cFNpemUoMiwgbGF5ZXIyUmVwZWF0ZWRHcm91cF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXy5zaXplKCk7IGkrKykgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlR3JvdXBTaXplKDQsIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgICByZXR1cm4gc2l6ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cCkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cCkgb2JqOwoKICAgICAgICBpZiAoIWdldExheWVyMlJlcGVhdGVkR3JvdXBMaXN0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRMYXllcjJSZXBlYXRlZEdyb3VwTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmICghZ2V0TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cExpc3QoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGlmIChnZXRMYXllcjJSZXBlYXRlZEdyb3VwQ291bnQoKSA+IDApIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIExBWUVSMlJFUEVBVEVER1JPVVBfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TGF5ZXIyUmVwZWF0ZWRHcm91cExpc3QoKS5oYXNoQ29kZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoZ2V0TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cENvdW50KCkgPiAwKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBMQVlFUjJBTk9USEVST1BUSU9OQUxSRVBFQVRFREdST1VQX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXB9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXApCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXBPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgICAgaWYgKGxheWVyMlJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGxheWVyMlJlcGVhdGVkR3JvdXBfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGF5ZXIyUmVwZWF0ZWRHcm91cF8gPSBudWxsOwogICAgICAgICAgICBsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgIGlmIChsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfID0gbnVsbDsKICAgICAgICAgICAgbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgICB9CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyX0xheWVyMU9wdGlvbmFsR3JvdXBfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cCh0aGlzKTsKICAgICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAgcmVzdWx0KSB7CiAgICAgICAgICBpZiAobGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICAgICAgbGF5ZXIyUmVwZWF0ZWRHcm91cF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChsYXllcjJSZXBlYXRlZEdyb3VwXyk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3VsdC5sYXllcjJSZXBlYXRlZEdyb3VwXyA9IGxheWVyMlJlcGVhdGVkR3JvdXBfOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVzdWx0LmxheWVyMlJlcGVhdGVkR3JvdXBfID0gbGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAobGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICAgICAgbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXyk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3VsdC5sYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXyA9IGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVzdWx0LmxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfID0gbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAgcmVzdWx0KSB7CiAgICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cCkgewogICAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXApb3RoZXIpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICAgIGlmIChsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAoIW90aGVyLmxheWVyMlJlcGVhdGVkR3JvdXBfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGlmIChsYXllcjJSZXBlYXRlZEdyb3VwXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIGxheWVyMlJlcGVhdGVkR3JvdXBfID0gb3RoZXIubGF5ZXIyUmVwZWF0ZWRHcm91cF87CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGVuc3VyZUxheWVyMlJlcGVhdGVkR3JvdXBJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIGxheWVyMlJlcGVhdGVkR3JvdXBfLmFkZEFsbChvdGhlci5sYXllcjJSZXBlYXRlZEdyb3VwXyk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoIW90aGVyLmxheWVyMlJlcGVhdGVkR3JvdXBfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGlmIChsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgICAgbGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICAgIGxheWVyMlJlcGVhdGVkR3JvdXBfID0gb3RoZXIubGF5ZXIyUmVwZWF0ZWRHcm91cF87CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICAgICAgICBsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICAgIGdldExheWVyMlJlcGVhdGVkR3JvdXBGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxheWVyMlJlcGVhdGVkR3JvdXBCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5sYXllcjJSZXBlYXRlZEdyb3VwXyk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBpZiAobGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCFvdGhlci5sYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBpZiAobGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXyA9IG90aGVyLmxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBlbnN1cmVMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXy5hZGRBbGwob3RoZXIubGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKCFvdGhlci5sYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICBpZiAobGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICAgIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXyA9IG90aGVyLmxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICAgICAgbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgICBnZXRMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIubGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZ2V0TGF5ZXIyUmVwZWF0ZWRHcm91cENvdW50KCk7IGkrKykgewogICAgICAgICAgICBpZiAoIWdldExheWVyMlJlcGVhdGVkR3JvdXAoaSkuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMTk6IHsKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAgbSA9CiAgICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkR3JvdXAoMiwKICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cC5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgICBpZiAobGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBlbnN1cmVMYXllcjJSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgbGF5ZXIyUmVwZWF0ZWRHcm91cF8uYWRkKG0pOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGxheWVyMlJlcGVhdGVkR3JvdXBCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDE5CiAgICAgICAgICAgICAgICBjYXNlIDM1OiB7CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwIG0gPQogICAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZEdyb3VwKDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgICAgaWYgKGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfLmFkZChtKTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSAzNQogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cD4gbGF5ZXIyUmVwZWF0ZWRHcm91cF8gPQogICAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVMYXllcjJSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCkgewogICAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICBsYXllcjJSZXBlYXRlZEdyb3VwXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwPihsYXllcjJSZXBlYXRlZEdyb3VwXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwT3JCdWlsZGVyPiBsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl87CgogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMlJlcGVhdGVkR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwPiBnZXRMYXllcjJSZXBlYXRlZEdyb3VwTGlzdCgpIHsKICAgICAgICAgIGlmIChsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QobGF5ZXIyUmVwZWF0ZWRHcm91cF8pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGxheWVyMlJlcGVhdGVkR3JvdXBCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJSZXBlYXRlZEdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBpbnQgZ2V0TGF5ZXIyUmVwZWF0ZWRHcm91cENvdW50KCkgewogICAgICAgICAgaWYgKGxheWVyMlJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBsYXllcjJSZXBlYXRlZEdyb3VwXy5zaXplKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMlJlcGVhdGVkR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIGdldExheWVyMlJlcGVhdGVkR3JvdXAoaW50IGluZGV4KSB7CiAgICAgICAgICBpZiAobGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGxheWVyMlJlcGVhdGVkR3JvdXBfLmdldChpbmRleCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJSZXBlYXRlZEdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExheWVyMlJlcGVhdGVkR3JvdXAoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAgdmFsdWUpIHsKICAgICAgICAgIGlmIChsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVuc3VyZUxheWVyMlJlcGVhdGVkR3JvdXBJc011dGFibGUoKTsKICAgICAgICAgICAgbGF5ZXIyUmVwZWF0ZWRHcm91cF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJSZXBlYXRlZEdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExheWVyMlJlcGVhdGVkR3JvdXAoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVMYXllcjJSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGxheWVyMlJlcGVhdGVkR3JvdXBfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxheWVyMlJlcGVhdGVkR3JvdXBCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyUmVwZWF0ZWRHcm91cCA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRMYXllcjJSZXBlYXRlZEdyb3VwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwIHZhbHVlKSB7CiAgICAgICAgICBpZiAobGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVMYXllcjJSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGxheWVyMlJlcGVhdGVkR3JvdXBfLmFkZCh2YWx1ZSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMlJlcGVhdGVkR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkTGF5ZXIyUmVwZWF0ZWRHcm91cCgKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCB2YWx1ZSkgewogICAgICAgICAgaWYgKGxheWVyMlJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5zdXJlTGF5ZXIyUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgICBsYXllcjJSZXBlYXRlZEdyb3VwXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMlJlcGVhdGVkR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkTGF5ZXIyUmVwZWF0ZWRHcm91cCgKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVMYXllcjJSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGxheWVyMlJlcGVhdGVkR3JvdXBfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMlJlcGVhdGVkR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkTGF5ZXIyUmVwZWF0ZWRHcm91cCgKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKGxheWVyMlJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUxheWVyMlJlcGVhdGVkR3JvdXBJc011dGFibGUoKTsKICAgICAgICAgICAgbGF5ZXIyUmVwZWF0ZWRHcm91cF8uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJSZXBlYXRlZEdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbExheWVyMlJlcGVhdGVkR3JvdXAoCiAgICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXA+IHZhbHVlcykgewogICAgICAgICAgaWYgKGxheWVyMlJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUxheWVyMlJlcGVhdGVkR3JvdXBJc011dGFibGUoKTsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgICAgdmFsdWVzLCBsYXllcjJSZXBlYXRlZEdyb3VwXyk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyUmVwZWF0ZWRHcm91cCA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxheWVyMlJlcGVhdGVkR3JvdXAoKSB7CiAgICAgICAgICBpZiAobGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgbGF5ZXIyUmVwZWF0ZWRHcm91cF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJSZXBlYXRlZEdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZUxheWVyMlJlcGVhdGVkR3JvdXAoaW50IGluZGV4KSB7CiAgICAgICAgICBpZiAobGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlTGF5ZXIyUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgICBsYXllcjJSZXBlYXRlZEdyb3VwXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxheWVyMlJlcGVhdGVkR3JvdXBCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMlJlcGVhdGVkR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwLkJ1aWxkZXIgZ2V0TGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgcmV0dXJuIGdldExheWVyMlJlcGVhdGVkR3JvdXBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyUmVwZWF0ZWRHcm91cCA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXBPckJ1aWxkZXIgZ2V0TGF5ZXIyUmVwZWF0ZWRHcm91cE9yQnVpbGRlcigKICAgICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgICBpZiAobGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGxheWVyMlJlcGVhdGVkR3JvdXBfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJSZXBlYXRlZEdyb3VwID0gMiB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXBPckJ1aWxkZXI+IAogICAgICAgICAgICAgZ2V0TGF5ZXIyUmVwZWF0ZWRHcm91cE9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgICBpZiAobGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGxheWVyMlJlcGVhdGVkR3JvdXBCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KGxheWVyMlJlcGVhdGVkR3JvdXBfKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyUmVwZWF0ZWRHcm91cCA9IDIgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAuQnVpbGRlciBhZGRMYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcigpIHsKICAgICAgICAgIHJldHVybiBnZXRMYXllcjJSZXBlYXRlZEdyb3VwRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMlJlcGVhdGVkR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwLkJ1aWxkZXIgYWRkTGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXIoCiAgICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgICAgcmV0dXJuIGdldExheWVyMlJlcGVhdGVkR3JvdXBGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICAgIGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMlJlcGVhdGVkR3JvdXAgPSAyIHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwLkJ1aWxkZXI+IAogICAgICAgICAgICAgZ2V0TGF5ZXIyUmVwZWF0ZWRHcm91cEJ1aWxkZXJMaXN0KCkgewogICAgICAgICAgcmV0dXJuIGdldExheWVyMlJlcGVhdGVkR3JvdXBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwT3JCdWlsZGVyPiAKICAgICAgICAgICAgZ2V0TGF5ZXIyUmVwZWF0ZWRHcm91cEZpZWxkQnVpbGRlcigpIHsKICAgICAgICAgIGlmIChsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJSZXBlYXRlZEdyb3VwT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgICBsYXllcjJSZXBlYXRlZEdyb3VwXywKICAgICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICAgIGxheWVyMlJlcGVhdGVkR3JvdXBfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBsYXllcjJSZXBlYXRlZEdyb3VwQnVpbGRlcl87CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwPiBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXyA9CiAgICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZUxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBJc011dGFibGUoKSB7CiAgICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICAgIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXA+KGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBPckJ1aWxkZXI+IGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBCdWlsZGVyXzsKCiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXA+IGdldExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBMaXN0KCkgewogICAgICAgICAgaWYgKGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXyk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGludCBnZXRMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQ291bnQoKSB7CiAgICAgICAgICBpZiAobGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfLnNpemUoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgZ2V0TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cChpbnQgaW5kZXgpIHsKICAgICAgICAgIGlmIChsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8uZ2V0KGluZGV4KTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCgKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCB2YWx1ZSkgewogICAgICAgICAgaWYgKGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5zdXJlTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCgKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBJc011dGFibGUoKTsKICAgICAgICAgICAgbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgdmFsdWUpIHsKICAgICAgICAgIGlmIChsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVuc3VyZUxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBJc011dGFibGUoKTsKICAgICAgICAgICAgbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8uYWRkKHZhbHVlKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwKAogICAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwIHZhbHVlKSB7CiAgICAgICAgICBpZiAobGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgICAgaWYgKGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZUxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBJc011dGFibGUoKTsKICAgICAgICAgICAgbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwKAogICAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgICBpZiAobGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCgKICAgICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cD4gdmFsdWVzKSB7CiAgICAgICAgICBpZiAobGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cElzTXV0YWJsZSgpOwogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgICB2YWx1ZXMsIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCgpIHsKICAgICAgICAgIGlmIChsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBCdWlsZGVyXy5jbGVhcigpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cChpbnQgaW5kZXgpIHsKICAgICAgICAgIGlmIChsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBlbnN1cmVMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAuQnVpbGRlciBnZXRMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcigKICAgICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgICByZXR1cm4gZ2V0TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cE9yQnVpbGRlciBnZXRMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwT3JCdWlsZGVyKAogICAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICAgIGlmIChsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGdyb3VwIExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAgPSA0IHsgLi4uIH08L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cE9yQnVpbGRlcj4gCiAgICAgICAgICAgICBnZXRMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICAgIGlmIChsYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QobGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCBncm91cCBMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwID0gNCB7IC4uLiB9PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cC5CdWlsZGVyIGFkZExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBCdWlsZGVyKCkgewogICAgICAgICAgcmV0dXJuIGdldExheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAuQnVpbGRlciBhZGRMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlcigKICAgICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgICByZXR1cm4gZ2V0TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgICAgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgZ3JvdXAgTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCA9IDQgeyAuLi4gfTwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAuQnVpbGRlcj4gCiAgICAgICAgICAgICBnZXRMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwQnVpbGRlckxpc3QoKSB7CiAgICAgICAgICByZXR1cm4gZ2V0TGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBPckJ1aWxkZXI+IAogICAgICAgICAgICBnZXRMYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwRmllbGRCdWlsZGVyKCkgewogICAgICAgICAgaWYgKGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICAgIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfLAogICAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApLAogICAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgICAgbGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF8gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBCdWlsZGVyXzsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwKQogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cCkKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIHN0YXRpYyB7CiAgICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxMYXllcjFPcHRpb25hbEdyb3VwPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TGF5ZXIxT3B0aW9uYWxHcm91cD4oKSB7CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBMYXllcjFPcHRpb25hbEdyb3VwIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICAgIH0KICAgICAgfTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TGF5ZXIxT3B0aW9uYWxHcm91cD4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPExheWVyMU9wdGlvbmFsR3JvdXA+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IExBWUVSMU9QVElPTkFMR1JPVVBfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwIGxheWVyMU9wdGlvbmFsR3JvdXBfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBMYXllcjFPcHRpb25hbEdyb3VwID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBsYXllcjFvcHRpb25hbGdyb3VwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzTGF5ZXIxT3B0aW9uYWxHcm91cCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBMYXllcjFPcHRpb25hbEdyb3VwID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgbGF5ZXIxb3B0aW9uYWxncm91cC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cCBnZXRMYXllcjFPcHRpb25hbEdyb3VwKCkgewogICAgICByZXR1cm4gbGF5ZXIxT3B0aW9uYWxHcm91cF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGxheWVyMU9wdGlvbmFsR3JvdXBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBMYXllcjFPcHRpb25hbEdyb3VwID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwT3JCdWlsZGVyIGdldExheWVyMU9wdGlvbmFsR3JvdXBPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBsYXllcjFPcHRpb25hbEdyb3VwXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbGF5ZXIxT3B0aW9uYWxHcm91cF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKGhhc0xheWVyMU9wdGlvbmFsR3JvdXAoKSkgewogICAgICAgIGlmICghZ2V0TGF5ZXIxT3B0aW9uYWxHcm91cCgpLmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVHcm91cCgxLCBnZXRMYXllcjFPcHRpb25hbEdyb3VwKCkpOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlR3JvdXBTaXplKDEsIGdldExheWVyMU9wdGlvbmFsR3JvdXAoKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlciBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyKSBvYmo7CgogICAgICBpZiAoaGFzTGF5ZXIxT3B0aW9uYWxHcm91cCgpICE9IG90aGVyLmhhc0xheWVyMU9wdGlvbmFsR3JvdXAoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzTGF5ZXIxT3B0aW9uYWxHcm91cCgpKSB7CiAgICAgICAgaWYgKCFnZXRMYXllcjFPcHRpb25hbEdyb3VwKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRMYXllcjFPcHRpb25hbEdyb3VwKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzTGF5ZXIxT3B0aW9uYWxHcm91cCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTEFZRVIxT1BUSU9OQUxHUk9VUF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0TGF5ZXIxT3B0aW9uYWxHcm91cCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlciBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlciBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlciBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlciBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlciBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogTk9URTogSW50ZW50aW9uYWxseSBuZXN0ZWQgdG8gbWlycm9yIGdvL2dsZXAuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0TGF5ZXIxT3B0aW9uYWxHcm91cEZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgbGF5ZXIxT3B0aW9uYWxHcm91cF8gPSBudWxsOwogICAgICAgIGlmIChsYXllcjFPcHRpb25hbEdyb3VwQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgbGF5ZXIxT3B0aW9uYWxHcm91cEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIGxheWVyMU9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlciByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5sYXllcjFPcHRpb25hbEdyb3VwXyA9IGxheWVyMU9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBsYXllcjFPcHRpb25hbEdyb3VwXwogICAgICAgICAgICAgIDogbGF5ZXIxT3B0aW9uYWxHcm91cEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0xheWVyMU9wdGlvbmFsR3JvdXAoKSkgewogICAgICAgICAgbWVyZ2VMYXllcjFPcHRpb25hbEdyb3VwKG90aGVyLmdldExheWVyMU9wdGlvbmFsR3JvdXAoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoaGFzTGF5ZXIxT3B0aW9uYWxHcm91cCgpKSB7CiAgICAgICAgICBpZiAoIWdldExheWVyMU9wdGlvbmFsR3JvdXAoKS5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTE6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRHcm91cCgxLAogICAgICAgICAgICAgICAgICAgIGdldExheWVyMU9wdGlvbmFsR3JvdXBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDExCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwIGxheWVyMU9wdGlvbmFsR3JvdXBfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXBPckJ1aWxkZXI+IGxheWVyMU9wdGlvbmFsR3JvdXBCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIExheWVyMU9wdGlvbmFsR3JvdXAgPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgbGF5ZXIxb3B0aW9uYWxncm91cCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNMYXllcjFPcHRpb25hbEdyb3VwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgTGF5ZXIxT3B0aW9uYWxHcm91cCA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgbGF5ZXIxb3B0aW9uYWxncm91cC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAgZ2V0TGF5ZXIxT3B0aW9uYWxHcm91cCgpIHsKICAgICAgICBpZiAobGF5ZXIxT3B0aW9uYWxHcm91cEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBsYXllcjFPcHRpb25hbEdyb3VwXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLmdldERlZmF1bHRJbnN0YW5jZSgpIDogbGF5ZXIxT3B0aW9uYWxHcm91cF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBsYXllcjFPcHRpb25hbEdyb3VwQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgTGF5ZXIxT3B0aW9uYWxHcm91cCA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldExheWVyMU9wdGlvbmFsR3JvdXAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwIHZhbHVlKSB7CiAgICAgICAgaWYgKGxheWVyMU9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGxheWVyMU9wdGlvbmFsR3JvdXBfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGxheWVyMU9wdGlvbmFsR3JvdXBCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBncm91cCBMYXllcjFPcHRpb25hbEdyb3VwID0gMSB7IC4uLiB9PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0TGF5ZXIxT3B0aW9uYWxHcm91cCgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChsYXllcjFPcHRpb25hbEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbGF5ZXIxT3B0aW9uYWxHcm91cF8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGF5ZXIxT3B0aW9uYWxHcm91cEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIExheWVyMU9wdGlvbmFsR3JvdXAgPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUxheWVyMU9wdGlvbmFsR3JvdXAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwIHZhbHVlKSB7CiAgICAgICAgaWYgKGxheWVyMU9wdGlvbmFsR3JvdXBCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkgJiYKICAgICAgICAgICAgbGF5ZXIxT3B0aW9uYWxHcm91cF8gIT0gbnVsbCAmJgogICAgICAgICAgICBsYXllcjFPcHRpb25hbEdyb3VwXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0TGF5ZXIxT3B0aW9uYWxHcm91cEJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGF5ZXIxT3B0aW9uYWxHcm91cF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGF5ZXIxT3B0aW9uYWxHcm91cEJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChsYXllcjFPcHRpb25hbEdyb3VwXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIExheWVyMU9wdGlvbmFsR3JvdXAgPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckxheWVyMU9wdGlvbmFsR3JvdXAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGxheWVyMU9wdGlvbmFsR3JvdXBfID0gbnVsbDsKICAgICAgICBpZiAobGF5ZXIxT3B0aW9uYWxHcm91cEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIGxheWVyMU9wdGlvbmFsR3JvdXBCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBsYXllcjFPcHRpb25hbEdyb3VwQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgTGF5ZXIxT3B0aW9uYWxHcm91cCA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuQnVpbGRlciBnZXRMYXllcjFPcHRpb25hbEdyb3VwQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldExheWVyMU9wdGlvbmFsR3JvdXBGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGdyb3VwIExheWVyMU9wdGlvbmFsR3JvdXAgPSAxIHsgLi4uIH08L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwT3JCdWlsZGVyIGdldExheWVyMU9wdGlvbmFsR3JvdXBPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKGxheWVyMU9wdGlvbmFsR3JvdXBCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gbGF5ZXIxT3B0aW9uYWxHcm91cEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGxheWVyMU9wdGlvbmFsR3JvdXBfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IGxheWVyMU9wdGlvbmFsR3JvdXBfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZ3JvdXAgTGF5ZXIxT3B0aW9uYWxHcm91cCA9IDEgeyAuLi4gfTwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHcm91cE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRMYXllcjFPcHRpb25hbEdyb3VwRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChsYXllcjFPcHRpb25hbEdyb3VwQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgbGF5ZXIxT3B0aW9uYWxHcm91cEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0TGF5ZXIxT3B0aW9uYWxHcm91cCgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgbGF5ZXIxT3B0aW9uYWxHcm91cF8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbGF5ZXIxT3B0aW9uYWxHcm91cEJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlciBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGlubmVyX25hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaW5uZXJOYW1lIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNJbm5lck5hbWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGlubmVyX25hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGlubmVyTmFtZS4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRJbm5lck5hbWUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGlubmVyX25hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBpbm5lck5hbWUuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldElubmVyTmFtZUJ5dGVzKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9ufQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24gZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24pCiAgICAgIFRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbi5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uKCkgewogICAgICBpbm5lck5hbWVfID0gIiI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSU5ORVJfTkFNRV9GSUVMRF9OVU1CRVIgPSAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3QgaW5uZXJOYW1lXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgaW5uZXJfbmFtZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBpbm5lck5hbWUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbm5lck5hbWUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGlubmVyX25hbWUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGlubmVyTmFtZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0SW5uZXJOYW1lKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IGlubmVyTmFtZV87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgaW5uZXJOYW1lXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBpbm5lcl9uYW1lID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgaW5uZXJOYW1lLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0SW5uZXJOYW1lQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gaW5uZXJOYW1lXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgaW5uZXJOYW1lXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxLCBpbm5lck5hbWVfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxLCBpbm5lck5hbWVfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24pIG9iajsKCiAgICAgIGlmIChoYXNJbm5lck5hbWUoKSAhPSBvdGhlci5oYXNJbm5lck5hbWUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzSW5uZXJOYW1lKCkpIHsKICAgICAgICBpZiAoIWdldElubmVyTmFtZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0SW5uZXJOYW1lKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzSW5uZXJOYW1lKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBJTk5FUl9OQU1FX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRJbm5lck5hbWUoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24gcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24gcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24gcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24gcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24gcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb259CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24uY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24uQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBpbm5lck5hbWVfID0gIiI7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbiBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbiBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbih0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmlubmVyTmFtZV8gPSBpbm5lck5hbWVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNJbm5lck5hbWUoKSkgewogICAgICAgICAgaW5uZXJOYW1lXyA9IG90aGVyLmlubmVyTmFtZV87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW5uZXJOYW1lXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBpbm5lck5hbWVfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgaW5uZXJfbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGlubmVyTmFtZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNJbm5lck5hbWUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgaW5uZXJfbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBpbm5lck5hbWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRJbm5lck5hbWUoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBpbm5lck5hbWVfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgaW5uZXJOYW1lXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgaW5uZXJfbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3IgaW5uZXJOYW1lLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0SW5uZXJOYW1lQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBpbm5lck5hbWVfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBpbm5lck5hbWVfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIGlubmVyX25hbWUgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBpbm5lck5hbWUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRJbm5lck5hbWUoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBpbm5lck5hbWVfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgaW5uZXJfbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcklubmVyTmFtZSgpIHsKICAgICAgICBpbm5lck5hbWVfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0SW5uZXJOYW1lKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgaW5uZXJfbmFtZSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBpbm5lck5hbWUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRJbm5lck5hbWVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgaW5uZXJOYW1lXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24pCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24gZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy4KICAgICAgICAgIEV4dGVuZGFibGVNZXNzYWdlT3JCdWlsZGVyPFRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZT4gewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vX29uZSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29PbmUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0Zvb09uZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb29fb25lID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29PbmUuCiAgICAgKi8KICAgIGludCBnZXRGb29PbmUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb190d28gPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vVHdvIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNGb29Ud28oKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vX3R3byA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vVHdvLgogICAgICovCiAgICBpbnQgZ2V0Rm9vVHdvKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb29fdGhyZWUgPSA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vVGhyZWUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0Zvb1RocmVlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb190aHJlZSA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vVGhyZWUuCiAgICAgKi8KICAgIGludCBnZXRGb29UaHJlZSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vX2ZvdXIgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb0ZvdXIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0Zvb0ZvdXIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vX2ZvdXIgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29Gb3VyLgogICAgICovCiAgICBpbnQgZ2V0Rm9vRm91cigpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgICBUZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemU+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUpCiAgICAgIFRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSwgPz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX09ORV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgZm9vT25lXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19vbmUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vT25lIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vT25lKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19vbmUgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb09uZS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGb29PbmUoKSB7CiAgICAgIHJldHVybiBmb29PbmVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19UV09fRklFTERfTlVNQkVSID0gNjsKICAgIHByaXZhdGUgaW50IGZvb1R3b18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb29fdHdvID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvb1R3byBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb1R3bygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb29fdHdvID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBmb29Ud28uCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Rm9vVHdvKCkgewogICAgICByZXR1cm4gZm9vVHdvXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGT09fVEhSRUVfRklFTERfTlVNQkVSID0gNzsKICAgIHByaXZhdGUgaW50IGZvb1RocmVlXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb190aHJlZSA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29UaHJlZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0Zvb1RocmVlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb190aHJlZSA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgZm9vVGhyZWUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Rm9vVGhyZWUoKSB7CiAgICAgIHJldHVybiBmb29UaHJlZV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX0ZPVVJfRklFTERfTlVNQkVSID0gMTM7CiAgICBwcml2YXRlIGludCBmb29Gb3VyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19mb3VyID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29Gb3VyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRm9vRm91cigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb29fZm91ciA9IDEzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvb0ZvdXIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0Rm9vRm91cigpIHsKICAgICAgcmV0dXJuIGZvb0ZvdXJfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLkV4dGVuZGFibGVNZXNzYWdlPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplPi5FeHRlbnNpb25Xcml0ZXIKICAgICAgICAgIGV4dGVuc2lvbldyaXRlciA9IG5ld0V4dGVuc2lvbldyaXRlcigpOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBmb29PbmVfKTsKICAgICAgfQogICAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCg1LCBvdXRwdXQpOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig2LCBmb29Ud29fKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig3LCBmb29UaHJlZV8pOwogICAgICB9CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDExLCBvdXRwdXQpOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxMywgZm9vRm91cl8pOwogICAgICB9CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDIwLCBvdXRwdXQpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBmb29PbmVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDYsIGZvb1R3b18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNywgZm9vVGhyZWVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEzLCBmb29Gb3VyXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBleHRlbnNpb25zU2VyaWFsaXplZFNpemUoKTsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplKSBvYmo7CgogICAgICBpZiAoaGFzRm9vT25lKCkgIT0gb3RoZXIuaGFzRm9vT25lKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0Zvb09uZSgpKSB7CiAgICAgICAgaWYgKGdldEZvb09uZSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEZvb09uZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0Zvb1R3bygpICE9IG90aGVyLmhhc0Zvb1R3bygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGb29Ud28oKSkgewogICAgICAgIGlmIChnZXRGb29Ud28oKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGb29Ud28oKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNGb29UaHJlZSgpICE9IG90aGVyLmhhc0Zvb1RocmVlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0Zvb1RocmVlKCkpIHsKICAgICAgICBpZiAoZ2V0Rm9vVGhyZWUoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGb29UaHJlZSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0Zvb0ZvdXIoKSAhPSBvdGhlci5oYXNGb29Gb3VyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc0Zvb0ZvdXIoKSkgewogICAgICAgIGlmIChnZXRGb29Gb3VyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0Rm9vRm91cigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzRm9vT25lKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGT09fT05FX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGb29PbmUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRm9vVHdvKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGT09fVFdPX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRGb29Ud28oKTsKICAgICAgfQogICAgICBpZiAoaGFzRm9vVGhyZWUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEZPT19USFJFRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0Rm9vVGhyZWUoKTsKICAgICAgfQogICAgICBpZiAoaGFzRm9vRm91cigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRk9PX0ZPVVJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZvb0ZvdXIoKTsKICAgICAgfQogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplLCBCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZS5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgZm9vT25lXyA9IDA7CiAgICAgICAgZm9vVHdvXyA9IDA7CiAgICAgICAgZm9vVGhyZWVfID0gMDsKICAgICAgICBmb29Gb3VyXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZvb09uZV8gPSBmb29PbmVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZvb1R3b18gPSBmb29Ud29fOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LmZvb1RocmVlXyA9IGZvb1RocmVlXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5mb29Gb3VyXyA9IGZvb0ZvdXJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSwgVHlwZT4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VD4gQnVpbGRlciBjbGVhckV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUsIFQ+IGV4dGVuc2lvbikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckV4dGVuc2lvbihleHRlbnNpb24pOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0Zvb09uZSgpKSB7CiAgICAgICAgICBzZXRGb29PbmUob3RoZXIuZ2V0Rm9vT25lKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzRm9vVHdvKCkpIHsKICAgICAgICAgIHNldEZvb1R3byhvdGhlci5nZXRGb29Ud28oKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGb29UaHJlZSgpKSB7CiAgICAgICAgICBzZXRGb29UaHJlZShvdGhlci5nZXRGb29UaHJlZSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc0Zvb0ZvdXIoKSkgewogICAgICAgICAgc2V0Rm9vRm91cihvdGhlci5nZXRGb29Gb3VyKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlRXh0ZW5zaW9uRmllbGRzKG90aGVyKTsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgZm9vT25lXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDQ4OiB7CiAgICAgICAgICAgICAgICBmb29Ud29fID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDgKICAgICAgICAgICAgICBjYXNlIDU2OiB7CiAgICAgICAgICAgICAgICBmb29UaHJlZV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NgogICAgICAgICAgICAgIGNhc2UgMTA0OiB7CiAgICAgICAgICAgICAgICBmb29Gb3VyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwNAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBmb29PbmVfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19vbmUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29PbmUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29PbmUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb29fb25lID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZvb09uZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGb29PbmUoKSB7CiAgICAgICAgcmV0dXJuIGZvb09uZV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19vbmUgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb29PbmUgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29PbmUoaW50IHZhbHVlKSB7CgogICAgICAgIGZvb09uZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19vbmUgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb29PbmUoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGZvb09uZV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmb29Ud29fIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb190d28gPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29Ud28gZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29Ud28oKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb29fdHdvID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGZvb1R3by4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGb29Ud28oKSB7CiAgICAgICAgcmV0dXJuIGZvb1R3b187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb190d28gPSA2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb29Ud28gdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb29Ud28oaW50IHZhbHVlKSB7CgogICAgICAgIGZvb1R3b18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb190d28gPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGb29Ud28oKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIGZvb1R3b18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmb29UaHJlZV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9vX3RocmVlID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZm9vVGhyZWUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGb29UaHJlZSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb190aHJlZSA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmb29UaHJlZS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRGb29UaHJlZSgpIHsKICAgICAgICByZXR1cm4gZm9vVGhyZWVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb29fdGhyZWUgPSA3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb29UaHJlZSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZvb1RocmVlKGludCB2YWx1ZSkgewoKICAgICAgICBmb29UaHJlZV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb190aHJlZSA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZvb1RocmVlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBmb29UaHJlZV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmb29Gb3VyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb29fZm91ciA9IDEzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb29Gb3VyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzRm9vRm91cigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19mb3VyID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmb29Gb3VyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldEZvb0ZvdXIoKSB7CiAgICAgICAgcmV0dXJuIGZvb0ZvdXJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb29fZm91ciA9IDEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb29Gb3VyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0Rm9vRm91cihpbnQgdmFsdWUpIHsKCiAgICAgICAgZm9vRm91cl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvb19mb3VyID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZvb0ZvdXIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIGZvb0ZvdXJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZT4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemU+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCQVJfT05FX0ZJRUxEX05VTUJFUiA9IDI7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gYmFyT25lID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAwLAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgICBudWxsKTsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9UV09fRklFTERfTlVNQkVSID0gNDsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplLAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiBiYXJUd28gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSwKICAgICAgICAgIDEsCiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICAgIG51bGwpOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSX1RIUkVFX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgLyoqCiAgICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUsCiAgICAgICAgamF2YS5sYW5nLkludGVnZXI+IGJhclRocmVlID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAyLAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgICBudWxsKTsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEJBUl9GT1VSX0ZJRUxEX05VTUJFUiA9IDE1OwogICAgLyoqCiAgICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemUsCiAgICAgICAgamF2YS5sYW5nLkludGVnZXI+IGJhckZvdXIgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZS5nZXREZWZhdWx0SW5zdGFuY2UoKSwKICAgICAgICAgIDMsCiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICAgIG51bGwpOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSX0ZJVkVfRklFTERfTlVNQkVSID0gMTk7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZSwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gYmFyRml2ZSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgNCwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgICAgbnVsbCk7CiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RWZXJpZnlJbnQzMlNpbXBsZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5SW50MzJTaW1wbGUpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMS4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzIxKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzIyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjMuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyNjMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzI2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI2NC4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzI2NCgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5SW50MzJTaW1wbGV9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0VmVyaWZ5SW50MzJTaW1wbGUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUludDMyU2ltcGxlKQogICAgICBUZXN0VmVyaWZ5SW50MzJTaW1wbGVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RWZXJpZnlJbnQzMlNpbXBsZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0VmVyaWZ5SW50MzJTaW1wbGUoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0VmVyaWZ5SW50MzJTaW1wbGUoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFZlcmlmeUludDMyU2ltcGxlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUludDMyU2ltcGxlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUludDMyU2ltcGxlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJTaW1wbGUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyU2ltcGxlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl8xX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyMV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjEoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDMyMV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UMzJfMl9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyXzYzX0ZJRUxEX05VTUJFUiA9IDYzOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjYzXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyNjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjYzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjYzXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl82NF9GSUVMRF9OVU1CRVIgPSA2NDsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI2NF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjY0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzI2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI2NF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBvcHRpb25hbEludDMyMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIG9wdGlvbmFsSW50MzIyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNjMsIG9wdGlvbmFsSW50MzI2M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDY0LCBvcHRpb25hbEludDMyNjRfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBvcHRpb25hbEludDMyMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMiwgb3B0aW9uYWxJbnQzMjJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDYzLCBvcHRpb25hbEludDMyNjNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDY0LCBvcHRpb25hbEludDMyNjRfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJTaW1wbGUgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJTaW1wbGUpIG9iajsKCiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMSgpICE9IG90aGVyLmhhc09wdGlvbmFsSW50MzIxKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIxKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMjEoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDMyMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIyKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMjIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjIoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMyMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzIyKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjYzKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMjYzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2MygpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50MzI2MygpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzI2MygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2NCgpICE9IG90aGVyLmhhc09wdGlvbmFsSW50MzI2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyNjQoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMyNjQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDMyNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIxKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl8xX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEludDMyMSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjIoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjYzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl82M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjYzKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzI2NCgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJTaW1wbGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyU2ltcGxlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyU2ltcGxlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyU2ltcGxlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJTaW1wbGUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyU2ltcGxlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyU2ltcGxlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyU2ltcGxlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlJbnQzMlNpbXBsZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlJbnQzMlNpbXBsZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJTaW1wbGVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUludDMyU2ltcGxlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyU2ltcGxlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyU2ltcGxlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyMV8gPSAwOwogICAgICAgIG9wdGlvbmFsSW50MzIyXyA9IDA7CiAgICAgICAgb3B0aW9uYWxJbnQzMjYzXyA9IDA7CiAgICAgICAgb3B0aW9uYWxJbnQzMjY0XyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlJbnQzMlNpbXBsZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJTaW1wbGUgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJTaW1wbGUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZSBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJTaW1wbGUgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyU2ltcGxlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyU2ltcGxlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzIxXyA9IG9wdGlvbmFsSW50MzIxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyMl8gPSBvcHRpb25hbEludDMyMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMjYzXyA9IG9wdGlvbmFsSW50MzI2M187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMjY0XyA9IG9wdGlvbmFsSW50MzI2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJTaW1wbGUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJTaW1wbGUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJTaW1wbGUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyMSgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyMShvdGhlci5nZXRPcHRpb25hbEludDMyMSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50MzIyKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzIyKG90aGVyLmdldE9wdGlvbmFsSW50MzIyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQzMjYzKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzI2MyhvdGhlci5nZXRPcHRpb25hbEludDMyNjMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyNjQoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQzMjY0KG90aGVyLmdldE9wdGlvbmFsSW50MzI2NCgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyMV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQzMjJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDUwNDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQzMjYzXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwNAogICAgICAgICAgICAgIGNhc2UgNTEyOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyNjRfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTEyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzIxXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjEoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzIxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMjEoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzIxKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvcHRpb25hbEludDMyMV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDMyMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50MzIyKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDMyMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEludDMyMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb3B0aW9uYWxJbnQzMjJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjYzXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyNjMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjYzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzI2MygpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjYzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQzMjYzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMjYzKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDMyNjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEludDMyNjMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9wdGlvbmFsSW50MzI2M18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyNjRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzI2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjY0KCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDMyNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyNjQoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzI2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzI2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb3B0aW9uYWxJbnQzMjY0XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUludDMyU2ltcGxlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5SW50MzJTaW1wbGUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMlNpbXBsZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJTaW1wbGUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VmVyaWZ5SW50MzJTaW1wbGU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFZlcmlmeUludDMyU2ltcGxlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdFZlcmlmeUludDMyU2ltcGxlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFZlcmlmeUludDMyU2ltcGxlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RWZXJpZnlJbnQzMlNpbXBsZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJTaW1wbGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0VmVyaWZ5SW50MzJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUludDMyKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjEuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyMSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjYzLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxJbnQzMjYzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjQuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyNjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQWxsVHlwZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsQWxsVHlwZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE9wdGlvbmFsQWxsVHlwZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0T3B0aW9uYWxBbGxUeXBlc09yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiAKICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0UmVwZWF0ZWRBbGxUeXBlcyhpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5SW50MzJ9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0VmVyaWZ5SW50MzIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUludDMyKQogICAgICBUZXN0VmVyaWZ5SW50MzJPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RWZXJpZnlJbnQzMi5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0VmVyaWZ5SW50MzIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0VmVyaWZ5SW50MzIoKSB7CiAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RWZXJpZnlJbnQzMigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlJbnQzMl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlJbnQzMl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UMzJfMV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjFfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIxKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyXzJfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzIyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzIyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl82M19GSUVMRF9OVU1CRVIgPSA2MzsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI2M18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjYzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjYzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzI2MygpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI2M187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UMzJfNjRfRklFTERfTlVNQkVSID0gNjQ7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyNjRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzI2NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyNjQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDMyNjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0FMTF9UWVBFU19GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBvcHRpb25hbEFsbFR5cGVzXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBbGxUeXBlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIG9wdGlvbmFsSW50MzIxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMiwgb3B0aW9uYWxJbnQzMjJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDksIGdldE9wdGlvbmFsQWxsVHlwZXMoKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEFsbFR5cGVzXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTAsIHJlcGVhdGVkQWxsVHlwZXNfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNjMsIG9wdGlvbmFsSW50MzI2M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDY0LCBvcHRpb25hbEludDMyNjRfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBvcHRpb25hbEludDMyMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMiwgb3B0aW9uYWxJbnQzMjJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOSwgZ2V0T3B0aW9uYWxBbGxUeXBlcygpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwLCByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNjMsIG9wdGlvbmFsSW50MzI2M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNjQsIG9wdGlvbmFsSW50MzI2NF8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMiBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMikgb2JqOwoKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIxKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMjEoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjEoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMyMSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzIxKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjIoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDMyMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMigpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50MzIyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyNjMoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDMyNjMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjYzKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMjYzKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjYzKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjY0KCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMjY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2NCgpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50MzI2NCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzI2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsQWxsVHlwZXMoKSAhPSBvdGhlci5oYXNPcHRpb25hbEFsbFR5cGVzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsQWxsVHlwZXMoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxBbGxUeXBlcygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxBbGxUeXBlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjEoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lOVDMyXzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzIyKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2MygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfNjNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzI2MygpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyNjQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lOVDMyXzY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEludDMyNjQoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxBbGxUeXBlcygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEFsbFR5cGVzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRBbGxUeXBlc0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUludDMyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUludDMyKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlJbnQzMl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgb3B0aW9uYWxJbnQzMjFfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyMl8gPSAwOwogICAgICAgIG9wdGlvbmFsSW50MzI2M18gPSAwOwogICAgICAgIG9wdGlvbmFsSW50MzI2NF8gPSAwOwogICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMih0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMiByZXN1bHQpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQWxsVHlwZXNfID0gcmVwZWF0ZWRBbGxUeXBlc187CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEFsbFR5cGVzXyA9IHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMjFfID0gb3B0aW9uYWxJbnQzMjFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzIyXyA9IG9wdGlvbmFsSW50MzIyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyNjNfID0gb3B0aW9uYWxJbnQzMjYzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyNjRfID0gb3B0aW9uYWxJbnQzMjY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEFsbFR5cGVzXyA9IG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbEFsbFR5cGVzXwogICAgICAgICAgICAgIDogb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyMSgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyMShvdGhlci5nZXRPcHRpb25hbEludDMyMSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50MzIyKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzIyKG90aGVyLmdldE9wdGlvbmFsSW50MzIyKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQzMjYzKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzI2MyhvdGhlci5nZXRPcHRpb25hbEludDMyNjMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyNjQoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQzMjY0KG90aGVyLmdldE9wdGlvbmFsSW50MzI2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsQWxsVHlwZXMoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbEFsbFR5cGVzKG90aGVyLmdldE9wdGlvbmFsQWxsVHlwZXMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEFsbFR5cGVzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gb3RoZXIucmVwZWF0ZWRBbGxUeXBlc187CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQWxsVHlwZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IG90aGVyLnJlcGVhdGVkQWxsVHlwZXNfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIucmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQzMjFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzIyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSA3NDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgICBjYXNlIDgyOiB7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgIGNhc2UgNTA0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyNjNfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTA0CiAgICAgICAgICAgICAgY2FzZSA1MTI6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzI2NF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MTIKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjFfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyMSgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQzMjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyMShpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMjEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9wdGlvbmFsSW50MzIxXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzIyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzIyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMjIoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzIyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvcHRpb25hbEludDMyMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyNjNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzI2MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjYzKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDMyNjNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyNjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyNjMoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzI2M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzI2MygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb3B0aW9uYWxJbnQzMjYzXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyNjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzI2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50MzI2NChpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMjY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMjY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvcHRpb25hbEludDMyNjRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQWxsVHlwZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0T3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxBbGxUeXBlcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQWxsVHlwZXMoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc18gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0T3B0aW9uYWxBbGxUeXBlc09yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXMoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gcmVwZWF0ZWRBbGxUeXBlc18gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4ocmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQWxsVHlwZXMoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRBbGxUeXBlcygpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlJbnQzMikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUludDMyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFZlcmlmeUludDMyPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RWZXJpZnlJbnQzMj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RWZXJpZnlJbnQzMiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RWZXJpZnlJbnQzMj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VmVyaWZ5SW50MzI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFZlcmlmeU1vc3RseUludDMyT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlNb3N0bHlJbnQzMikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzMwID0gMzA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDY0MzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50NjQzMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF8zMCA9IDMwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjQzMC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbEludDY0MzAoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzIxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIxLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxJbnQzMjEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzIyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIyLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxJbnQzMjIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzIzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIzLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxJbnQzMjMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzI0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI0LgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxJbnQzMjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyNjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzI2MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI2My4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzI2MygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjY0LgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxJbnQzMjY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEFsbFR5cGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEFsbFR5cGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEFsbFR5cGVzLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRPcHRpb25hbEFsbFR5cGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldE9wdGlvbmFsQWxsVHlwZXNPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gCiAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQWxsVHlwZXMoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEFsbFR5cGVzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeU1vc3RseUludDMyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFZlcmlmeU1vc3RseUludDMyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlNb3N0bHlJbnQzMikKICAgICAgVGVzdFZlcmlmeU1vc3RseUludDMyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0VmVyaWZ5TW9zdGx5SW50MzIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFZlcmlmeU1vc3RseUludDMyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFZlcmlmeU1vc3RseUludDMyKCkgewogICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0VmVyaWZ5TW9zdGx5SW50MzIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5TW9zdGx5SW50MzJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5TW9zdGx5SW50MzJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDY0XzMwX0ZJRUxEX05VTUJFUiA9IDMwOwogICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsSW50NjQzMF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfMzAgPSAzMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50NjQzMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50NjQzMCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF8zMCA9IDMwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjQzMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxJbnQ2NDMwKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQ2NDMwXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl8xX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyMV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjEoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDMyMV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UMzJfMl9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyXzNfRklFTERfTlVNQkVSID0gMzsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzIzXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyMygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8zID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyMygpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzIzXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl80X0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyNF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl80ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDMyNF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UMzJfNjNfRklFTERfTlVNQkVSID0gNjM7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyNjNfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzI2MygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI2My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyNjMoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDMyNjNfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyXzY0X0ZJRUxEX05VTUJFUiA9IDY0OwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjY0XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjY0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9BTExfVFlQRVNfRklFTERfTlVNQkVSID0gOTsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgb3B0aW9uYWxBbGxUeXBlc187CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQWxsVHlwZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEFsbFR5cGVzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0T3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsQWxsVHlwZXNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0T3B0aW9uYWxBbGxUeXBlc09yQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsQWxsVHlwZXNfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0FMTF9UWVBFU19GSUVMRF9OVU1CRVIgPSAxMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gcmVwZWF0ZWRBbGxUeXBlc187CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEFsbFR5cGVzQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0UmVwZWF0ZWRBbGxUeXBlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLmdldChpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxLCBvcHRpb25hbEludDMyMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIG9wdGlvbmFsSW50MzIyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMywgb3B0aW9uYWxJbnQzMjNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig0LCBvcHRpb25hbEludDMyNF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoOSwgZ2V0T3B0aW9uYWxBbGxUeXBlcygpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxMCwgcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgzMCwgb3B0aW9uYWxJbnQ2NDMwXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNjMsIG9wdGlvbmFsSW50MzI2M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDY0LCBvcHRpb25hbEludDMyNjRfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBvcHRpb25hbEludDMyMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMiwgb3B0aW9uYWxJbnQzMjJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDMsIG9wdGlvbmFsSW50MzIzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg0LCBvcHRpb25hbEludDMyNF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5LCBnZXRPcHRpb25hbEFsbFR5cGVzKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRBbGxUeXBlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTAsIHJlcGVhdGVkQWxsVHlwZXNfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSgzMCwgb3B0aW9uYWxJbnQ2NDMwXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg2Mywgb3B0aW9uYWxJbnQzMjYzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg2NCwgb3B0aW9uYWxJbnQzMjY0Xyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyKSBvYmo7CgogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQ2NDMwKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQ2NDMwKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50NjQzMCgpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50NjQzMCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50NjQzMCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIxKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMjEoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjEoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMyMSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzIxKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjIoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDMyMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMigpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50MzIyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMygpICE9IG90aGVyLmhhc09wdGlvbmFsSW50MzIzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIzKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMjMoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDMyMygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI0KCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjQoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMyNCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzI0KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjYzKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMjYzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2MygpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50MzI2MygpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzI2MygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2NCgpICE9IG90aGVyLmhhc09wdGlvbmFsSW50MzI2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyNjQoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMyNjQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDMyNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEFsbFR5cGVzKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxBbGxUeXBlcygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEFsbFR5cGVzKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsQWxsVHlwZXMoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsQWxsVHlwZXMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQ2NDMwKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQ2NF8zMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0T3B0aW9uYWxJbnQ2NDMwKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjEoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lOVDMyXzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzIyKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl8zX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEludDMyMygpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyNCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfNF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjQoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjYzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl82M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjYzKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzI2NCgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEFsbFR5cGVzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9BTExfVFlQRVNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsQWxsVHlwZXMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEFsbFR5cGVzQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9BTExfVFlQRVNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMiBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMiBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5TW9zdGx5SW50MzJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5TW9zdGx5SW50MzIpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU1vc3RseUludDMyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlNb3N0bHlJbnQzMl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMi5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRPcHRpb25hbEFsbFR5cGVzRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbEludDY0MzBfID0gMEw7CiAgICAgICAgb3B0aW9uYWxJbnQzMjFfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyMl8gPSAwOwogICAgICAgIG9wdGlvbmFsSW50MzIzXyA9IDA7CiAgICAgICAgb3B0aW9uYWxJbnQzMjRfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyNjNfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyNjRfID0gMDsKICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU1vc3RseUludDMyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMiBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIodGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIgcmVzdWx0KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEFsbFR5cGVzXyA9IHJlcGVhdGVkQWxsVHlwZXNfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRBbGxUeXBlc18gPSByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50NjQzMF8gPSBvcHRpb25hbEludDY0MzBfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzIxXyA9IG9wdGlvbmFsSW50MzIxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyMl8gPSBvcHRpb25hbEludDMyMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMjNfID0gb3B0aW9uYWxJbnQzMjNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzI0XyA9IG9wdGlvbmFsSW50MzI0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyNjNfID0gb3B0aW9uYWxJbnQzMjYzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyNjRfID0gb3B0aW9uYWxJbnQzMjY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEFsbFR5cGVzXyA9IG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbEFsbFR5cGVzXwogICAgICAgICAgICAgIDogb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDY0MzAoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQ2NDMwKG90aGVyLmdldE9wdGlvbmFsSW50NjQzMCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50MzIxKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzIxKG90aGVyLmdldE9wdGlvbmFsSW50MzIxKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQzMjIoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQzMjIob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyMygpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyMyhvdGhlci5nZXRPcHRpb25hbEludDMyMygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50MzI0KCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzI0KG90aGVyLmdldE9wdGlvbmFsSW50MzI0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQzMjYzKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzI2MyhvdGhlci5nZXRPcHRpb25hbEludDMyNjMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyNjQoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQzMjY0KG90aGVyLmdldE9wdGlvbmFsSW50MzI2NCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsQWxsVHlwZXMoKSkgewogICAgICAgICAgbWVyZ2VPcHRpb25hbEFsbFR5cGVzKG90aGVyLmdldE9wdGlvbmFsQWxsVHlwZXMoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEFsbFR5cGVzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gb3RoZXIucmVwZWF0ZWRBbGxUeXBlc187CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQWxsVHlwZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IG90aGVyLnJlcGVhdGVkQWxsVHlwZXNfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMgPwogICAgICAgICAgICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpIDogbnVsbDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIucmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQzMjFfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzIyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQzMjNfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQKICAgICAgICAgICAgICBjYXNlIDMyOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyNF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMgogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBjYXNlIDI0MDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQ2NDMwXyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0MAogICAgICAgICAgICAgIGNhc2UgNTA0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyNjNfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTA0CiAgICAgICAgICAgICAgY2FzZSA1MTI6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzI2NF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MTIKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsSW50NjQzMF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQ2NDMwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQ2NDMwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjQzMC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxJbnQ2NDMwKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDY0MzBfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF8zMCA9IDMwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDY0MzAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDY0MzAobG9uZyB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDY0MzBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF8zMCA9IDMwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEludDY0MzAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9wdGlvbmFsSW50NjQzMF8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjFfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyMSgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQzMjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyMShpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMjEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9wdGlvbmFsSW50MzIxXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzIyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzIyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMjIoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzIyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvcHRpb25hbEludDMyMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyM18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8zID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIzKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDMyM187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzMgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50MzIzKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDMyM18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEludDMyMygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb3B0aW9uYWxJbnQzMjNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyNCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzI0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyNCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl80ID0gNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQzMjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyNChpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl80ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9wdGlvbmFsSW50MzI0XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI2M18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjYzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjYzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI2My4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyNjMoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI2M187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzI2MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50MzI2MyhpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMjYzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMjYzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvcHRpb25hbEludDMyNjNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjY0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjY0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzI2NCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQzMjY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMjY0KGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDMyNjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEludDMyNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9wdGlvbmFsSW50MzI2NF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG9wdGlvbmFsQWxsVHlwZXNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBbGxUeXBlcyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxBbGxUeXBlcy4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsQWxsVHlwZXNfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEFsbFR5cGVzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxBbGxUeXBlcygKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxBbGxUeXBlcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0J1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldE9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsQWxsVHlwZXNfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbEFsbFR5cGVzRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlcygpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiByZXBlYXRlZEFsbFR5cGVzXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPihyZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRBbGxUeXBlc0NvdW50KCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0UmVwZWF0ZWRBbGxUeXBlcyhpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEFsbFR5cGVzKCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkQWxsVHlwZXMoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeU1vc3RseUludDMyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5TW9zdGx5SW50MzIpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMiBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VmVyaWZ5TW9zdGx5SW50MzI+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFZlcmlmeU1vc3RseUludDMyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdFZlcmlmeU1vc3RseUludDMyIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFZlcmlmeU1vc3RseUludDMyPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RWZXJpZnlNb3N0bHlJbnQzMj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlck9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlcikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzMwID0gMzA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDY0MzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50NjQzMCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF8zMCA9IDMwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjQzMC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbEludDY0MzAoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzMwMCA9IDMwMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIzMDAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzIzMDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMzAwID0gMzAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIzMDAuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyMzAwKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMS4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzIxKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzIyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8zID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyMygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8zID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMy4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzIzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl80ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl80ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNC4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzI0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjMuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyNjMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzI2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI2NC4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzI2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBbGxUeXBlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxBbGxUeXBlcygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxBbGxUeXBlcy4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0T3B0aW9uYWxBbGxUeXBlcygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IAogICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRBbGxUeXBlc0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIpCiAgICAgIFRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlci5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlcihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyKCkgewogICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQ2NF8zMF9GSUVMRF9OVU1CRVIgPSAzMDsKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbEludDY0MzBfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzMwID0gMzA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDY0MzAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDY0MzAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfMzAgPSAzMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDY0MzAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjQzMCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50NjQzMF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UMzJfMzAwX0ZJRUxEX05VTUJFUiA9IDMwMDsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzIzMDBfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMzAwID0gMzAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjMwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIzMDAoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMzAwID0gMzAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIzMDAuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjMwMCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzIzMDBfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyXzFfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzIxXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyMSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzIxXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl8yX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDMyMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UMzJfM19GSUVMRF9OVU1CRVIgPSAzOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjNfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzMgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjNfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyXzRfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI0XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl80ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyNCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI0XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl82M19GSUVMRF9OVU1CRVIgPSA2MzsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI2M18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjYzKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjYzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzI2MygpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI2M187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UMzJfNjRfRklFTERfTlVNQkVSID0gNjQ7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyNjRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzI2NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyNjQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDMyNjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0FMTF9UWVBFU19GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBvcHRpb25hbEFsbFR5cGVzXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBbGxUeXBlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIG9wdGlvbmFsSW50MzIxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMiwgb3B0aW9uYWxJbnQzMjJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigzLCBvcHRpb25hbEludDMyM18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDQsIG9wdGlvbmFsSW50MzI0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg5LCBnZXRPcHRpb25hbEFsbFR5cGVzKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRBbGxUeXBlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEwLCByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDMwLCBvcHRpb25hbEludDY0MzBfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig2Mywgb3B0aW9uYWxJbnQzMjYzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNjQsIG9wdGlvbmFsSW50MzI2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDMwMCwgb3B0aW9uYWxJbnQzMjMwMF8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIG9wdGlvbmFsSW50MzIxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgyLCBvcHRpb25hbEludDMyMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMywgb3B0aW9uYWxJbnQzMjNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDQsIG9wdGlvbmFsSW50MzI0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDksIGdldE9wdGlvbmFsQWxsVHlwZXMoKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEFsbFR5cGVzXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplKDMwLCBvcHRpb25hbEludDY0MzBfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDYzLCBvcHRpb25hbEludDMyNjNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDY0LCBvcHRpb25hbEludDMyNjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDMwMCwgb3B0aW9uYWxJbnQzMjMwMF8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlcikgb2JqOwoKICAgICAgaWYgKGhhc09wdGlvbmFsSW50NjQzMCgpICE9IG90aGVyLmhhc09wdGlvbmFsSW50NjQzMCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDY0MzAoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDY0MzAoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDY0MzAoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMzAwKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMjMwMCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMzAwKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMjMwMCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzIzMDAoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMSgpICE9IG90aGVyLmhhc09wdGlvbmFsSW50MzIxKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIxKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMjEoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDMyMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIyKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMjIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjIoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMyMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzIyKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjMoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDMyMygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMygpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50MzIzKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjMoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyNCgpICE9IG90aGVyLmhhc09wdGlvbmFsSW50MzI0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI0KCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMjQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDMyNCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2MygpICE9IG90aGVyLmhhc09wdGlvbmFsSW50MzI2MygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyNjMoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMyNjMoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDMyNjMoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyNjQoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDMyNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjY0KCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMjY0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxBbGxUeXBlcygpICE9IG90aGVyLmhhc09wdGlvbmFsQWxsVHlwZXMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxBbGxUeXBlcygpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbEFsbFR5cGVzKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEFsbFR5cGVzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50NjQzMCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UNjRfMzBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldE9wdGlvbmFsSW50NjQzMCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjMwMCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfMzAwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEludDMyMzAwKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIxKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl8xX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEludDMyMSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjIoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lOVDMyXzNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzIzKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl80X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEludDMyNCgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyNjMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lOVDMyXzYzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEludDMyNjMoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjY0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl82NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjY0KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsQWxsVHlwZXMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0FMTF9UWVBFU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxBbGxUeXBlcygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0FMTF9UWVBFU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlcikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIG9wdGlvbmFsSW50NjQzMF8gPSAwTDsKICAgICAgICBvcHRpb25hbEludDMyMzAwXyA9IDA7CiAgICAgICAgb3B0aW9uYWxJbnQzMjFfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyMl8gPSAwOwogICAgICAgIG9wdGlvbmFsSW50MzIzXyA9IDA7CiAgICAgICAgb3B0aW9uYWxJbnQzMjRfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyNjNfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyNjRfID0gMDsKICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgcmVzdWx0KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEFsbFR5cGVzXyA9IHJlcGVhdGVkQWxsVHlwZXNfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRBbGxUeXBlc18gPSByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQ2NDMwXyA9IG9wdGlvbmFsSW50NjQzMF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMjMwMF8gPSBvcHRpb25hbEludDMyMzAwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyMV8gPSBvcHRpb25hbEludDMyMV87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMjJfID0gb3B0aW9uYWxJbnQzMjJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzIzXyA9IG9wdGlvbmFsSW50MzIzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyNF8gPSBvcHRpb25hbEludDMyNF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMjYzXyA9IG9wdGlvbmFsSW50MzI2M187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMjY0XyA9IG9wdGlvbmFsSW50MzI2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxBbGxUeXBlc18gPSBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxBbGxUeXBlc18KICAgICAgICAgICAgICA6IG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlcikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlcilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDY0MzAoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQ2NDMwKG90aGVyLmdldE9wdGlvbmFsSW50NjQzMCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50MzIzMDAoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQzMjMwMChvdGhlci5nZXRPcHRpb25hbEludDMyMzAwKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQzMjEoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQzMjEob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyMigpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyMihvdGhlci5nZXRPcHRpb25hbEludDMyMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50MzIzKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzIzKG90aGVyLmdldE9wdGlvbmFsSW50MzIzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQzMjQoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQzMjQob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyNjMoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQzMjYzKG90aGVyLmdldE9wdGlvbmFsSW50MzI2MygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50MzI2NCgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyNjQob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxBbGxUeXBlcygpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsQWxsVHlwZXMob3RoZXIuZ2V0T3B0aW9uYWxBbGxUeXBlcygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQWxsVHlwZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBvdGhlci5yZXBlYXRlZEFsbFR5cGVzXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZEFsbChvdGhlci5yZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRBbGxUeXBlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gb3RoZXIucmVwZWF0ZWRBbGxUeXBlc187CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyMV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQzMjJfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyM18gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgMzI6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzI0XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDMyCiAgICAgICAgICAgICAgY2FzZSA3NDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgICBjYXNlIDgyOiB7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgIGNhc2UgMjQwOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDY0MzBfID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQwCiAgICAgICAgICAgICAgY2FzZSA1MDQ6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzI2M18gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MDQKICAgICAgICAgICAgICBjYXNlIDUxMjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQzMjY0XyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUxMgogICAgICAgICAgICAgIGNhc2UgMjQwMDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQzMjMwMF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNDAwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbEludDY0MzBfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzMwID0gMzA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50NjQzMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50NjQzMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzMwID0gMzA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDY0MzAuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjQzMCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQ2NDMwXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQ2NDMwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQ2NDMwKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQ2NDMwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQ2NDMwKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvcHRpb25hbEludDY0MzBfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzIzMDBfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzMwMCA9IDMwMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjMwMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIzMDAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8zMDAgPSAzMDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMzAwLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIzMDAoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzIzMDBfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8zMDAgPSAzMDA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzIzMDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyMzAwKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDMyMzAwXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMzAwID0gMzAwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEludDMyMzAwKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvcHRpb25hbEludDMyMzAwXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzIxXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjEoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzIxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMjEoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzIxKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvcHRpb25hbEludDMyMV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDMyMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50MzIyKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDMyMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEludDMyMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb3B0aW9uYWxJbnQzMjJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMy4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyMygpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8zID0gMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQzMjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyMyhpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8zID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMjMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9wdGlvbmFsSW50MzIzXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl80ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzI0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMjQoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzI0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzI0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvcHRpb25hbEludDMyNF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyNjNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzI2MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjYzKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDMyNjNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyNjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyNjMoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzI2M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzI2MygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb3B0aW9uYWxJbnQzMjYzXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyNjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzI2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50MzI2NChpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMjY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMjY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvcHRpb25hbEludDMyNjRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQWxsVHlwZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0T3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxBbGxUeXBlcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQWxsVHlwZXMoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc18gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0T3B0aW9uYWxBbGxUeXBlc09yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXMoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gcmVwZWF0ZWRBbGxUeXBlc18gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4ocmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQWxsVHlwZXMoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRBbGxUeXBlcygpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlcikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlciBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RWZXJpZnlNb3N0bHlJbnQzMkJpZ0ZpZWxkTnVtYmVyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlcj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlcj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RWZXJpZnlVaW50MzJTaW1wbGVPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeVVpbnQzMlNpbXBsZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyMS4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsVWludDMyMSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzIyKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIyLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxVaW50MzIyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjYzLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxVaW50MzI2MygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzI2NCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI2NC4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsVWludDMyNjQoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeVVpbnQzMlNpbXBsZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RWZXJpZnlVaW50MzJTaW1wbGUgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeVVpbnQzMlNpbXBsZSkKICAgICAgVGVzdFZlcmlmeVVpbnQzMlNpbXBsZU9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFZlcmlmeVVpbnQzMlNpbXBsZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0VmVyaWZ5VWludDMyU2ltcGxlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFZlcmlmeVVpbnQzMlNpbXBsZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0VmVyaWZ5VWludDMyU2ltcGxlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeVVpbnQzMlNpbXBsZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlVaW50MzJTaW1wbGVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMlNpbXBsZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfVUlOVDMyXzFfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyMV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzIxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyMSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyMV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfVUlOVDMyXzJfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyMl8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzIyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyMigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfVUlOVDMyXzYzX0ZJRUxEX05VTUJFUiA9IDYzOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzI2M18gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjYzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzI2MygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI2My4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjYzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxVaW50MzI2M187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfVUlOVDMyXzY0X0ZJRUxEX05VTUJFUiA9IDY0OwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzI2NF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzI2NCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI2NC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjY0KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxVaW50MzI2NF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoMSwgb3B0aW9uYWxVaW50MzIxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKDIsIG9wdGlvbmFsVWludDMyMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMig2Mywgb3B0aW9uYWxVaW50MzI2M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMig2NCwgb3B0aW9uYWxVaW50MzI2NF8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSgxLCBvcHRpb25hbFVpbnQzMjFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSgyLCBvcHRpb25hbFVpbnQzMjJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSg2Mywgb3B0aW9uYWxVaW50MzI2M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKDY0LCBvcHRpb25hbFVpbnQzMjY0Xyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyU2ltcGxlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyU2ltcGxlKSBvYmo7CgogICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIxKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVaW50MzIxKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyMSgpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsVWludDMyMSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyMigpICE9IG90aGVyLmhhc09wdGlvbmFsVWludDMyMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjIoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQzMjIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFVpbnQzMjIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjYzKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVaW50MzI2MygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjYzKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxVaW50MzI2MygpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyNjMoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjY0KCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVaW50MzI2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjY0KCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxVaW50MzI2NCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDMyXzFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsVWludDMyMSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1VJTlQzMl8yX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFVpbnQzMjIoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzI2MygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDMyXzYzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFVpbnQzMjYzKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1VJTlQzMl82NF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxVaW50MzI2NCgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyU2ltcGxlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyU2ltcGxlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyU2ltcGxlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMlNpbXBsZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMlNpbXBsZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyU2ltcGxlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyU2ltcGxlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMlNpbXBsZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5VWludDMyU2ltcGxlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeVVpbnQzMlNpbXBsZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGVPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeVVpbnQzMlNpbXBsZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5VWludDMyU2ltcGxlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMlNpbXBsZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyU2ltcGxlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyU2ltcGxlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbFVpbnQzMjFfID0gMDsKICAgICAgICBvcHRpb25hbFVpbnQzMjJfID0gMDsKICAgICAgICBvcHRpb25hbFVpbnQzMjYzXyA9IDA7CiAgICAgICAgb3B0aW9uYWxVaW50MzI2NF8gPSAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5VWludDMyU2ltcGxlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMlNpbXBsZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMlNpbXBsZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMlNpbXBsZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyU2ltcGxlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMlNpbXBsZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMjFfID0gb3B0aW9uYWxVaW50MzIxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMjJfID0gb3B0aW9uYWxVaW50MzIyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMjYzXyA9IG9wdGlvbmFsVWludDMyNjNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVWludDMyNjRfID0gb3B0aW9uYWxVaW50MzI2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMlNpbXBsZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyU2ltcGxlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxVaW50MzIxKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsVWludDMyMShvdGhlci5nZXRPcHRpb25hbFVpbnQzMjEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFVpbnQzMjIoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxVaW50MzIyKG90aGVyLmdldE9wdGlvbmFsVWludDMyMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsVWludDMyNjMoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxVaW50MzI2MyhvdGhlci5nZXRPcHRpb25hbFVpbnQzMjYzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxVaW50MzI2NCgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFVpbnQzMjY0KG90aGVyLmdldE9wdGlvbmFsVWludDMyNjQoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgb3B0aW9uYWxVaW50MzIxXyA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxVaW50MzIyXyA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgNTA0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFVpbnQzMjYzXyA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MDQKICAgICAgICAgICAgICBjYXNlIDUxMjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxVaW50MzI2NF8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTEyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyMV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzIxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyMS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjEoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsVWludDMyMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVWludDMyMShpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxVaW50MzIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50MzIxKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvcHRpb25hbFVpbnQzMjFfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzIyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyMigpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxVaW50MzIyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxVaW50MzIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzIyKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbFVpbnQzMjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFVpbnQzMjIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9wdGlvbmFsVWludDMyMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjYzXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyNjMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjYzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI2My4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjYzKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjYzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFVpbnQzMjYzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzI2MyhpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxVaW50MzI2M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50MzI2MygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb3B0aW9uYWxVaW50MzI2M18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjY0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjY0KCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFVpbnQzMjY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzI2NChpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxVaW50MzI2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50MzI2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb3B0aW9uYWxVaW50MzI2NF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlVaW50MzJTaW1wbGUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlVaW50MzJTaW1wbGUpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyU2ltcGxlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VmVyaWZ5VWludDMyU2ltcGxlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RWZXJpZnlVaW50MzJTaW1wbGU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0VmVyaWZ5VWludDMyU2ltcGxlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFZlcmlmeVVpbnQzMlNpbXBsZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VmVyaWZ5VWludDMyU2ltcGxlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJTaW1wbGUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0VmVyaWZ5VWludDMyT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlVaW50MzIpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjEuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbFVpbnQzMjEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsVWludDMyMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzI2MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI2My4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsVWludDMyNjMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjQuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbFVpbnQzMjY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEFsbFR5cGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEFsbFR5cGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEFsbFR5cGVzLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRPcHRpb25hbEFsbFR5cGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldE9wdGlvbmFsQWxsVHlwZXNPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gCiAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQWxsVHlwZXMoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEFsbFR5cGVzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeVVpbnQzMn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RWZXJpZnlVaW50MzIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeVVpbnQzMikKICAgICAgVGVzdFZlcmlmeVVpbnQzMk9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFZlcmlmeVVpbnQzMi5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0VmVyaWZ5VWludDMyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFZlcmlmeVVpbnQzMigpIHsKICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFZlcmlmeVVpbnQzMigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlVaW50MzJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5VWludDMyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VJTlQzMl8xX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjFfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjEoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VJTlQzMl8yX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VJTlQzMl82M19GSUVMRF9OVU1CRVIgPSA2MzsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyNjNfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzI2MygpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyNjNfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VJTlQzMl82NF9GSUVMRF9OVU1CRVIgPSA2NDsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyNjRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzI2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyNjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0FMTF9UWVBFU19GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBvcHRpb25hbEFsbFR5cGVzXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBbGxUeXBlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigxLCBvcHRpb25hbFVpbnQzMjFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoMiwgb3B0aW9uYWxVaW50MzIyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg5LCBnZXRPcHRpb25hbEFsbFR5cGVzKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRBbGxUeXBlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEwLCByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMig2Mywgb3B0aW9uYWxVaW50MzI2M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMig2NCwgb3B0aW9uYWxVaW50MzI2NF8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSgxLCBvcHRpb25hbFVpbnQzMjFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSgyLCBvcHRpb25hbFVpbnQzMjJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOSwgZ2V0T3B0aW9uYWxBbGxUeXBlcygpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwLCByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKDYzLCBvcHRpb25hbFVpbnQzMjYzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoNjQsIG9wdGlvbmFsVWludDMyNjRfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMiBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIpIG9iajsKCiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjEoKSAhPSBvdGhlci5oYXNPcHRpb25hbFVpbnQzMjEoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIxKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxVaW50MzIxKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxVaW50MzIxKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIyKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVaW50MzIyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyMigpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsVWludDMyMigpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjMoKSAhPSBvdGhlci5oYXNPcHRpb25hbFVpbnQzMjYzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjMoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQzMjYzKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxVaW50MzI2MygpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjQoKSAhPSBvdGhlci5oYXNPcHRpb25hbFVpbnQzMjY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjQoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQzMjY0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxVaW50MzI2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsQWxsVHlwZXMoKSAhPSBvdGhlci5oYXNPcHRpb25hbEFsbFR5cGVzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsQWxsVHlwZXMoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxBbGxUeXBlcygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxBbGxUeXBlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjEoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1VJTlQzMl8xX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFVpbnQzMjEoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9VSU5UMzJfMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxVaW50MzIyKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1VJTlQzMl82M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxVaW50MzI2MygpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjY0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9VSU5UMzJfNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsVWludDMyNjQoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxBbGxUeXBlcygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEFsbFR5cGVzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRBbGxUeXBlc0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlVaW50MzJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5VWludDMyKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMk9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5VWludDMyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlVaW50MzJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgb3B0aW9uYWxVaW50MzIxXyA9IDA7CiAgICAgICAgb3B0aW9uYWxVaW50MzIyXyA9IDA7CiAgICAgICAgb3B0aW9uYWxVaW50MzI2M18gPSAwOwogICAgICAgIG9wdGlvbmFsVWludDMyNjRfID0gMDsKICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeVVpbnQzMl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMih0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIgcmVzdWx0KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEFsbFR5cGVzXyA9IHJlcGVhdGVkQWxsVHlwZXNfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRBbGxUeXBlc18gPSByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMiByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMjFfID0gb3B0aW9uYWxVaW50MzIxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMjJfID0gb3B0aW9uYWxVaW50MzIyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMjYzXyA9IG9wdGlvbmFsVWludDMyNjNfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVWludDMyNjRfID0gb3B0aW9uYWxVaW50MzI2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxBbGxUeXBlc18gPSBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxBbGxUeXBlc18KICAgICAgICAgICAgICA6IG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMi5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsVWludDMyMSgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFVpbnQzMjEob3RoZXIuZ2V0T3B0aW9uYWxVaW50MzIxKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxVaW50MzIyKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsVWludDMyMihvdGhlci5nZXRPcHRpb25hbFVpbnQzMjIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFVpbnQzMjYzKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsVWludDMyNjMob3RoZXIuZ2V0T3B0aW9uYWxVaW50MzI2MygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsVWludDMyNjQoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxVaW50MzI2NChvdGhlci5nZXRPcHRpb25hbFVpbnQzMjY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxBbGxUeXBlcygpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsQWxsVHlwZXMob3RoZXIuZ2V0T3B0aW9uYWxBbGxUeXBlcygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQWxsVHlwZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBvdGhlci5yZXBlYXRlZEFsbFR5cGVzXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZEFsbChvdGhlci5yZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRBbGxUeXBlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gb3RoZXIucmVwZWF0ZWRBbGxUeXBlc187CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFVpbnQzMjFfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFVpbnQzMjJfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSA3NDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgICBjYXNlIDgyOiB7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgIGNhc2UgNTA0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFVpbnQzMjYzXyA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MDQKICAgICAgICAgICAgICBjYXNlIDUxMjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxVaW50MzI2NF8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTEyCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyMV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIxIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzIxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyMS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjEoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsVWludDMyMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVWludDMyMShpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxVaW50MzIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50MzIxKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvcHRpb25hbFVpbnQzMjFfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzIyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyMigpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxVaW50MzIyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxVaW50MzIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzIyKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbFVpbnQzMjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFVpbnQzMjIoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9wdGlvbmFsVWludDMyMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjYzXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyNjMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjYzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI2My4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjYzKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjYzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFVpbnQzMjYzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzI2MyhpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxVaW50MzI2M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50MzI2MygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb3B0aW9uYWxVaW50MzI2M18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjY0XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjY0KCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFVpbnQzMjY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzI2NChpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxVaW50MzI2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50MzI2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb3B0aW9uYWxVaW50MzI2NF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG9wdGlvbmFsQWxsVHlwZXNfOwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBbGxUeXBlcyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxBbGxUeXBlcy4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsQWxsVHlwZXNfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEFsbFR5cGVzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gdmFsdWU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxBbGxUeXBlcygKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlT3B0aW9uYWxBbGxUeXBlcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0J1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldE9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsQWxsVHlwZXNfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbEFsbFR5cGVzRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlcygpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiByZXBlYXRlZEFsbFR5cGVzXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPihyZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXzsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRBbGxUeXBlc0NvdW50KCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0UmVwZWF0ZWRBbGxUeXBlcyhpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEFsbFR5cGVzKCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHJlbW92ZVJlcGVhdGVkQWxsVHlwZXMoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcihpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzQnVpbGRlcigpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl87CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeVVpbnQzMikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeVVpbnQzMikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMiBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMiBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RWZXJpZnlVaW50MzI+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFZlcmlmeVVpbnQzMj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RWZXJpZnlVaW50MzIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VmVyaWZ5VWludDMyPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RWZXJpZnlVaW50MzI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RWZXJpZnlPbmVVaW50MzJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeU9uZVVpbnQzMikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyMS4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsVWludDMyMSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjYzLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxJbnQzMjYzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjQuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyNjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQWxsVHlwZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsQWxsVHlwZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE9wdGlvbmFsQWxsVHlwZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0T3B0aW9uYWxBbGxUeXBlc09yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiAKICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0UmVwZWF0ZWRBbGxUeXBlcyhpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5T25lVWludDMyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFZlcmlmeU9uZVVpbnQzMiBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5T25lVWludDMyKQogICAgICBUZXN0VmVyaWZ5T25lVWludDMyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0VmVyaWZ5T25lVWludDMyLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RWZXJpZnlPbmVVaW50MzIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0VmVyaWZ5T25lVWludDMyKCkgewogICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0VmVyaWZ5T25lVWludDMyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU9uZVVpbnQzMl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlPbmVVaW50MzJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVVaW50MzIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfVUlOVDMyXzFfRklFTERfTlVNQkVSID0gMTsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyMV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzIxKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIxLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyMSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyMV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UMzJfMl9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyXzYzX0ZJRUxEX05VTUJFUiA9IDYzOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjYzXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyNjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjYzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjYzXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl82NF9GSUVMRF9OVU1CRVIgPSA2NDsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI2NF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjY0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzI2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG9wdGlvbmFsQWxsVHlwZXNfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEFsbFR5cGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxBbGxUeXBlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE9wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldE9wdGlvbmFsQWxsVHlwZXNPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9BTExfVFlQRVNfRklFTERfTlVNQkVSID0gMTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IHJlcGVhdGVkQWxsVHlwZXNfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRBbGxUeXBlc0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQWxsVHlwZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKDEsIG9wdGlvbmFsVWludDMyMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIG9wdGlvbmFsSW50MzIyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg5LCBnZXRPcHRpb25hbEFsbFR5cGVzKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRBbGxUeXBlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEwLCByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDYzLCBvcHRpb25hbEludDMyNjNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig2NCwgb3B0aW9uYWxJbnQzMjY0Xyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKDEsIG9wdGlvbmFsVWludDMyMV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMiwgb3B0aW9uYWxJbnQzMjJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOSwgZ2V0T3B0aW9uYWxBbGxUeXBlcygpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwLCByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNjMsIG9wdGlvbmFsSW50MzI2M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoNjQsIG9wdGlvbmFsSW50MzI2NF8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lVWludDMyIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMikgb2JqOwoKICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyMSgpICE9IG90aGVyLmhhc09wdGlvbmFsVWludDMyMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjEoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQzMjEoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFVpbnQzMjEoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMigpICE9IG90aGVyLmhhc09wdGlvbmFsSW50MzIyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIyKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMjIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDMyMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2MygpICE9IG90aGVyLmhhc09wdGlvbmFsSW50MzI2MygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyNjMoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMyNjMoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDMyNjMoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyNjQoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDMyNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjY0KCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMjY0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxBbGxUeXBlcygpICE9IG90aGVyLmhhc09wdGlvbmFsQWxsVHlwZXMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxBbGxUeXBlcygpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbEFsbFR5cGVzKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEFsbFR5cGVzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyMSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDMyXzFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsVWludDMyMSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjIoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjYzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl82M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjYzKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzI2NCgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEFsbFR5cGVzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9BTExfVFlQRVNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsQWxsVHlwZXMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEFsbFR5cGVzQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9BTExfVFlQRVNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lVWludDMyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lVWludDMyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lVWludDMyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMiBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVVaW50MzIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lVWludDMyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lVWludDMyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVVaW50MzIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVVaW50MzIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeU9uZVVpbnQzMn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlPbmVVaW50MzIpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lVWludDMyT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlPbmVVaW50MzJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU9uZVVpbnQzMl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVVaW50MzIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMi5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMi5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRPcHRpb25hbEFsbFR5cGVzRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbFVpbnQzMjFfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyMl8gPSAwOwogICAgICAgIG9wdGlvbmFsSW50MzI2M18gPSAwOwogICAgICAgIG9wdGlvbmFsSW50MzI2NF8gPSAwOwogICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5T25lVWludDMyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMiBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVVaW50MzIuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMiBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVVaW50MzIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVVaW50MzIgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lVWludDMyKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMiByZXN1bHQpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgICAgfQogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQWxsVHlwZXNfID0gcmVwZWF0ZWRBbGxUeXBlc187CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEFsbFR5cGVzXyA9IHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5idWlsZCgpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lVWludDMyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVWludDMyMV8gPSBvcHRpb25hbFVpbnQzMjFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzIyXyA9IG9wdGlvbmFsSW50MzIyXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyNjNfID0gb3B0aW9uYWxJbnQzMjYzXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyNjRfID0gb3B0aW9uYWxJbnQzMjY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEFsbFR5cGVzXyA9IG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbEFsbFR5cGVzXwogICAgICAgICAgICAgIDogb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVVaW50MzIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVVaW50MzIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lVWludDMyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxVaW50MzIxKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsVWludDMyMShvdGhlci5nZXRPcHRpb25hbFVpbnQzMjEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyMigpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyMihvdGhlci5nZXRPcHRpb25hbEludDMyMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50MzI2MygpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyNjMob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjYzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQzMjY0KCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzI2NChvdGhlci5nZXRPcHRpb25hbEludDMyNjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEFsbFR5cGVzKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxBbGxUeXBlcyhvdGhlci5nZXRPcHRpb25hbEFsbFR5cGVzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRBbGxUeXBlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IG90aGVyLnJlcGVhdGVkQWxsVHlwZXNfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkQWxsKG90aGVyLnJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEFsbFR5cGVzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBvdGhlci5yZXBlYXRlZEFsbFR5cGVzXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsVWludDMyMV8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzIyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSA3NDogewogICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNzQKICAgICAgICAgICAgICBjYXNlIDgyOiB7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgIGNhc2UgNTA0OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyNjNfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTA0CiAgICAgICAgICAgICAgY2FzZSA1MTI6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzI2NF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MTIKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzIxXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjEoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIxLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyMSgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxVaW50MzIxXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxVaW50MzIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzIxKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbFVpbnQzMjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFVpbnQzMjEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9wdGlvbmFsVWludDMyMV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjIoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDMyMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50MzIyKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDMyMl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEludDMyMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb3B0aW9uYWxJbnQzMjJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjYzXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyNjMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjYzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzI2MygpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjYzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQzMjYzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMjYzKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDMyNjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEludDMyNjMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9wdGlvbmFsSW50MzI2M18gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyNjRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzI2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjY0KCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDMyNjRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyNjQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyNjQoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzI2NF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzI2NCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb3B0aW9uYWxJbnQzMjY0XyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgb3B0aW9uYWxBbGxUeXBlc187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEFsbFR5cGVzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEFsbFR5cGVzLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE9wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEFsbFR5cGVzKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbEFsbFR5cGVzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbEFsbFR5cGVzQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0T3B0aW9uYWxBbGxUeXBlc0J1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldE9wdGlvbmFsQWxsVHlwZXNPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEFsbFR5cGVzKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IHJlcGVhdGVkQWxsVHlwZXNfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+KHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEFsbFR5cGVzQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IHZhbHVlcykgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQWxsVHlwZXMoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRBbGxUeXBlcyhpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldFJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5T25lVWludDMyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5T25lVWludDMyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lVWludDMyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZVVpbnQzMigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lVWludDMyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFZlcmlmeU9uZVVpbnQzMj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0VmVyaWZ5T25lVWludDMyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdFZlcmlmeU9uZVVpbnQzMiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RWZXJpZnlPbmVVaW50MzI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFZlcmlmeU9uZVVpbnQzMj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lVWludDMyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NSA9IDY1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjY1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjUuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyNjUoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQ2NDEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50NjQxKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjQxLgogICAgICovCiAgICBsb25nIGdldE9wdGlvbmFsSW50NjQxKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50NjQyIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDY0MigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDY0Mi4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbEludDY0MigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50NjQ2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQ2NDYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NDYzLgogICAgICovCiAgICBsb25nIGdldE9wdGlvbmFsSW50NjQ2MygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50NjQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQ2NDY0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NDY0LgogICAgICovCiAgICBsb25nIGdldE9wdGlvbmFsSW50NjQ2NCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBbGxUeXBlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxBbGxUeXBlcygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxBbGxUeXBlcy4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0T3B0aW9uYWxBbGxUeXBlcygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IAogICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRBbGxUeXBlc0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIpCiAgICAgIFRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlci5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlcihjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIFRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyKCkgewogICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl82NV9GSUVMRF9OVU1CRVIgPSA2NTsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI2NV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NSA9IDY1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjY1IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjY1KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjY1LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzI2NSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI2NV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UNjRfMV9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsSW50NjQxXyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50NjQxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQ2NDEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NDEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjQxKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQ2NDFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDY0XzJfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbEludDY0Ml8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDY0MiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50NjQyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjQyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbEludDY0MigpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50NjQyXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQ2NF82M19GSUVMRF9OVU1CRVIgPSA2MzsKICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbEludDY0NjNfID0gMEw7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDY0NjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDY0NjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDY0NjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjQ2MygpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50NjQ2M187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UNjRfNjRfRklFTERfTlVNQkVSID0gNjQ7CiAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxJbnQ2NDY0XyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQ2NDY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQ2NDY0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NDY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbEludDY0NjQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDY0NjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0FMTF9UWVBFU19GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBvcHRpb25hbEFsbFR5cGVzXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBbGxUeXBlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDEsIG9wdGlvbmFsSW50NjQxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMiwgb3B0aW9uYWxJbnQ2NDJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDksIGdldE9wdGlvbmFsQWxsVHlwZXMoKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEFsbFR5cGVzXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMTAsIHJlcGVhdGVkQWxsVHlwZXNfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoNjMsIG9wdGlvbmFsSW50NjQ2M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDY0LCBvcHRpb25hbEludDY0NjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig2NSwgb3B0aW9uYWxJbnQzMjY1Xyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemUoMSwgb3B0aW9uYWxJbnQ2NDFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplKDIsIG9wdGlvbmFsSW50NjQyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDksIGdldE9wdGlvbmFsQWxsVHlwZXMoKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEFsbFR5cGVzXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplKDYzLCBvcHRpb25hbEludDY0NjNfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplKDY0LCBvcHRpb25hbEludDY0NjRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDY1LCBvcHRpb25hbEludDMyNjVfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIpIG9iajsKCiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyNjUoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDMyNjUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjY1KCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMjY1KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjY1KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQ2NDEoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDY0MSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDY0MSgpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50NjQxKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQ2NDEoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDY0MigpICE9IG90aGVyLmhhc09wdGlvbmFsSW50NjQyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50NjQyKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQ2NDIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDY0MigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50NjQ2MygpICE9IG90aGVyLmhhc09wdGlvbmFsSW50NjQ2MygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDY0NjMoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDY0NjMoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEludDY0NjMoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDY0NjQoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDY0NjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQ2NDY0KCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQ2NDY0KCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQ2NDY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxBbGxUeXBlcygpICE9IG90aGVyLmhhc09wdGlvbmFsQWxsVHlwZXMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxBbGxUeXBlcygpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbEFsbFR5cGVzKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEFsbFR5cGVzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2NSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfNjVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzI2NSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDY0MSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UNjRfMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0T3B0aW9uYWxJbnQ2NDEoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50NjQyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQ2NF8yX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXRPcHRpb25hbEludDY0MigpKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQ2NDYzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQ2NF82M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0T3B0aW9uYWxJbnQ2NDYzKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDY0NjQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lOVDY0XzY0X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICBnZXRPcHRpb25hbEludDY0NjQoKSk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsQWxsVHlwZXMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0FMTF9UWVBFU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxBbGxUeXBlcygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0FMTF9UWVBFU19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlcikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKTsKICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIG9wdGlvbmFsSW50MzI2NV8gPSAwOwogICAgICAgIG9wdGlvbmFsSW50NjQxXyA9IDBMOwogICAgICAgIG9wdGlvbmFsSW50NjQyXyA9IDBMOwogICAgICAgIG9wdGlvbmFsSW50NjQ2M18gPSAwTDsKICAgICAgICBvcHRpb25hbEludDY0NjRfID0gMEw7CiAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlciBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlciByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlcih0aGlzKTsKICAgICAgICBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhyZXN1bHQpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyIHJlc3VsdCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRBbGxUeXBlc18gPSByZXBlYXRlZEFsbFR5cGVzXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQWxsVHlwZXNfID0gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzI2NV8gPSBvcHRpb25hbEludDMyNjVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50NjQxXyA9IG9wdGlvbmFsSW50NjQxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDY0Ml8gPSBvcHRpb25hbEludDY0Ml87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQ2NDYzXyA9IG9wdGlvbmFsSW50NjQ2M187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQ2NDY0XyA9IG9wdGlvbmFsSW50NjQ2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxBbGxUeXBlc18gPSBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxBbGxUeXBlc18KICAgICAgICAgICAgICA6IG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlcikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlcilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyNjUoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQzMjY1KG90aGVyLmdldE9wdGlvbmFsSW50MzI2NSgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50NjQxKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50NjQxKG90aGVyLmdldE9wdGlvbmFsSW50NjQxKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQ2NDIoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQ2NDIob3RoZXIuZ2V0T3B0aW9uYWxJbnQ2NDIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDY0NjMoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQ2NDYzKG90aGVyLmdldE9wdGlvbmFsSW50NjQ2MygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50NjQ2NCgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDY0NjQob3RoZXIuZ2V0T3B0aW9uYWxJbnQ2NDY0KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxBbGxUeXBlcygpKSB7CiAgICAgICAgICBtZXJnZU9wdGlvbmFsQWxsVHlwZXMob3RoZXIuZ2V0T3B0aW9uYWxBbGxUeXBlcygpKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQWxsVHlwZXNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBvdGhlci5yZXBlYXRlZEFsbFR5cGVzXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZEFsbChvdGhlci5yZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRBbGxUeXBlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gb3RoZXIucmVwZWF0ZWRBbGxUeXBlc187CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9IAogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyhvdGhlci5yZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDY0MV8gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQ2NDJfID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDc0OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NAogICAgICAgICAgICAgIGNhc2UgODI6IHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgyCiAgICAgICAgICAgICAgY2FzZSA1MDQ6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50NjQ2M18gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MDQKICAgICAgICAgICAgICBjYXNlIDUxMjogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQ2NDY0XyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUxMgogICAgICAgICAgICAgIGNhc2UgNTIwOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyNjVfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTIwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI2NV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjY1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjY1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI2NS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyNjUoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI2NV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzI2NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50MzI2NShpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMjY1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMjY1KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvcHRpb25hbEludDMyNjVfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsSW50NjQxXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQ2NDEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDY0MSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NDEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjQxKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDY0MV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDY0MSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50NjQxKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQ2NDFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQ2NDEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9wdGlvbmFsSW50NjQxXyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxJbnQ2NDJfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDY0MiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50NjQyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDY0Mi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxJbnQ2NDIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50NjQyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50NjQyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQ2NDIobG9uZyB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDY0Ml8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEludDY0MigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb3B0aW9uYWxJbnQ2NDJfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbEludDY0NjNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50NjQ2MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50NjQ2MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDY0NjMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjQ2MygpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQ2NDYzXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQ2NDYzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQ2NDYzKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQ2NDYzXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQ2NDYzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvcHRpb25hbEludDY0NjNfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbEludDY0NjRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50NjQ2NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50NjQ2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0XzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDY0NjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjQ2NCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQ2NDY0XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQ2NDY0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQ2NDY0KGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQ2NDY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQ2NDY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvcHRpb25hbEludDY0NjRfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgb3B0aW9uYWxBbGxUeXBlc187CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEFsbFR5cGVzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEFsbFR5cGVzLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE9wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZSgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEFsbFR5cGVzKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbEFsbFR5cGVzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyAhPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbEFsbFR5cGVzQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0T3B0aW9uYWxBbGxUeXBlc0J1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldE9wdGlvbmFsQWxsVHlwZXNPckJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNfID09IG51bGwgPwogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEFsbFR5cGVzKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IHJlcGVhdGVkQWxsVHlwZXNfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+KHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEFsbFR5cGVzQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uc2l6ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLmdldChpbmRleCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5zZXQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZCh2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IHZhbHVlcykgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRBbGxNZXNzYWdlcyh2YWx1ZXMpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQWxsVHlwZXMoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRBbGxUeXBlcyhpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGdldFJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzQnVpbGRlckxpc3QoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLAogICAgICAgICAgICAgICAgICAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlcikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlcj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlcj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXIgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBUZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlck9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzEwMDAgPSAxMDAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjEwMDAgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzIxMDAwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzEwMDAgPSAxMDAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIxMDAwLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxJbnQzMjEwMDAoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyNjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzI2NSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NSA9IDY1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI2NS4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzI2NSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjEuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyMSgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjIuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjYzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjYzLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxJbnQzMjYzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjQuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbEludDMyNjQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQWxsVHlwZXMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsQWxsVHlwZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE9wdGlvbmFsQWxsVHlwZXMoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0T3B0aW9uYWxBbGxUeXBlc09yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiAKICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0UmVwZWF0ZWRBbGxUeXBlcyhpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlcigKICAgICAgICBpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIFRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyKQogICAgICBUZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlck9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcigpIHsKICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlci5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlci5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UMzJfMTAwMF9GSUVMRF9OVU1CRVIgPSAxMDAwOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjEwMDBfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMTAwMCA9IDEwMDA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMTAwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIxMDAwKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzEwMDAgPSAxMDAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIxMDAwLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIxMDAwKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjEwMDBfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyXzY1X0ZJRUxEX05VTUJFUiA9IDY1OwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjY1XyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyNjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjY1KCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjY1XzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl8xX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyMV8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjEoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjEuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjEoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEludDMyMV87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UMzJfMl9GSUVMRF9OVU1CRVIgPSAyOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIyKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzIyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyXzYzX0ZJRUxEX05VTUJFUiA9IDYzOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjYzXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyNjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyNjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjYzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjYzXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl82NF9GSUVMRF9OVU1CRVIgPSA2NDsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI2NF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjY0KCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjY0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzI2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI2NF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUiA9IDk7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG9wdGlvbmFsQWxsVHlwZXNfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEFsbFR5cGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxBbGxUeXBlcy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldE9wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldE9wdGlvbmFsQWxsVHlwZXNPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9BTExfVFlQRVNfRklFTERfTlVNQkVSID0gMTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IHJlcGVhdGVkQWxsVHlwZXNfOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiBnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRBbGxUeXBlc0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQWxsVHlwZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgb3B0aW9uYWxJbnQzMjFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyLCBvcHRpb25hbEludDMyMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoOSwgZ2V0T3B0aW9uYWxBbGxUeXBlcygpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgxMCwgcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig2Mywgb3B0aW9uYWxJbnQzMjYzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoNjQsIG9wdGlvbmFsSW50MzI2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDY1LCBvcHRpb25hbEludDMyNjVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxMDAwLCBvcHRpb25hbEludDMyMTAwMF8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIG9wdGlvbmFsSW50MzIxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgyLCBvcHRpb25hbEludDMyMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5LCBnZXRPcHRpb25hbEFsbFR5cGVzKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRBbGxUeXBlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMTAsIHJlcGVhdGVkQWxsVHlwZXNfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg2Mywgb3B0aW9uYWxJbnQzMjYzXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg2NCwgb3B0aW9uYWxJbnQzMjY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSg2NSwgb3B0aW9uYWxJbnQzMjY1Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxMDAwLCBvcHRpb25hbEludDMyMTAwMF8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXIpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXIgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcikgb2JqOwoKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIxMDAwKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMjEwMDAoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjEwMDAoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMyMTAwMCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzIxMDAwKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjY1KCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMjY1KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2NSgpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50MzI2NSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzI2NSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIxKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMjEoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjEoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMyMSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzIxKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjIoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDMyMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMigpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50MzIyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyNjMoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDMyNjMoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjYzKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMjYzKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjYzKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjY0KCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMjY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2NCgpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50MzI2NCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzI2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsQWxsVHlwZXMoKSAhPSBvdGhlci5oYXNPcHRpb25hbEFsbFR5cGVzKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsQWxsVHlwZXMoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxBbGxUeXBlcygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxBbGxUeXBlcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMTAwMCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfMTAwMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjEwMDAoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjY1KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl82NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjY1KCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIxKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl8xX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEludDMyMSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyMigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjIoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMjYzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQzMl82M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxJbnQzMjYzKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzI2NCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzI2NCgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEFsbFR5cGVzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9BTExfVFlQRVNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsQWxsVHlwZXMoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEFsbFR5cGVzQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9BTExfVFlQRVNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlciBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXIpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlck9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlci5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRPcHRpb25hbEFsbFR5cGVzRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzRmllbGRCdWlsZGVyKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyMTAwMF8gPSAwOwogICAgICAgIG9wdGlvbmFsSW50MzI2NV8gPSAwOwogICAgICAgIG9wdGlvbmFsSW50MzIxXyA9IDA7CiAgICAgICAgb3B0aW9uYWxJbnQzMjJfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyNjNfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyNjRfID0gMDsKICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBudWxsOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXIgcmVzdWx0KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEFsbFR5cGVzXyA9IHJlcGVhdGVkQWxsVHlwZXNfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRBbGxUeXBlc18gPSByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXIgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMjEwMDBfID0gb3B0aW9uYWxJbnQzMjEwMDBfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzI2NV8gPSBvcHRpb25hbEludDMyNjVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzIxXyA9IG9wdGlvbmFsSW50MzIxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEludDMyMl8gPSBvcHRpb25hbEludDMyMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMjYzXyA9IG9wdGlvbmFsSW50MzI2M187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxJbnQzMjY0XyA9IG9wdGlvbmFsSW50MzI2NF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxBbGxUeXBlc18gPSBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxBbGxUeXBlc18KICAgICAgICAgICAgICA6IG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyMTAwMCgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyMTAwMChvdGhlci5nZXRPcHRpb25hbEludDMyMTAwMCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50MzI2NSgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyNjUob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjY1KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQzMjEoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQzMjEob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyMigpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyMihvdGhlci5nZXRPcHRpb25hbEludDMyMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50MzI2MygpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyNjMob3RoZXIuZ2V0T3B0aW9uYWxJbnQzMjYzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQzMjY0KCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzI2NChvdGhlci5nZXRPcHRpb25hbEludDMyNjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEFsbFR5cGVzKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxBbGxUeXBlcyhvdGhlci5nZXRPcHRpb25hbEFsbFR5cGVzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRBbGxUeXBlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IG90aGVyLnJlcGVhdGVkQWxsVHlwZXNfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkQWxsKG90aGVyLnJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEFsbFR5cGVzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBvdGhlci5yZXBlYXRlZEFsbFR5cGVzXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzIxXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyMl8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLlBBUlNFUiwKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKG0pOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBjYXNlIDUwNDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxJbnQzMjYzXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwNAogICAgICAgICAgICAgIGNhc2UgNTEyOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyNjRfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTEyCiAgICAgICAgICAgICAgY2FzZSA1MjA6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzI2NV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MjAKICAgICAgICAgICAgICBjYXNlIDgwMDA6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzIxMDAwXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjEwMDBfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzEwMDAgPSAxMDAwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMTAwMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIxMDAwKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMTAwMCA9IDEwMDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMTAwMC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyMTAwMCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjEwMDBfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xMDAwID0gMTAwMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQzMjEwMDAgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyMTAwMChpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMjEwMDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xMDAwID0gMTAwMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMjEwMDAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9wdGlvbmFsSW50MzIxMDAwXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI2NV8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjY1IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjY1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI2NS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyNjUoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI2NV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzI2NSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50MzI2NShpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMjY1XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMjY1KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvcHRpb25hbEludDMyNjVfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMjFfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIxKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyMS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyMSgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMjFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQzMjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyMShpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMjFfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMjEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9wdGlvbmFsSW50MzIxXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzIyXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMjIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzIyXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMjIoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzIyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvcHRpb25hbEludDMyMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyNjNfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzI2MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyNjMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMjYzKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDMyNjNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyNjMgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyNjMoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzI2M18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzI2MygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb3B0aW9uYWxJbnQzMjYzXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzI2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMjY0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzI2NC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyNjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzI2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzI2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50MzI2NChpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQzMjY0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMjY0KCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvcHRpb25hbEludDMyNjRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQWxsVHlwZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0T3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxBbGxUeXBlcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQWxsVHlwZXMoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc18gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0T3B0aW9uYWxBbGxUeXBlc09yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXMoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gcmVwZWF0ZWRBbGxUeXBlc18gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4ocmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQWxsVHlwZXMoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRBbGxUeXBlcygpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlciBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdFZlcmlmeUludDMyQmlnRmllbGROdW1iZXIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlck9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEwMDAgPSAxMDAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIxMDAwIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjEwMDAoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xMDAwID0gMTAwMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjEwMDAuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbFVpbnQzMjEwMDAoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyNjUgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjUoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NSA9IDY1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjUuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbFVpbnQzMjY1KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjEoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjEuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbFVpbnQzMjEoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsVWludDMyMigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzI2MygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI2My4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsVWludDMyNjMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjQuCiAgICAgKi8KICAgIGludCBnZXRPcHRpb25hbFVpbnQzMjY0KCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEFsbFR5cGVzIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEFsbFR5cGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEFsbFR5cGVzLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRPcHRpb25hbEFsbFR5cGVzKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldE9wdGlvbmFsQWxsVHlwZXNPckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gCiAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQWxsVHlwZXMoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEFsbFR5cGVzQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc09yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlcikKICAgICAgVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyKCkgewogICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlci5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VJTlQzMl8xMDAwX0ZJRUxEX05VTUJFUiA9IDEwMDA7CiAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjEwMDBfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xMDAwID0gMTAwMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyMTAwMCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMTAwMCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEwMDAgPSAxMDAwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyMTAwMC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjEwMDAoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjEwMDBfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VJTlQzMl82NV9GSUVMRF9OVU1CRVIgPSA2NTsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyNjVfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NSA9IDY1OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2NSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjUoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NSA9IDY1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjUuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzI2NSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyNjVfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VJTlQzMl8xX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjFfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyMSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjEoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjFfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VJTlQzMl8yX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjJfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzIgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjJfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VJTlQzMl82M19GSUVMRF9OVU1CRVIgPSA2MzsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyNjNfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzI2MygpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyNjNfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VJTlQzMl82NF9GSUVMRF9OVU1CRVIgPSA2NDsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyNjRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzI2NCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyNjRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0FMTF9UWVBFU19GSUVMRF9OVU1CRVIgPSA5OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBvcHRpb25hbEFsbFR5cGVzXzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBbGxUeXBlcyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQWxsVHlwZXMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxBbGxUeXBlc187CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzPiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNPckJ1aWxkZXJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBnZXRSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigxLCBvcHRpb25hbFVpbnQzMjFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoMiwgb3B0aW9uYWxVaW50MzIyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSg5LCBnZXRPcHRpb25hbEFsbFR5cGVzKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRBbGxUeXBlc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEwLCByZXBlYXRlZEFsbFR5cGVzXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMig2Mywgb3B0aW9uYWxVaW50MzI2M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMig2NCwgb3B0aW9uYWxVaW50MzI2NF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMig2NSwgb3B0aW9uYWxVaW50MzI2NV8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMigxMDAwLCBvcHRpb25hbFVpbnQzMjEwMDBfKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoMSwgb3B0aW9uYWxVaW50MzIxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoMiwgb3B0aW9uYWxVaW50MzIyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDksIGdldE9wdGlvbmFsQWxsVHlwZXMoKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEFsbFR5cGVzXy5zaXplKCk7IGkrKykgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxMCwgcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSg2Mywgb3B0aW9uYWxVaW50MzI2M18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKDY0LCBvcHRpb25hbFVpbnQzMjY0Xyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoNjUsIG9wdGlvbmFsVWludDMyNjVfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSgxMDAwLCBvcHRpb25hbFVpbnQzMjEwMDBfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlcikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIpIG9iajsKCiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjEwMDAoKSAhPSBvdGhlci5oYXNPcHRpb25hbFVpbnQzMjEwMDAoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIxMDAwKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxVaW50MzIxMDAwKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxVaW50MzIxMDAwKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzI2NSgpICE9IG90aGVyLmhhc09wdGlvbmFsVWludDMyNjUoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzI2NSgpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsVWludDMyNjUoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFVpbnQzMjY1KCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIxKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVaW50MzIxKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyMSgpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsVWludDMyMSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyMigpICE9IG90aGVyLmhhc09wdGlvbmFsVWludDMyMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjIoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQzMjIoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFVpbnQzMjIoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjYzKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVaW50MzI2MygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjYzKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxVaW50MzI2MygpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyNjMoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjY0KCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVaW50MzI2NCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjY0KCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxVaW50MzI2NCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEFsbFR5cGVzKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxBbGxUeXBlcygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEFsbFR5cGVzKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsQWxsVHlwZXMoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsQWxsVHlwZXMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRBbGxUeXBlc0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIxMDAwKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9VSU5UMzJfMTAwMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxVaW50MzIxMDAwKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjUoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1VJTlQzMl82NV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxVaW50MzI2NSgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjEoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1VJTlQzMl8xX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFVpbnQzMjEoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIyKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9VSU5UMzJfMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxVaW50MzIyKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjMoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1VJTlQzMl82M19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxVaW50MzI2MygpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjY0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9VSU5UMzJfNjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsVWludDMyNjQoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxBbGxUeXBlcygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEFsbFR5cGVzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRBbGxUeXBlc0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQUxMX1RZUEVTX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEFsbFR5cGVzTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlciBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSB2b2lkIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKSB7CiAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAuYWx3YXlzVXNlRmllbGRCdWlsZGVycykgewogICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgb3B0aW9uYWxVaW50MzIxMDAwXyA9IDA7CiAgICAgICAgb3B0aW9uYWxVaW50MzI2NV8gPSAwOwogICAgICAgIG9wdGlvbmFsVWludDMyMV8gPSAwOwogICAgICAgIG9wdGlvbmFsVWludDMyMl8gPSAwOwogICAgICAgIG9wdGlvbmFsVWludDMyNjNfID0gMDsKICAgICAgICBvcHRpb25hbFVpbnQzMjY0XyA9IDA7CiAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyIHJlc3VsdCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRBbGxUeXBlc18gPSByZXBlYXRlZEFsbFR5cGVzXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkQWxsVHlwZXNfID0gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMjEwMDBfID0gb3B0aW9uYWxVaW50MzIxMDAwXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMjY1XyA9IG9wdGlvbmFsVWludDMyNjVfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVWludDMyMV8gPSBvcHRpb25hbFVpbnQzMjFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVWludDMyMl8gPSBvcHRpb25hbFVpbnQzMjJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVWludDMyNjNfID0gb3B0aW9uYWxVaW50MzI2M187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxVaW50MzI2NF8gPSBvcHRpb25hbFVpbnQzMjY0XzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEFsbFR5cGVzXyA9IG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbEFsbFR5cGVzXwogICAgICAgICAgICAgIDogb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlcikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFVpbnQzMjEwMDAoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxVaW50MzIxMDAwKG90aGVyLmdldE9wdGlvbmFsVWludDMyMTAwMCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsVWludDMyNjUoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxVaW50MzI2NShvdGhlci5nZXRPcHRpb25hbFVpbnQzMjY1KCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxVaW50MzIxKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsVWludDMyMShvdGhlci5nZXRPcHRpb25hbFVpbnQzMjEoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFVpbnQzMjIoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxVaW50MzIyKG90aGVyLmdldE9wdGlvbmFsVWludDMyMigpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsVWludDMyNjMoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxVaW50MzI2MyhvdGhlci5nZXRPcHRpb25hbFVpbnQzMjYzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxVaW50MzI2NCgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFVpbnQzMjY0KG90aGVyLmdldE9wdGlvbmFsVWludDMyNjQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEFsbFR5cGVzKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxBbGxUeXBlcyhvdGhlci5nZXRPcHRpb25hbEFsbFR5cGVzKCkpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRBbGxUeXBlc18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXyA9IG90aGVyLnJlcGVhdGVkQWxsVHlwZXNfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkQWxsKG90aGVyLnJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEFsbFR5cGVzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBvdGhlci5yZXBlYXRlZEFsbFR5cGVzXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsVWludDMyMV8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsVWludDMyMl8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDc0OiB7CiAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbEFsbFR5cGVzRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NAogICAgICAgICAgICAgIGNhc2UgODI6IHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIG0gPQogICAgICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRNZXNzYWdlKG0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgyCiAgICAgICAgICAgICAgY2FzZSA1MDQ6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsVWludDMyNjNfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwNAogICAgICAgICAgICAgIGNhc2UgNTEyOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFVpbnQzMjY0XyA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MTIKICAgICAgICAgICAgICBjYXNlIDUyMDogewogICAgICAgICAgICAgICAgb3B0aW9uYWxVaW50MzI2NV8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTIwCiAgICAgICAgICAgICAgY2FzZSA4MDAwOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFVpbnQzMjEwMDBfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzIxMDAwXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEwMDAgPSAxMDAwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjEwMDAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjEwMDAoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEwMDAgPSAxMDAwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIxMDAwLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyMTAwMCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxVaW50MzIxMDAwXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xMDAwID0gMTAwMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxVaW50MzIxMDAwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzIxMDAwKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbFVpbnQzMjEwMDBfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEwMDAgPSAxMDAwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFVpbnQzMjEwMDAoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9wdGlvbmFsVWludDMyMTAwMF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjY1XyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyNjUgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjY1KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NSA9IDY1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI2NS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjY1KCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjY1XzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NSA9IDY1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFVpbnQzMjY1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzI2NShpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxVaW50MzI2NV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50MzI2NSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb3B0aW9uYWxVaW50MzI2NV8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjFfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzIxKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFVpbnQzMjEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFVpbnQzMjEoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsVWludDMyMV8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsVWludDMyMSgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb3B0aW9uYWxVaW50MzIxXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIyIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzIyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyMi4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsVWludDMyMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVWludDMyMihpbnQgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxVaW50MzIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50MzIyKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvcHRpb25hbFVpbnQzMjJfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzI2M18gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjYzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzI2MygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzI2MygpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxVaW50MzI2M187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxVaW50MzI2MyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVWludDMyNjMoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsVWludDMyNjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsVWludDMyNjMoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9wdGlvbmFsVWludDMyNjNfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzI2NF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzI2NCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzI2NCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxVaW50MzI2NF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxVaW50MzI2NCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVWludDMyNjQoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsVWludDMyNjRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsVWludDMyNjQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9wdGlvbmFsVWludDMyNjRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQWxsVHlwZXMgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQWxsVHlwZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgZ2V0T3B0aW9uYWxBbGxUeXBlcygpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxBbGxUeXBlcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcyB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyBvcHRpb25hbF9hbGxfdHlwZXMgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQWxsVHlwZXMoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc18gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyAhPSBudWxsICYmCiAgICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gdmFsdWU7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc18gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIG9wdGlvbmFsX2FsbF90eXBlcyA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEFsbFR5cGVzKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBvcHRpb25hbEFsbFR5cGVzXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBnZXRPcHRpb25hbEFsbFR5cGVzQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldE9wdGlvbmFsQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXIgZ2V0T3B0aW9uYWxBbGxUeXBlc09yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxBbGxUeXBlc18gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbEFsbFR5cGVzXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgb3B0aW9uYWxfYWxsX3R5cGVzID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxBbGxUeXBlc0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsQWxsVHlwZXMoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsQWxsVHlwZXNfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsQWxsVHlwZXNCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gcmVwZWF0ZWRBbGxUeXBlc18gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4ocmVwZWF0ZWRBbGxUeXBlc18pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgICB9CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXM+IGdldFJlcGVhdGVkQWxsVHlwZXNMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQWxsVHlwZXNDb3VudCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIGdldFJlcGVhdGVkQWxsVHlwZXMoaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5nZXRNZXNzYWdlKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRBbGxUeXBlcygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMgdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQWxsVHlwZXNJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfLmFkZChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18uYWRkKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQWxsVHlwZXMoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uYWRkTWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEFsbFR5cGVzKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gdmFsdWVzKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFsbFR5cGVzSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEFsbFR5cGVzXyk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKHZhbHVlcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRBbGxUeXBlcygpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZEFsbFR5cGVzKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBbGxUeXBlc0lzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18ucmVtb3ZlKGluZGV4KTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8ucmVtb3ZlKGluZGV4KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgZ2V0UmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzIHJlcGVhdGVkX2FsbF90eXBlcyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlc09yQnVpbGRlciBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc18uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyByZXBlYXRlZF9hbGxfdHlwZXMgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPiAKICAgICAgICAgICBnZXRSZXBlYXRlZEFsbFR5cGVzT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZEFsbFR5cGVzQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkQWxsVHlwZXNfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkQWxsVHlwZXNGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIgYWRkUmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMgcmVwZWF0ZWRfYWxsX3R5cGVzID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXJMaXN0KCk7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXNPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWRBbGxUeXBlc0ZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAocmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkQWxsVHlwZXNCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18sCiAgICAgICAgICAgICAgICAgICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgcmVwZWF0ZWRBbGxUeXBlc18gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRBbGxUeXBlc0J1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlcikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlcj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlciBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlcj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIG9wdGlvbmFsX25lc3RlZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE5lc3RlZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxOZXN0ZWQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxfbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIGdldE9wdGlvbmFsTmVzdGVkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIG9wdGlvbmFsX25lc3RlZCA9IDE7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWRPckJ1aWxkZXIgZ2V0T3B0aW9uYWxOZXN0ZWRPckJ1aWxkZXIoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMikKICAgICAgVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBUZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIE5lc3RlZE9yQnVpbGRlciBleHRlbmRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzUwMDAgPSA1MDAwOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjUwMDAgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjUwMDAoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNTAwMCA9IDUwMDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjUwMDAuCiAgICAgICAqLwogICAgICBpbnQgZ2V0T3B0aW9uYWxVaW50MzI1MDAwKCk7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xMDAwID0gMTAwMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIxMDAwIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzIxMDAwKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEwMDAgPSAxMDAwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIxMDAwLgogICAgICAgKi8KICAgICAgaW50IGdldE9wdGlvbmFsVWludDMyMTAwMCgpOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjYoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjYuCiAgICAgICAqLwogICAgICBpbnQgZ2V0T3B0aW9uYWxVaW50MzI2NigpOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjUoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjUuCiAgICAgICAqLwogICAgICBpbnQgZ2V0T3B0aW9uYWxVaW50MzI2NSgpOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMSgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyMS4KICAgICAgICovCiAgICAgIGludCBnZXRPcHRpb25hbFVpbnQzMjEoKTsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjIoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjIuCiAgICAgICAqLwogICAgICBpbnQgZ2V0T3B0aW9uYWxVaW50MzIyKCk7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjYzIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzI2MygpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82MyA9IDYzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI2My4KICAgICAgICovCiAgICAgIGludCBnZXRPcHRpb25hbFVpbnQzMjYzKCk7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjY0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzI2NCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI2NC4KICAgICAgICovCiAgICAgIGludCBnZXRPcHRpb25hbFVpbnQzMjY0KCk7CgogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxfbmVzdGVkID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZCgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxfbmVzdGVkID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkLgogICAgICAgKi8KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIGdldE9wdGlvbmFsTmVzdGVkKCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBvcHRpb25hbF9uZXN0ZWQgPSA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZE9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE9yQnVpbGRlcigpOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlcGVhdGVkX25lc3RlZCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZD4gCiAgICAgICAgICBnZXRSZXBlYXRlZE5lc3RlZExpc3QoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlcGVhdGVkX25lc3RlZCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBnZXRSZXBlYXRlZE5lc3RlZChpbnQgaW5kZXgpOwogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgcmVwZWF0ZWRfbmVzdGVkID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgaW50IGdldFJlcGVhdGVkTmVzdGVkQ291bnQoKTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlcGVhdGVkX25lc3RlZCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWRPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRPckJ1aWxkZXJMaXN0KCk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCByZXBlYXRlZF9uZXN0ZWQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWRPckJ1aWxkZXIgZ2V0UmVwZWF0ZWROZXN0ZWRPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIE5lc3RlZCBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCkKICAgICAgICBOZXN0ZWRPckJ1aWxkZXIgewogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAgIC8vIFVzZSBOZXN0ZWQubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBOZXN0ZWQoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBOZXN0ZWQoKSB7CiAgICAgICAgcmVwZWF0ZWROZXN0ZWRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgICByZXR1cm4gbmV3IE5lc3RlZCgpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyX05lc3RlZF9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzJfTmVzdGVkX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UMzJfNTAwMF9GSUVMRF9OVU1CRVIgPSA1MDAwOwogICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjUwMDBfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNTAwMCA9IDUwMDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyNTAwMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNTAwMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNTAwMCA9IDUwMDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjUwMDAuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzI1MDAwKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjUwMDBfOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UMzJfMTAwMF9GSUVMRF9OVU1CRVIgPSAxMDAwOwogICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjEwMDBfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMTAwMCA9IDEwMDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyMTAwMCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMTAwMCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMTAwMCA9IDEwMDA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjEwMDAuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzIxMDAwKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjEwMDBfOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UMzJfNjZfRklFTERfTlVNQkVSID0gNjY7CiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyNjZfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjYgPSA2Njs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2NiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjYoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY2ID0gNjY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjY2LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyNjYoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyNjZfOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UMzJfNjVfRklFTERfTlVNQkVSID0gNjU7CiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyNjVfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2NSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjUoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY1ID0gNjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjY1LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyNjUoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyNjVfOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UMzJfMV9GSUVMRF9OVU1CRVIgPSAxOwogICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjFfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyMSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjEuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzIxKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjFfOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UMzJfMl9GSUVMRF9OVU1CRVIgPSAyOwogICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjJfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjIuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzIyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjJfOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UMzJfNjNfRklFTERfTlVNQkVSID0gNjM7CiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyNjNfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjYzLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyNjMoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyNjNfOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UMzJfNjRfRklFTERfTlVNQkVSID0gNjQ7CiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyNjRfID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjQgPSA2NDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2NCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjY0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyNjQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyNjRfOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9ORVNURURfRklFTERfTlVNQkVSID0gOTsKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxOZXN0ZWRfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxfbmVzdGVkID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbE5lc3RlZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIG9wdGlvbmFsX25lc3RlZCA9IDk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBnZXRPcHRpb25hbE5lc3RlZCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIG9wdGlvbmFsX25lc3RlZCA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkT3JCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkXzsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTkVTVEVEX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQ+IHJlcGVhdGVkTmVzdGVkXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlcGVhdGVkX25lc3RlZCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZD4gZ2V0UmVwZWF0ZWROZXN0ZWRMaXN0KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlcGVhdGVkX25lc3RlZCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWRPckJ1aWxkZXI+IAogICAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRPckJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlcGVhdGVkX25lc3RlZCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZE5lc3RlZENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCByZXBlYXRlZF9uZXN0ZWQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgZ2V0UmVwZWF0ZWROZXN0ZWQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCByZXBlYXRlZF9uZXN0ZWQgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWRPckJ1aWxkZXIgZ2V0UmVwZWF0ZWROZXN0ZWRPckJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRfLmdldChpbmRleCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoMSwgb3B0aW9uYWxVaW50MzIxXyk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKDIsIG9wdGlvbmFsVWludDMyMl8pOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoOSwgZ2V0T3B0aW9uYWxOZXN0ZWQoKSk7CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWROZXN0ZWRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDEwLCByZXBlYXRlZE5lc3RlZF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoNjMsIG9wdGlvbmFsVWludDMyNjNfKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoNjQsIG9wdGlvbmFsVWludDMyNjRfKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoNjUsIG9wdGlvbmFsVWludDMyNjVfKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoNjYsIG9wdGlvbmFsVWludDMyNjZfKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICBvdXRwdXQud3JpdGVVSW50MzIoMTAwMCwgb3B0aW9uYWxVaW50MzIxMDAwXyk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgb3V0cHV0LndyaXRlVUludDMyKDUwMDAsIG9wdGlvbmFsVWludDMyNTAwMF8pOwogICAgICAgIH0KICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoMSwgb3B0aW9uYWxVaW50MzIxXyk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSgyLCBvcHRpb25hbFVpbnQzMjJfKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg5LCBnZXRPcHRpb25hbE5lc3RlZCgpKTsKICAgICAgICB9CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZE5lc3RlZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwLCByZXBlYXRlZE5lc3RlZF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKDYzLCBvcHRpb25hbFVpbnQzMjYzXyk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSg2NCwgb3B0aW9uYWxVaW50MzI2NF8pOwogICAgICAgIH0KICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemUoNjUsIG9wdGlvbmFsVWludDMyNjVfKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKDY2LCBvcHRpb25hbFVpbnQzMjY2Xyk7CiAgICAgICAgfQogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZSgxMDAwLCBvcHRpb25hbFVpbnQzMjEwMDBfKTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplKDUwMDAsIG9wdGlvbmFsVWludDMyNTAwMF8pOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQpKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgICAgfQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQpIG9iajsKCiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNTAwMCgpICE9IG90aGVyLmhhc09wdGlvbmFsVWludDMyNTAwMCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNTAwMCgpKSB7CiAgICAgICAgICBpZiAoZ2V0T3B0aW9uYWxVaW50MzI1MDAwKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFVpbnQzMjUwMDAoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIxMDAwKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVaW50MzIxMDAwKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIxMDAwKCkpIHsKICAgICAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQzMjEwMDAoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyMTAwMCgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjY2KCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVaW50MzI2NigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjYoKSkgewogICAgICAgICAgaWYgKGdldE9wdGlvbmFsVWludDMyNjYoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyNjYoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzI2NSgpICE9IG90aGVyLmhhc09wdGlvbmFsVWludDMyNjUoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjY1KCkpIHsKICAgICAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQzMjY1KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFVpbnQzMjY1KCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyMSgpICE9IG90aGVyLmhhc09wdGlvbmFsVWludDMyMSgpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyMSgpKSB7CiAgICAgICAgICBpZiAoZ2V0T3B0aW9uYWxVaW50MzIxKCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFVpbnQzMjEoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIyKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVaW50MzIyKCkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzIyKCkpIHsKICAgICAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQzMjIoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyMigpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjYzKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVaW50MzI2MygpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjMoKSkgewogICAgICAgICAgaWYgKGdldE9wdGlvbmFsVWludDMyNjMoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsVWludDMyNjMoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICBpZiAoaGFzT3B0aW9uYWxVaW50MzI2NCgpICE9IG90aGVyLmhhc09wdGlvbmFsVWludDMyNjQoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNPcHRpb25hbFVpbnQzMjY0KCkpIHsKICAgICAgICAgIGlmIChnZXRPcHRpb25hbFVpbnQzMjY0KCkKICAgICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbFVpbnQzMjY0KCkpIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxOZXN0ZWQoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGlmIChoYXNPcHRpb25hbE5lc3RlZCgpKSB7CiAgICAgICAgICBpZiAoIWdldE9wdGlvbmFsTmVzdGVkKCkKICAgICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsTmVzdGVkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmICghZ2V0UmVwZWF0ZWROZXN0ZWRMaXN0KCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZE5lc3RlZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgICAgfQogICAgICAgIGludCBoYXNoID0gNDE7CiAgICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNTAwMCgpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9VSU5UMzJfNTAwMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFVpbnQzMjUwMDAoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyMTAwMCgpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9VSU5UMzJfMTAwMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFVpbnQzMjEwMDAoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjYoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDMyXzY2X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsVWludDMyNjYoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjUoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDMyXzY1X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsVWludDMyNjUoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyMSgpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9VSU5UMzJfMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFVpbnQzMjEoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyMigpKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9VSU5UMzJfMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFVpbnQzMjIoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjMoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDMyXzYzX0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsVWludDMyNjMoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc09wdGlvbmFsVWludDMyNjQoKSkgewogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVUlOVDMyXzY0X0ZJRUxEX05VTUJFUjsKICAgICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsVWludDMyNjQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkKCkpIHsKICAgICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX05FU1RFRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbE5lc3RlZCgpLmhhc2hDb2RlKCk7CiAgICAgICAgfQogICAgICAgIGlmIChnZXRSZXBlYXRlZE5lc3RlZENvdW50KCkgPiAwKSB7CiAgICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9ORVNURURfRklFTERfTlVNQkVSOwogICAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWROZXN0ZWRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgICB9CiAgICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgcGFyc2VGcm9tKAogICAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgcGFyc2VGcm9tKAogICAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWR9CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQpCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWRPckJ1aWxkZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyX05lc3RlZF9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyX05lc3RlZF9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLm5ld0J1aWxkZXIoKQogICAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKICAgICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgICBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgICAgaWYgKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICAgIG9wdGlvbmFsVWludDMyNTAwMF8gPSAwOwogICAgICAgICAgb3B0aW9uYWxVaW50MzIxMDAwXyA9IDA7CiAgICAgICAgICBvcHRpb25hbFVpbnQzMjY2XyA9IDA7CiAgICAgICAgICBvcHRpb25hbFVpbnQzMjY1XyA9IDA7CiAgICAgICAgICBvcHRpb25hbFVpbnQzMjFfID0gMDsKICAgICAgICAgIG9wdGlvbmFsVWludDMyMl8gPSAwOwogICAgICAgICAgb3B0aW9uYWxVaW50MzI2M18gPSAwOwogICAgICAgICAgb3B0aW9uYWxVaW50MzI2NF8gPSAwOwogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRfID0gbnVsbDsKICAgICAgICAgIGlmIChvcHRpb25hbE5lc3RlZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkQnVpbGRlcl8gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXBlYXRlZE5lc3RlZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXBlYXRlZE5lc3RlZF8gPSBudWxsOwogICAgICAgICAgICByZXBlYXRlZE5lc3RlZEJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgICB9CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMl9OZXN0ZWRfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCh0aGlzKTsKICAgICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgcmVzdWx0KSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkXyk7CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZE5lc3RlZF8gPSByZXBlYXRlZE5lc3RlZF87CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHQucmVwZWF0ZWROZXN0ZWRfID0gcmVwZWF0ZWROZXN0ZWRCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlc3VsdCkgewogICAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQub3B0aW9uYWxVaW50MzI1MDAwXyA9IG9wdGlvbmFsVWludDMyNTAwMF87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0KICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMjEwMDBfID0gb3B0aW9uYWxVaW50MzIxMDAwXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgfQogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVWludDMyNjZfID0gb3B0aW9uYWxVaW50MzI2Nl87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIH0KICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMjY1XyA9IG9wdGlvbmFsVWludDMyNjVfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQub3B0aW9uYWxVaW50MzIxXyA9IG9wdGlvbmFsVWludDMyMV87CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgIH0KICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMjJfID0gb3B0aW9uYWxVaW50MzIyXzsKICAgICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgfQogICAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsVWludDMyNjNfID0gb3B0aW9uYWxVaW50MzI2M187CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgIH0KICAgICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVpbnQzMjY0XyA9IG9wdGlvbmFsVWludDMyNjRfOwogICAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgICByZXN1bHQub3B0aW9uYWxOZXN0ZWRfID0gb3B0aW9uYWxOZXN0ZWRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgICA/IG9wdGlvbmFsTmVzdGVkXwogICAgICAgICAgICAgICAgOiBvcHRpb25hbE5lc3RlZEJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQpIHsKICAgICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBvdGhlcikgewogICAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxVaW50MzI1MDAwKCkpIHsKICAgICAgICAgICAgc2V0T3B0aW9uYWxVaW50MzI1MDAwKG90aGVyLmdldE9wdGlvbmFsVWludDMyNTAwMCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFVpbnQzMjEwMDAoKSkgewogICAgICAgICAgICBzZXRPcHRpb25hbFVpbnQzMjEwMDAob3RoZXIuZ2V0T3B0aW9uYWxVaW50MzIxMDAwKCkpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsVWludDMyNjYoKSkgewogICAgICAgICAgICBzZXRPcHRpb25hbFVpbnQzMjY2KG90aGVyLmdldE9wdGlvbmFsVWludDMyNjYoKSk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxVaW50MzI2NSgpKSB7CiAgICAgICAgICAgIHNldE9wdGlvbmFsVWludDMyNjUob3RoZXIuZ2V0T3B0aW9uYWxVaW50MzI2NSgpKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFVpbnQzMjEoKSkgewogICAgICAgICAgICBzZXRPcHRpb25hbFVpbnQzMjEob3RoZXIuZ2V0T3B0aW9uYWxVaW50MzIxKCkpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsVWludDMyMigpKSB7CiAgICAgICAgICAgIHNldE9wdGlvbmFsVWludDMyMihvdGhlci5nZXRPcHRpb25hbFVpbnQzMjIoKSk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxVaW50MzI2MygpKSB7CiAgICAgICAgICAgIHNldE9wdGlvbmFsVWludDMyNjMob3RoZXIuZ2V0T3B0aW9uYWxVaW50MzI2MygpKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFVpbnQzMjY0KCkpIHsKICAgICAgICAgICAgc2V0T3B0aW9uYWxVaW50MzI2NChvdGhlci5nZXRPcHRpb25hbFVpbnQzMjY0KCkpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsTmVzdGVkKCkpIHsKICAgICAgICAgICAgbWVyZ2VPcHRpb25hbE5lc3RlZChvdGhlci5nZXRPcHRpb25hbE5lc3RlZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZE5lc3RlZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkXyA9IG90aGVyLnJlcGVhdGVkTmVzdGVkXzsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWROZXN0ZWRfKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWROZXN0ZWRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEJ1aWxkZXJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkXyA9IG90aGVyLnJlcGVhdGVkTmVzdGVkXzsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkQnVpbGRlcl8gPSAKICAgICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuYWx3YXlzVXNlRmllbGRCdWlsZGVycyA/CiAgICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkTmVzdGVkXyk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICB0cnkgewogICAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgICAgb3B0aW9uYWxVaW50MzIxXyA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICAgIG9wdGlvbmFsVWludDMyMl8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA3NAogICAgICAgICAgICAgICAgY2FzZSA4MjogewogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgbSA9CiAgICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRfLmFkZChtKTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZEJ1aWxkZXJfLmFkZE1lc3NhZ2UobSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICAgIGNhc2UgNTA0OiB7CiAgICAgICAgICAgICAgICAgIG9wdGlvbmFsVWludDMyNjNfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwNAogICAgICAgICAgICAgICAgY2FzZSA1MTI6IHsKICAgICAgICAgICAgICAgICAgb3B0aW9uYWxVaW50MzI2NF8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgNTEyCiAgICAgICAgICAgICAgICBjYXNlIDUyMDogewogICAgICAgICAgICAgICAgICBvcHRpb25hbFVpbnQzMjY1XyA9IGlucHV0LnJlYWRVSW50MzIoKTsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gY2FzZSA1MjAKICAgICAgICAgICAgICAgIGNhc2UgNTI4OiB7CiAgICAgICAgICAgICAgICAgIG9wdGlvbmFsVWludDMyNjZfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDUyOAogICAgICAgICAgICAgICAgY2FzZSA4MDAwOiB7CiAgICAgICAgICAgICAgICAgIG9wdGlvbmFsVWludDMyMTAwMF8gPSBpbnB1dC5yZWFkVUludDMyKCk7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMAogICAgICAgICAgICAgICAgY2FzZSA0MDAwMDogewogICAgICAgICAgICAgICAgICBvcHRpb25hbFVpbnQzMjUwMDBfID0gaW5wdXQucmVhZFVJbnQzMigpOwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfSAvLyBjYXNlIDQwMDAwCiAgICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjUwMDBfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzUwMDAgPSA1MDAwOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyNTAwMCBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNTAwMCgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl81MDAwID0gNTAwMDs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI1MDAwLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyNTAwMCgpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjUwMDBfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzUwMDAgPSA1MDAwOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsVWludDMyNTAwMCB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVWludDMyNTAwMChpbnQgdmFsdWUpIHsKCiAgICAgICAgICBvcHRpb25hbFVpbnQzMjUwMDBfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzUwMDAgPSA1MDAwOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFVpbnQzMjUwMDAoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICBvcHRpb25hbFVpbnQzMjUwMDBfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjEwMDBfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEwMDAgPSAxMDAwOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyMTAwMCBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyMTAwMCgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl8xMDAwID0gMTAwMDs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzIxMDAwLgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyMTAwMCgpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjEwMDBfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEwMDAgPSAxMDAwOzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsVWludDMyMTAwMCB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVWludDMyMTAwMChpbnQgdmFsdWUpIHsKCiAgICAgICAgICBvcHRpb25hbFVpbnQzMjEwMDBfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEwMDAgPSAxMDAwOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFVpbnQzMjEwMDAoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgICBvcHRpb25hbFVpbnQzMjEwMDBfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjY2XyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NiA9IDY2OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyNjYgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjY2KCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY2ID0gNjY7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjYuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzI2NigpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjY2XzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NiA9IDY2OzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsVWludDMyNjYgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFVpbnQzMjY2KGludCB2YWx1ZSkgewoKICAgICAgICAgIG9wdGlvbmFsVWludDMyNjZfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY2ID0gNjY7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsVWludDMyNjYoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgICBvcHRpb25hbFVpbnQzMjY2XyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxVaW50MzI2NV8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVpbnQzMjY1IGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzI2NSgpIHsKICAgICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NSA9IDY1OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjY1LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsVWludDMyNjUoKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxVaW50MzI2NV87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjUgPSA2NTs8L2NvZGU+CiAgICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFVpbnQzMjY1IHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzI2NShpbnQgdmFsdWUpIHsKCiAgICAgICAgICBvcHRpb25hbFVpbnQzMjY1XyA9IHZhbHVlOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NSA9IDY1OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFVpbnQzMjY1KCkgewogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgICAgb3B0aW9uYWxVaW50MzI2NV8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyMV8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIxIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzIxKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzEgPSAxOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjEuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzIxKCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyMV87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxVaW50MzIxIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzIxKGludCB2YWx1ZSkgewoKICAgICAgICAgIG9wdGlvbmFsVWludDMyMV8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMSA9IDE7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsVWludDMyMSgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICAgIG9wdGlvbmFsVWludDMyMV8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyMl8gOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzIyIGZpZWxkIGlzIHNldC4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVaW50MzIyKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzIgPSAyOzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVpbnQzMjIuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzIyKCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyMl87CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxVaW50MzIyIHRvIHNldC4KICAgICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVaW50MzIyKGludCB2YWx1ZSkgewoKICAgICAgICAgIG9wdGlvbmFsVWludDMyMl8gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfMiA9IDI7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsVWludDMyMigpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICAgIG9wdGlvbmFsVWludDMyMl8gPSAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsVWludDMyNjNfIDsKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVaW50MzI2MyBmaWVsZCBpcyBzZXQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVWludDMyNjMoKSB7CiAgICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCk7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVaW50MzI2My4KICAgICAgICAgKi8KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbFVpbnQzMjYzKCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsVWludDMyNjNfOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzYzID0gNjM7PC9jb2RlPgogICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxVaW50MzI2MyB0byBzZXQuCiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVWludDMyNjMoaW50IHZhbHVlKSB7CgogICAgICAgICAgb3B0aW9uYWxVaW50MzI2M18gPSB2YWx1ZTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHVpbnQzMiBvcHRpb25hbF91aW50MzJfNjMgPSA2Mzs8L2NvZGU+CiAgICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVaW50MzI2MygpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICAgIG9wdGlvbmFsVWludDMyNjNfID0gMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGludCBvcHRpb25hbFVpbnQzMjY0XyA7CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVWludDMyNjQgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVpbnQzMjY0KCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVWludDMyNjQuCiAgICAgICAgICovCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxVaW50MzI2NCgpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFVpbnQzMjY0XzsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgdWludDMyIG9wdGlvbmFsX3VpbnQzMl82NCA9IDY0OzwvY29kZT4KICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsVWludDMyNjQgdG8gc2V0LgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFVpbnQzMjY0KGludCB2YWx1ZSkgewoKICAgICAgICAgIG9wdGlvbmFsVWludDMyNjRfID0gdmFsdWU7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCB1aW50MzIgb3B0aW9uYWxfdWludDMyXzY0ID0gNjQ7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsVWludDMyNjQoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgICBvcHRpb25hbFVpbnQzMjY0XyA9IDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxOZXN0ZWRfOwogICAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkT3JCdWlsZGVyPiBvcHRpb25hbE5lc3RlZEJ1aWxkZXJfOwogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIG9wdGlvbmFsX25lc3RlZCA9IDk7PC9jb2RlPgogICAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxOZXN0ZWQgZmllbGQgaXMgc2V0LgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkKCkgewogICAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBvcHRpb25hbF9uZXN0ZWQgPSA5OzwvY29kZT4KICAgICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbE5lc3RlZC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIGdldE9wdGlvbmFsTmVzdGVkKCkgewogICAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZF87CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIG9wdGlvbmFsX25lc3RlZCA9IDk7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCB2YWx1ZSkgewogICAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkXyA9IHZhbHVlOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIG9wdGlvbmFsX25lc3RlZCA9IDk7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChvcHRpb25hbE5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbE5lc3RlZEJ1aWxkZXJfLnNldE1lc3NhZ2UoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgfQogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxfbmVzdGVkID0gOTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VPcHRpb25hbE5lc3RlZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgdmFsdWUpIHsKICAgICAgICAgIGlmIChvcHRpb25hbE5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApICYmCiAgICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRfICE9IG51bGwgJiYKICAgICAgICAgICAgICBvcHRpb25hbE5lc3RlZF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWRCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBvcHRpb25hbE5lc3RlZF8gPSB2YWx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkXyAhPSBudWxsKSB7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxfbmVzdGVkID0gOTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbE5lc3RlZCgpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkXyA9IG51bGw7CiAgICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICAgIG9wdGlvbmFsTmVzdGVkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICBvcHRpb25hbE5lc3RlZEJ1aWxkZXJfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIG9wdGlvbmFsX25lc3RlZCA9IDk7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZEJ1aWxkZXIoKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIHJldHVybiBnZXRPcHRpb25hbE5lc3RlZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxfbmVzdGVkID0gOTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZE9yQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZE9yQnVpbGRlcigpIHsKICAgICAgICAgIGlmIChvcHRpb25hbE5lc3RlZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkXyA9PSBudWxsID8KICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkXzsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxfbmVzdGVkID0gOTs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZC5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWRPckJ1aWxkZXI+IAogICAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZEZpZWxkQnVpbGRlcigpIHsKICAgICAgICAgIGlmIChvcHRpb25hbE5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZCgpLAogICAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgICAgb3B0aW9uYWxOZXN0ZWRfID0gbnVsbDsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZEJ1aWxkZXJfOwogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQ+IHJlcGVhdGVkTmVzdGVkXyA9CiAgICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkTmVzdGVkSXNNdXRhYmxlKCkgewogICAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgICByZXBlYXRlZE5lc3RlZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQ+KHJlcGVhdGVkTmVzdGVkXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkT3JCdWlsZGVyPiByZXBlYXRlZE5lc3RlZEJ1aWxkZXJfOwoKICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCByZXBlYXRlZF9uZXN0ZWQgPSAxMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZD4gZ2V0UmVwZWF0ZWROZXN0ZWRMaXN0KCkgewogICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWROZXN0ZWRfKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEJ1aWxkZXJfLmdldE1lc3NhZ2VMaXN0KCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlcGVhdGVkX25lc3RlZCA9IDEwOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkTmVzdGVkQ291bnQoKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZF8uc2l6ZSgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkQnVpbGRlcl8uZ2V0Q291bnQoKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgcmVwZWF0ZWRfbmVzdGVkID0gMTA7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgZ2V0UmVwZWF0ZWROZXN0ZWQoaW50IGluZGV4KSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZF8uZ2V0KGluZGV4KTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCByZXBlYXRlZF9uZXN0ZWQgPSAxMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWROZXN0ZWQoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHZhbHVlKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlcGVhdGVkX25lc3RlZCA9IDEwOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZE5lc3RlZCgKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRfLnNldChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlcGVhdGVkX25lc3RlZCA9IDEwOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgdmFsdWUpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZE5lc3RlZF8uYWRkKHZhbHVlKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXBlYXRlZE5lc3RlZEJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlcGVhdGVkX25lc3RlZCA9IDEwOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZE5lc3RlZCgKICAgICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgdmFsdWUpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZE5lc3RlZElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZE5lc3RlZF8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgcmVwZWF0ZWRfbmVzdGVkID0gMTA7PC9jb2RlPgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkKAogICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRfLmFkZChidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCByZXBlYXRlZF9uZXN0ZWQgPSAxMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWQoCiAgICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkTmVzdGVkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXBlYXRlZE5lc3RlZEJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCByZXBlYXRlZF9uZXN0ZWQgPSAxMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWROZXN0ZWQoCiAgICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkPiB2YWx1ZXMpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRJc011dGFibGUoKTsKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZE5lc3RlZF8pOwogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCByZXBlYXRlZF9uZXN0ZWQgPSAxMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZE5lc3RlZCgpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRCdWlsZGVyXy5jbGVhcigpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlcGVhdGVkX25lc3RlZCA9IDEwOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZE5lc3RlZChpbnQgaW5kZXgpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZE5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWROZXN0ZWRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVwZWF0ZWROZXN0ZWRCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlcGVhdGVkX25lc3RlZCA9IDEwOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLkJ1aWxkZXIgZ2V0UmVwZWF0ZWROZXN0ZWRCdWlsZGVyKAogICAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICAgIHJldHVybiBnZXRSZXBlYXRlZE5lc3RlZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCByZXBlYXRlZF9uZXN0ZWQgPSAxMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZE9yQnVpbGRlciBnZXRSZXBlYXRlZE5lc3RlZE9yQnVpbGRlcigKICAgICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZF8uZ2V0KGluZGV4KTsgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiByZXBlYXRlZE5lc3RlZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCByZXBlYXRlZF9uZXN0ZWQgPSAxMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWRPckJ1aWxkZXI+IAogICAgICAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRPckJ1aWxkZXJMaXN0KCkgewogICAgICAgICAgaWYgKHJlcGVhdGVkTmVzdGVkQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgICByZXR1cm4gcmVwZWF0ZWROZXN0ZWRCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkTmVzdGVkXyk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHJlcGVhdGVkX25lc3RlZCA9IDEwOzwvY29kZT4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLkJ1aWxkZXIgYWRkUmVwZWF0ZWROZXN0ZWRCdWlsZGVyKCkgewogICAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkTmVzdGVkRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCByZXBlYXRlZF9uZXN0ZWQgPSAxMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZC5CdWlsZGVyIGFkZFJlcGVhdGVkTmVzdGVkQnVpbGRlcigKICAgICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWROZXN0ZWRGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICAgIGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICAgIH0KICAgICAgICAvKioKICAgICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCByZXBlYXRlZF9uZXN0ZWQgPSAxMDs8L2NvZGU+CiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZC5CdWlsZGVyPiAKICAgICAgICAgICAgIGdldFJlcGVhdGVkTmVzdGVkQnVpbGRlckxpc3QoKSB7CiAgICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWROZXN0ZWRGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICAgIH0KICAgICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkT3JCdWlsZGVyPiAKICAgICAgICAgICAgZ2V0UmVwZWF0ZWROZXN0ZWRGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWROZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICAgIHJlcGVhdGVkTmVzdGVkQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgICByZXBlYXRlZE5lc3RlZF8sCiAgICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCksCiAgICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgICByZXBlYXRlZE5lc3RlZF8gPSBudWxsOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkTmVzdGVkQnVpbGRlcl87CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgICAgfQoKCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQpCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkPgogICAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8TmVzdGVkPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE5lc3RlZCBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgICB9CiAgICAgIH07CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZD4gcGFyc2VyKCkgewogICAgICAgIHJldHVybiBQQVJTRVI7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgICAgfQoKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfTkVTVEVEX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBvcHRpb25hbE5lc3RlZF87CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIG9wdGlvbmFsX25lc3RlZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbE5lc3RlZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIG9wdGlvbmFsX25lc3RlZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxOZXN0ZWQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgZ2V0T3B0aW9uYWxOZXN0ZWQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxfbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWRPckJ1aWxkZXIgZ2V0T3B0aW9uYWxOZXN0ZWRPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZF8gPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZC5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsTmVzdGVkXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoMSwgZ2V0T3B0aW9uYWxOZXN0ZWQoKSk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSgxLCBnZXRPcHRpb25hbE5lc3RlZCgpKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIpIG9iajsKCiAgICAgIGlmIChoYXNPcHRpb25hbE5lc3RlZCgpICE9IG90aGVyLmhhc09wdGlvbmFsTmVzdGVkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsTmVzdGVkKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbE5lc3RlZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsTmVzdGVkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9ORVNURURfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsTmVzdGVkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMiBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMiBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMiBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZEZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgb3B0aW9uYWxOZXN0ZWRfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZEJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMiBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMiByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxOZXN0ZWRfID0gb3B0aW9uYWxOZXN0ZWRCdWlsZGVyXyA9PSBudWxsCiAgICAgICAgICAgICAgPyBvcHRpb25hbE5lc3RlZF8KICAgICAgICAgICAgICA6IG9wdGlvbmFsTmVzdGVkQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMiBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsTmVzdGVkKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxOZXN0ZWQob3RoZXIuZ2V0T3B0aW9uYWxOZXN0ZWQoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBvcHRpb25hbE5lc3RlZF87CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZE9yQnVpbGRlcj4gb3B0aW9uYWxOZXN0ZWRCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIG9wdGlvbmFsX25lc3RlZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsTmVzdGVkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsTmVzdGVkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxfbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsTmVzdGVkLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBnZXRPcHRpb25hbE5lc3RlZCgpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxOZXN0ZWRfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZF87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZEJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIG9wdGlvbmFsX25lc3RlZCA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxOZXN0ZWQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkIHZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbE5lc3RlZF8gPSB2YWx1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBvcHRpb25hbF9uZXN0ZWQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsTmVzdGVkKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsTmVzdGVkQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxfbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsTmVzdGVkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZEJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSAmJgogICAgICAgICAgICBvcHRpb25hbE5lc3RlZF8gIT0gbnVsbCAmJgogICAgICAgICAgICBvcHRpb25hbE5lc3RlZF8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldE9wdGlvbmFsTmVzdGVkQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbE5lc3RlZF8gPSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxfbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsTmVzdGVkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvcHRpb25hbE5lc3RlZF8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxOZXN0ZWRCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBvcHRpb25hbF9uZXN0ZWQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuQnVpbGRlciBnZXRPcHRpb25hbE5lc3RlZEJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbE5lc3RlZEZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQgb3B0aW9uYWxfbmVzdGVkID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkT3JCdWlsZGVyIGdldE9wdGlvbmFsTmVzdGVkT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbE5lc3RlZEJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZEJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsTmVzdGVkXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBvcHRpb25hbE5lc3RlZF87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCBvcHRpb25hbF9uZXN0ZWQgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyLk5lc3RlZE9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRPcHRpb25hbE5lc3RlZEZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxOZXN0ZWRCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbE5lc3RlZEJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMi5OZXN0ZWQuQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIuTmVzdGVkT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0T3B0aW9uYWxOZXN0ZWQoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsTmVzdGVkXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiBvcHRpb25hbE5lc3RlZEJ1aWxkZXJfOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgRW51bVBhcnNlVGVzdGVyT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3RlcikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxFbnVtUGFyc2VUZXN0ZXI+IHsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIG9wdGlvbmFsX3NlcV9zbWFsbF8wX2xvd2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2VxU21hbGwwTG93ZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsU2VxU21hbGwwTG93ZmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgb3B0aW9uYWxfc2VxX3NtYWxsXzBfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2VxU21hbGwwTG93ZmllbGQuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBnZXRPcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBvcHRpb25hbF9zZXFfc21hbGxfMF9taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIG9wdGlvbmFsX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgZ2V0T3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgb3B0aW9uYWxfc2VxX3NtYWxsXzBfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNlcVNtYWxsMEhpZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsU2VxU21hbGwwSGlmaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBvcHRpb25hbF9zZXFfc21hbGxfMF9oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNlcVNtYWxsMEhpZmllbGQuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBnZXRPcHRpb25hbFNlcVNtYWxsMEhpZmllbGQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IGdldFJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgZ2V0UmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVwZWF0ZWRfc2VxX3NtYWxsXzBfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4gZ2V0UmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVwZWF0ZWRfc2VxX3NtYWxsXzBfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVwZWF0ZWRfc2VxX3NtYWxsXzBfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBnZXRSZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXBlYXRlZF9zZXFfc21hbGxfMF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4gZ2V0UmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXBlYXRlZF9zZXFfc21hbGxfMF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXBlYXRlZF9zZXFfc21hbGxfMF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBnZXRSZXBlYXRlZFNlcVNtYWxsMEhpZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IGdldFBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBwYWNrZWRfc2VxX3NtYWxsXzBfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcGFja2VkX3NlcV9zbWFsbF8wX2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBnZXRQYWNrZWRTZXFTbWFsbDBMb3dmaWVsZChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcGFja2VkX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2VxU21hbGwwTWlkZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4gZ2V0UGFja2VkU2VxU21hbGwwTWlkZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2VxU21hbGwwTWlkZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBwYWNrZWRfc2VxX3NtYWxsXzBfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIGdldFBhY2tlZFNlcVNtYWxsME1pZGZpZWxkKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBwYWNrZWRfc2VxX3NtYWxsXzBfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcVNtYWxsMEhpZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4gZ2V0UGFja2VkU2VxU21hbGwwSGlmaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcGFja2VkX3NlcV9zbWFsbF8wX2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZXFTbWFsbDBIaWZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2VxU21hbGwwSGlmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZXFTbWFsbDBIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIGdldFBhY2tlZFNlcVNtYWxsMEhpZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIG9wdGlvbmFsX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsU2VxU21hbGwxTG93ZmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgb3B0aW9uYWxfc2VxX3NtYWxsXzFfbG93ZmllbGQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGQuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBnZXRPcHRpb25hbFNlcVNtYWxsMUxvd2ZpZWxkKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBvcHRpb25hbF9zZXFfc21hbGxfMV9taWRmaWVsZCA9IDEwMDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNlcVNtYWxsMU1pZGZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFNlcVNtYWxsMU1pZGZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIG9wdGlvbmFsX3NlcV9zbWFsbF8xX21pZGZpZWxkID0gMTAwNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNlcVNtYWxsMU1pZGZpZWxkLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgZ2V0T3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgb3B0aW9uYWxfc2VxX3NtYWxsXzFfaGlmaWVsZCA9IDEwMDAwMDQ7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNlcVNtYWxsMUhpZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsU2VxU21hbGwxSGlmaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBvcHRpb25hbF9zZXFfc21hbGxfMV9oaWZpZWxkID0gMTAwMDAwNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNlcVNtYWxsMUhpZmllbGQuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBnZXRPcHRpb25hbFNlcVNtYWxsMUhpZmllbGQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDE+IGdldFJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgZ2V0UmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVwZWF0ZWRfc2VxX3NtYWxsXzFfbWlkZmllbGQgPSAxMDA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4gZ2V0UmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVwZWF0ZWRfc2VxX3NtYWxsXzFfbWlkZmllbGQgPSAxMDA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVwZWF0ZWRfc2VxX3NtYWxsXzFfbWlkZmllbGQgPSAxMDA1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBnZXRSZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXBlYXRlZF9zZXFfc21hbGxfMV9oaWZpZWxkID0gMTAwMDAwNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4gZ2V0UmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXBlYXRlZF9zZXFfc21hbGxfMV9oaWZpZWxkID0gMTAwMDAwNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXBlYXRlZF9zZXFfc21hbGxfMV9oaWZpZWxkID0gMTAwMDAwNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBnZXRSZXBlYXRlZFNlcVNtYWxsMUhpZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHBhY2tlZF9zZXFfc21hbGxfMV9sb3dmaWVsZCA9IDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDE+IGdldFBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBwYWNrZWRfc2VxX3NtYWxsXzFfbG93ZmllbGQgPSA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBnZXRQYWNrZWRTZXFTbWFsbDFMb3dmaWVsZChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX21pZGZpZWxkID0gMTAwNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2VxU21hbGwxTWlkZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4gZ2V0UGFja2VkU2VxU21hbGwxTWlkZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHBhY2tlZF9zZXFfc21hbGxfMV9taWRmaWVsZCA9IDEwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2VxU21hbGwxTWlkZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBwYWNrZWRfc2VxX3NtYWxsXzFfbWlkZmllbGQgPSAxMDA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIGdldFBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBwYWNrZWRfc2VxX3NtYWxsXzFfaGlmaWVsZCA9IDEwMDAwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcVNtYWxsMUhpZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4gZ2V0UGFja2VkU2VxU21hbGwxSGlmaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX2hpZmllbGQgPSAxMDAwMDA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZXFTbWFsbDFIaWZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2VxU21hbGwxSGlmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHBhY2tlZF9zZXFfc21hbGxfMV9oaWZpZWxkID0gMTAwMDAwNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZXFTbWFsbDFIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIGdldFBhY2tlZFNlcVNtYWxsMUhpZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2Ugb3B0aW9uYWxfc2VxX2xhcmdlX2xvd2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxTZXFMYXJnZUxvd2ZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2Ugb3B0aW9uYWxfc2VxX2xhcmdlX2xvd2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNlcUxhcmdlTG93ZmllbGQuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIGdldE9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBvcHRpb25hbF9zZXFfbGFyZ2VfbWlkZmllbGQgPSAxMDA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFNlcUxhcmdlTWlkZmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBvcHRpb25hbF9zZXFfbGFyZ2VfbWlkZmllbGQgPSAxMDA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgZ2V0T3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIG9wdGlvbmFsX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2VxTGFyZ2VIaWZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFNlcUxhcmdlSGlmaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIG9wdGlvbmFsX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNlcUxhcmdlSGlmaWVsZC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgZ2V0T3B0aW9uYWxTZXFMYXJnZUhpZmllbGQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX2xvd2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPiBnZXRSZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX2xvd2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDg7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBnZXRSZXBlYXRlZFNlcUxhcmdlTG93ZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX21pZGZpZWxkID0gMTAwODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPiBnZXRSZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX21pZGZpZWxkID0gMTAwODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9taWRmaWVsZCA9IDEwMDg7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBnZXRSZXBlYXRlZFNlcUxhcmdlTWlkZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX2hpZmllbGQgPSAxMDAwMDA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4gZ2V0UmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX2hpZmllbGQgPSAxMDAwMDA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwODs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgZ2V0UmVwZWF0ZWRTZXFMYXJnZUhpZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcUxhcmdlTG93ZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPiBnZXRQYWNrZWRTZXFMYXJnZUxvd2ZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHBhY2tlZF9zZXFfbGFyZ2VfbG93ZmllbGQgPSA5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2VxTGFyZ2VMb3dmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2VxTGFyZ2VMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIGdldFBhY2tlZFNlcUxhcmdlTG93ZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9taWRmaWVsZCA9IDEwMDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcUxhcmdlTWlkZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPiBnZXRQYWNrZWRTZXFMYXJnZU1pZGZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHBhY2tlZF9zZXFfbGFyZ2VfbWlkZmllbGQgPSAxMDA5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZXFMYXJnZU1pZGZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkU2VxTGFyZ2VNaWRmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9taWRmaWVsZCA9IDEwMDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIGdldFBhY2tlZFNlcUxhcmdlTWlkZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2VxTGFyZ2VIaWZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4gZ2V0UGFja2VkU2VxTGFyZ2VIaWZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHBhY2tlZF9zZXFfbGFyZ2VfaGlmaWVsZCA9IDEwMDAwMDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNlcUxhcmdlSGlmaWVsZC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZFNlcUxhcmdlSGlmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZXFMYXJnZUhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBnZXRQYWNrZWRTZXFMYXJnZUhpZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IG9wdGlvbmFsX2FyYml0cmFyeV9sb3dmaWVsZCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBvcHRpb25hbF9hcmJpdHJhcnlfbG93ZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEFyYml0cmFyeUxvd2ZpZWxkLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgZ2V0T3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgb3B0aW9uYWxfYXJiaXRyYXJ5X21pZGZpZWxkID0gMTAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQXJiaXRyYXJ5TWlkZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsQXJiaXRyYXJ5TWlkZmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgb3B0aW9uYWxfYXJiaXRyYXJ5X21pZGZpZWxkID0gMTAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgZ2V0T3B0aW9uYWxBcmJpdHJhcnlNaWRmaWVsZCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgb3B0aW9uYWxfYXJiaXRyYXJ5X2hpZmllbGQgPSAxMDAwMDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEFyYml0cmFyeUhpZmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgb3B0aW9uYWxfYXJiaXRyYXJ5X2hpZmllbGQgPSAxMDAwMDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQXJiaXRyYXJ5SGlmaWVsZC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IGdldE9wdGlvbmFsQXJiaXRyYXJ5SGlmaWVsZCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X2xvd2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PiBnZXRSZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXBlYXRlZF9hcmJpdHJhcnlfbG93ZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9sb3dmaWVsZCA9IDExOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBnZXRSZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXBlYXRlZF9hcmJpdHJhcnlfbWlkZmllbGQgPSAxMDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gZ2V0UmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X21pZGZpZWxkID0gMTAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9taWRmaWVsZCA9IDEwMTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IGdldFJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9oaWZpZWxkID0gMTAwMDAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEFyYml0cmFyeUhpZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gZ2V0UmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXBlYXRlZF9hcmJpdHJhcnlfaGlmaWVsZCA9IDEwMDAwMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X2hpZmllbGQgPSAxMDAwMDExOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IGdldFJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9sb3dmaWVsZCA9IDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRBcmJpdHJhcnlMb3dmaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PiBnZXRQYWNrZWRBcmJpdHJhcnlMb3dmaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9sb3dmaWVsZCA9IDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRBcmJpdHJhcnlMb3dmaWVsZC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9sb3dmaWVsZCA9IDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IGdldFBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X21pZGZpZWxkID0gMTAxMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkQXJiaXRyYXJ5TWlkZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gZ2V0UGFja2VkQXJiaXRyYXJ5TWlkZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHBhY2tlZF9hcmJpdHJhcnlfbWlkZmllbGQgPSAxMDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEFyYml0cmFyeU1pZGZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9taWRmaWVsZCA9IDEwMTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkQXJiaXRyYXJ5TWlkZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgZ2V0UGFja2VkQXJiaXRyYXJ5TWlkZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHBhY2tlZF9hcmJpdHJhcnlfaGlmaWVsZCA9IDEwMDAwMTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEFyYml0cmFyeUhpZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gZ2V0UGFja2VkQXJiaXRyYXJ5SGlmaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9oaWZpZWxkID0gMTAwMDAxMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkQXJiaXRyYXJ5SGlmaWVsZC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEFyYml0cmFyeUhpZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X2hpZmllbGQgPSAxMDAwMDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEFyYml0cmFyeUhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgZ2V0UGFja2VkQXJiaXRyYXJ5SGlmaWVsZChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvdGhlckZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPdGhlckZpZWxkKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBbiBhcmJpdHJhcnkgZmllbGQgd2UgY2FuIGFwcGVuZCB0byB0byBicmVhayB0aGUgcnVucyBvZiByZXBlYXRlZCBmaWVsZHMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdGhlcl9maWVsZCA9IDk5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG90aGVyRmllbGQuCiAgICAgKi8KICAgIGludCBnZXRPdGhlckZpZWxkKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVGhpcyBtZXNzYWdlIGNvbnRhaW5zIGRpZmZlcmVudCBraW5kIG9mIGVudW1zIHRvIGV4ZXJjaXNlIHRoZSBkaWZmZXJlbnQKICAgKiBwYXJzZXJzIGluIHRhYmxlLWRyaXZlbi4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlcn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEVudW1QYXJzZVRlc3RlciBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVNZXNzYWdlPAogICAgICAgIEVudW1QYXJzZVRlc3Rlcj4gaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3RlcikKICAgICAgRW51bVBhcnNlVGVzdGVyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBFbnVtUGFyc2VUZXN0ZXIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgRW51bVBhcnNlVGVzdGVyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBFbnVtUGFyc2VUZXN0ZXIoKSB7CiAgICAgIG9wdGlvbmFsU2VxU21hbGwwTG93ZmllbGRfID0gMDsKICAgICAgb3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZF8gPSAwOwogICAgICBvcHRpb25hbFNlcVNtYWxsMEhpZmllbGRfID0gMDsKICAgICAgcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcGFja2VkU2VxU21hbGwwSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIG9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGRfID0gMTsKICAgICAgb3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZF8gPSAxOwogICAgICBvcHRpb25hbFNlcVNtYWxsMUhpZmllbGRfID0gMTsKICAgICAgcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcGFja2VkU2VxU21hbGwxSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIG9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZF8gPSAtMTsKICAgICAgb3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkXyA9IC0xOwogICAgICBvcHRpb25hbFNlcUxhcmdlSGlmaWVsZF8gPSAtMTsKICAgICAgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHBhY2tlZFNlcUxhcmdlSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIG9wdGlvbmFsQXJiaXRyYXJ5TG93ZmllbGRfID0gLTEyMzEyMzsKICAgICAgb3B0aW9uYWxBcmJpdHJhcnlNaWRmaWVsZF8gPSAtMTIzMTIzOwogICAgICBvcHRpb25hbEFyYml0cmFyeUhpZmllbGRfID0gLTEyMzEyMzsKICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwYWNrZWRBcmJpdHJhcnlMb3dmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcGFja2VkQXJiaXRyYXJ5SGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgRW51bVBhcnNlVGVzdGVyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRW51bVBhcnNlVGVzdGVyX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRW51bVBhcnNlVGVzdGVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIC8qKgogICAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMH0KICAgICAqLwogICAgcHVibGljIGVudW0gU2VxU21hbGwwCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX1NNQUxMXzBfREVGQVVMVCA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgU0VRX1NNQUxMXzBfREVGQVVMVCgwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9TTUFMTF8wXzEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIFNFUV9TTUFMTF8wXzEoMSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfU01BTExfMF8yID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfU01BTExfMF8yKDIpLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX1NNQUxMXzBfREVGQVVMVCA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX1NNQUxMXzBfREVGQVVMVF9WQUxVRSA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfU01BTExfMF8xID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfU01BTExfMF8xX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9TTUFMTF8wXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUV9TTUFMTF8wXzJfVkFMVUUgPSAyOwoKCiAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgU2VxU21hbGwwIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBTZXFTbWFsbDAgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIFNFUV9TTUFMTF8wX0RFRkFVTFQ7CiAgICAgICAgICBjYXNlIDE6IHJldHVybiBTRVFfU01BTExfMF8xOwogICAgICAgICAgY2FzZSAyOiByZXR1cm4gU0VRX1NNQUxMXzBfMjsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFNlcVNtYWxsMD4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIFNlcVNtYWxsMD4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFNlcVNtYWxsMD4oKSB7CiAgICAgICAgICAgICAgcHVibGljIFNlcVNtYWxsMCBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gU2VxU21hbGwwLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgICB9CiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2VxU21hbGwwW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIFNlcVNtYWxsMCB2YWx1ZU9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgICBwcml2YXRlIFNlcVNtYWxsMChpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDApCiAgICB9CgogICAgLyoqCiAgICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxfQogICAgICovCiAgICBwdWJsaWMgZW51bSBTZXFTbWFsbDEKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfU01BTExfMV9ERUZBVUxUID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfU01BTExfMV9ERUZBVUxUKDEpLAogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX1NNQUxMXzFfMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgU0VRX1NNQUxMXzFfMigyKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9TTUFMTF8xXzMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIFNFUV9TTUFMTF8xXzMoMyksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfU01BTExfMV9ERUZBVUxUID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfU01BTExfMV9ERUZBVUxUX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9TTUFMTF8xXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUV9TTUFMTF8xXzJfVkFMVUUgPSAyOwogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX1NNQUxMXzFfMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX1NNQUxMXzFfM19WQUxVRSA9IDM7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBTZXFTbWFsbDEgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIFNlcVNtYWxsMSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAxOiByZXR1cm4gU0VRX1NNQUxMXzFfREVGQVVMVDsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIFNFUV9TTUFMTF8xXzI7CiAgICAgICAgICBjYXNlIDM6IHJldHVybiBTRVFfU01BTExfMV8zOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8U2VxU21hbGwxPgogICAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgICAgfQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgICAgU2VxU21hbGwxPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8U2VxU21hbGwxPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgU2VxU21hbGwxIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBTZXFTbWFsbDEuZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwoKICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgICAgZ2V0VmFsdWVEZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCkuZ2V0VmFsdWVzKCkuZ2V0KG9yZGluYWwoKSk7CiAgICAgIH0KICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDEpOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTZXFTbWFsbDFbXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgU2VxU21hbGwxIHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgU2VxU21hbGwxKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSkKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZX0KICAgICAqLwogICAgcHVibGljIGVudW0gU2VxTGFyZ2UKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfREVGQVVMVCA9IC0xOzwvY29kZT4KICAgICAgICovCiAgICAgIFNFUV9MQVJHRV9ERUZBVUxUKC0xKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8wID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfMCgwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8xID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfMSgxKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8yID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfMigyKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8zID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfMygzKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV80ID0gNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfNCg0KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV81ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfNSg1KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV82ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfNig2KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV83ID0gNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfNyg3KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV84ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfOCg4KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV85ID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfOSg5KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8xMCA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIFNFUV9MQVJHRV8xMCgxMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfMTEoMTEpLAogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgU0VRX0xBUkdFXzEyKDEyKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8xMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIFNFUV9MQVJHRV8xMygxMyksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfMTQoMTQpLAogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzE1ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgU0VRX0xBUkdFXzE1KDE1KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8xNiA9IDE2OzwvY29kZT4KICAgICAgICovCiAgICAgIFNFUV9MQVJHRV8xNigxNiksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfMTcoMTcpLAogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzE4ID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgU0VRX0xBUkdFXzE4KDE4KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8xOSA9IDE5OzwvY29kZT4KICAgICAgICovCiAgICAgIFNFUV9MQVJHRV8xOSgxOSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfMjAoMjApLAogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgU0VRX0xBUkdFXzIxKDIxKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8yMiA9IDIyOzwvY29kZT4KICAgICAgICovCiAgICAgIFNFUV9MQVJHRV8yMigyMiksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfMjMoMjMpLAogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgU0VRX0xBUkdFXzI0KDI0KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8yNSA9IDI1OzwvY29kZT4KICAgICAgICovCiAgICAgIFNFUV9MQVJHRV8yNSgyNSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfMjYoMjYpLAogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgU0VRX0xBUkdFXzI3KDI3KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8yOCA9IDI4OzwvY29kZT4KICAgICAgICovCiAgICAgIFNFUV9MQVJHRV8yOCgyOCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfMjkoMjkpLAogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgU0VRX0xBUkdFXzMwKDMwKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8zMSA9IDMxOzwvY29kZT4KICAgICAgICovCiAgICAgIFNFUV9MQVJHRV8zMSgzMSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBTRVFfTEFSR0VfMzIoMzIpLAogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzMzID0gMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgU0VRX0xBUkdFXzMzKDMzKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV9ERUZBVUxUID0gLTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX0xBUkdFX0RFRkFVTFRfVkFMVUUgPSAtMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8wID0gMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfTEFSR0VfMF9WQUxVRSA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX0xBUkdFXzFfVkFMVUUgPSAxOwogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUV9MQVJHRV8yX1ZBTFVFID0gMjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8zID0gMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfTEFSR0VfM19WQUxVRSA9IDM7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfNCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX0xBUkdFXzRfVkFMVUUgPSA0OwogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzUgPSA1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUV9MQVJHRV81X1ZBTFVFID0gNTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV82ID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfTEFSR0VfNl9WQUxVRSA9IDY7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfNyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX0xBUkdFXzdfVkFMVUUgPSA3OwogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzggPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUV9MQVJHRV84X1ZBTFVFID0gODsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV85ID0gOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfTEFSR0VfOV9WQUxVRSA9IDk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfTEFSR0VfMTBfVkFMVUUgPSAxMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8xMSA9IDExOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUV9MQVJHRV8xMV9WQUxVRSA9IDExOwogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX0xBUkdFXzEyX1ZBTFVFID0gMTI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfTEFSR0VfMTNfVkFMVUUgPSAxMzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8xNCA9IDE0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUV9MQVJHRV8xNF9WQUxVRSA9IDE0OwogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzE1ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX0xBUkdFXzE1X1ZBTFVFID0gMTU7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfTEFSR0VfMTZfVkFMVUUgPSAxNjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8xNyA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUV9MQVJHRV8xN19WQUxVRSA9IDE3OwogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzE4ID0gMTg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX0xBUkdFXzE4X1ZBTFVFID0gMTg7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfTEFSR0VfMTlfVkFMVUUgPSAxOTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8yMCA9IDIwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUV9MQVJHRV8yMF9WQUxVRSA9IDIwOwogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzIxID0gMjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX0xBUkdFXzIxX1ZBTFVFID0gMjE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfTEFSR0VfMjJfVkFMVUUgPSAyMjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8yMyA9IDIzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUV9MQVJHRV8yM19WQUxVRSA9IDIzOwogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX0xBUkdFXzI0X1ZBTFVFID0gMjQ7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfTEFSR0VfMjVfVkFMVUUgPSAyNTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8yNiA9IDI2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUV9MQVJHRV8yNl9WQUxVRSA9IDI2OwogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX0xBUkdFXzI3X1ZBTFVFID0gMjc7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMjggPSAyODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfTEFSR0VfMjhfVkFMVUUgPSAyODsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8yOSA9IDI5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUV9MQVJHRV8yOV9WQUxVRSA9IDI5OwogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzMwID0gMzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX0xBUkdFXzMwX1ZBTFVFID0gMzA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5TRVFfTEFSR0VfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTRVFfTEFSR0VfMzFfVkFMVUUgPSAzMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPlNFUV9MQVJHRV8zMiA9IDMyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUV9MQVJHRV8zMl9WQUxVRSA9IDMyOwogICAgICAvKioKICAgICAgICogPGNvZGU+U0VRX0xBUkdFXzMzID0gMzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU0VRX0xBUkdFXzMzX1ZBTFVFID0gMzM7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBTZXFMYXJnZSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgU2VxTGFyZ2UgZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgLTE6IHJldHVybiBTRVFfTEFSR0VfREVGQVVMVDsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIFNFUV9MQVJHRV8wOwogICAgICAgICAgY2FzZSAxOiByZXR1cm4gU0VRX0xBUkdFXzE7CiAgICAgICAgICBjYXNlIDI6IHJldHVybiBTRVFfTEFSR0VfMjsKICAgICAgICAgIGNhc2UgMzogcmV0dXJuIFNFUV9MQVJHRV8zOwogICAgICAgICAgY2FzZSA0OiByZXR1cm4gU0VRX0xBUkdFXzQ7CiAgICAgICAgICBjYXNlIDU6IHJldHVybiBTRVFfTEFSR0VfNTsKICAgICAgICAgIGNhc2UgNjogcmV0dXJuIFNFUV9MQVJHRV82OwogICAgICAgICAgY2FzZSA3OiByZXR1cm4gU0VRX0xBUkdFXzc7CiAgICAgICAgICBjYXNlIDg6IHJldHVybiBTRVFfTEFSR0VfODsKICAgICAgICAgIGNhc2UgOTogcmV0dXJuIFNFUV9MQVJHRV85OwogICAgICAgICAgY2FzZSAxMDogcmV0dXJuIFNFUV9MQVJHRV8xMDsKICAgICAgICAgIGNhc2UgMTE6IHJldHVybiBTRVFfTEFSR0VfMTE7CiAgICAgICAgICBjYXNlIDEyOiByZXR1cm4gU0VRX0xBUkdFXzEyOwogICAgICAgICAgY2FzZSAxMzogcmV0dXJuIFNFUV9MQVJHRV8xMzsKICAgICAgICAgIGNhc2UgMTQ6IHJldHVybiBTRVFfTEFSR0VfMTQ7CiAgICAgICAgICBjYXNlIDE1OiByZXR1cm4gU0VRX0xBUkdFXzE1OwogICAgICAgICAgY2FzZSAxNjogcmV0dXJuIFNFUV9MQVJHRV8xNjsKICAgICAgICAgIGNhc2UgMTc6IHJldHVybiBTRVFfTEFSR0VfMTc7CiAgICAgICAgICBjYXNlIDE4OiByZXR1cm4gU0VRX0xBUkdFXzE4OwogICAgICAgICAgY2FzZSAxOTogcmV0dXJuIFNFUV9MQVJHRV8xOTsKICAgICAgICAgIGNhc2UgMjA6IHJldHVybiBTRVFfTEFSR0VfMjA7CiAgICAgICAgICBjYXNlIDIxOiByZXR1cm4gU0VRX0xBUkdFXzIxOwogICAgICAgICAgY2FzZSAyMjogcmV0dXJuIFNFUV9MQVJHRV8yMjsKICAgICAgICAgIGNhc2UgMjM6IHJldHVybiBTRVFfTEFSR0VfMjM7CiAgICAgICAgICBjYXNlIDI0OiByZXR1cm4gU0VRX0xBUkdFXzI0OwogICAgICAgICAgY2FzZSAyNTogcmV0dXJuIFNFUV9MQVJHRV8yNTsKICAgICAgICAgIGNhc2UgMjY6IHJldHVybiBTRVFfTEFSR0VfMjY7CiAgICAgICAgICBjYXNlIDI3OiByZXR1cm4gU0VRX0xBUkdFXzI3OwogICAgICAgICAgY2FzZSAyODogcmV0dXJuIFNFUV9MQVJHRV8yODsKICAgICAgICAgIGNhc2UgMjk6IHJldHVybiBTRVFfTEFSR0VfMjk7CiAgICAgICAgICBjYXNlIDMwOiByZXR1cm4gU0VRX0xBUkdFXzMwOwogICAgICAgICAgY2FzZSAzMTogcmV0dXJuIFNFUV9MQVJHRV8zMTsKICAgICAgICAgIGNhc2UgMzI6IHJldHVybiBTRVFfTEFSR0VfMzI7CiAgICAgICAgICBjYXNlIDMzOiByZXR1cm4gU0VRX0xBUkdFXzMzOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8U2VxTGFyZ2U+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBTZXFMYXJnZT4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFNlcUxhcmdlPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgU2VxTGFyZ2UgZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIFNlcUxhcmdlLmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgICB9CiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgyKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU2VxTGFyZ2VbXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgU2VxTGFyZ2UgdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBTZXFMYXJnZShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSkKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnl9CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIEFyYml0cmFyeQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkFSQklUUkFSWV9ERUZBVUxUID0gLTEyMzEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBBUkJJVFJBUllfREVGQVVMVCgtMTIzMTIzKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkFSQklUUkFSWV8xID0gLTEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBBUkJJVFJBUllfMSgtMTIzKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkFSQklUUkFSWV8yID0gMjEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEFSQklUUkFSWV8yKDIxMyksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BUkJJVFJBUllfMyA9IDIxMzIxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBBUkJJVFJBUllfMygyMTMyMTMpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QVJCSVRSQVJZX01JTiA9IC0yMTQ3NDgzNjQ4OzwvY29kZT4KICAgICAgICovCiAgICAgIEFSQklUUkFSWV9NSU4oLTIxNDc0ODM2NDgpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QVJCSVRSQVJZX01BWCA9IDIxNDc0ODM2NDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQVJCSVRSQVJZX01BWCgyMTQ3NDgzNjQ3KSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkFSQklUUkFSWV9ERUZBVUxUID0gLTEyMzEyMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBUkJJVFJBUllfREVGQVVMVF9WQUxVRSA9IC0xMjMxMjM7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BUkJJVFJBUllfMSA9IC0xMjM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVJCSVRSQVJZXzFfVkFMVUUgPSAtMTIzOwogICAgICAvKioKICAgICAgICogPGNvZGU+QVJCSVRSQVJZXzIgPSAyMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQVJCSVRSQVJZXzJfVkFMVUUgPSAyMTM7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BUkJJVFJBUllfMyA9IDIxMzIxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBUkJJVFJBUllfM19WQUxVRSA9IDIxMzIxMzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkFSQklUUkFSWV9NSU4gPSAtMjE0NzQ4MzY0ODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBUkJJVFJBUllfTUlOX1ZBTFVFID0gLTIxNDc0ODM2NDg7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BUkJJVFJBUllfTUFYID0gMjE0NzQ4MzY0Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBUkJJVFJBUllfTUFYX1ZBTFVFID0gMjE0NzQ4MzY0NzsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIEFyYml0cmFyeSB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgQXJiaXRyYXJ5IGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIC0xMjMxMjM6IHJldHVybiBBUkJJVFJBUllfREVGQVVMVDsKICAgICAgICAgIGNhc2UgLTEyMzogcmV0dXJuIEFSQklUUkFSWV8xOwogICAgICAgICAgY2FzZSAyMTM6IHJldHVybiBBUkJJVFJBUllfMjsKICAgICAgICAgIGNhc2UgMjEzMjEzOiByZXR1cm4gQVJCSVRSQVJZXzM7CiAgICAgICAgICBjYXNlIC0yMTQ3NDgzNjQ4OiByZXR1cm4gQVJCSVRSQVJZX01JTjsKICAgICAgICAgIGNhc2UgMjE0NzQ4MzY0NzogcmV0dXJuIEFSQklUUkFSWV9NQVg7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxBcmJpdHJhcnk+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBBcmJpdHJhcnk+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxBcmJpdHJhcnk+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBBcmJpdHJhcnkgZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIEFyYml0cmFyeS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMyk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIEFyYml0cmFyeVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBBcmJpdHJhcnkgdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBBcmJpdHJhcnkoaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5KQogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TRVFfU01BTExfMF9MT1dGSUVMRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZXFTbWFsbDBMb3dmaWVsZF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBvcHRpb25hbF9zZXFfc21hbGxfMF9sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIG9wdGlvbmFsX3NlcV9zbWFsbF8wX2xvd2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgZ2V0T3B0aW9uYWxTZXFTbWFsbDBMb3dmaWVsZCgpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMC5mb3JOdW1iZXIob3B0aW9uYWxTZXFTbWFsbDBMb3dmaWVsZF8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuU0VRX1NNQUxMXzBfREVGQVVMVCA6IHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TRVFfU01BTExfMF9NSURGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDAxOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBvcHRpb25hbF9zZXFfc21hbGxfMF9taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIG9wdGlvbmFsX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgZ2V0T3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZCgpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMC5mb3JOdW1iZXIob3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZF8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuU0VRX1NNQUxMXzBfREVGQVVMVCA6IHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TRVFfU01BTExfMF9ISUZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDAwMDE7CiAgICBwcml2YXRlIGludCBvcHRpb25hbFNlcVNtYWxsMEhpZmllbGRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgb3B0aW9uYWxfc2VxX3NtYWxsXzBfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNlcVNtYWxsMEhpZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2VxU21hbGwwSGlmaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBvcHRpb25hbF9zZXFfc21hbGxfMF9oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNlcVNtYWxsMEhpZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBnZXRPcHRpb25hbFNlcVNtYWxsMEhpZmllbGQoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuZm9yTnVtYmVyKG9wdGlvbmFsU2VxU21hbGwwSGlmaWVsZF8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuU0VRX1NNQUxMXzBfREVGQVVMVCA6IHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TRVFfU01BTExfMF9MT1dGSUVMRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IHJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGRfY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMC5TRVFfU01BTExfMF9ERUZBVUxUIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVwZWF0ZWRfc2VxX3NtYWxsXzBfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IGdldFJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwPihyZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkXywgcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF9jb252ZXJ0ZXJfKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVwZWF0ZWRfc2VxX3NtYWxsXzBfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXBlYXRlZF9zZXFfc21hbGxfMF9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBnZXRSZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0VRX1NNQUxMXzBfTUlERklFTERfRklFTERfTlVNQkVSID0gMTAwMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwPiByZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMC5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuU0VRX1NNQUxMXzBfREVGQVVMVCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwPiBnZXRSZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4ocmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8sIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVwZWF0ZWRfc2VxX3NtYWxsXzBfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgZ2V0UmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfLmdldChpbmRleCkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NFUV9TTUFMTF8wX0hJRklFTERfRklFTERfTlVNQkVSID0gMTAwMDAwMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4oKSB7CiAgICAgICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLlNFUV9TTUFMTF8wX0RFRkFVTFQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXBlYXRlZF9zZXFfc21hbGxfMF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IGdldFJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+KHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8sIHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF9jb252ZXJ0ZXJfKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVwZWF0ZWRfc2VxX3NtYWxsXzBfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBnZXRSZXBlYXRlZFNlcVNtYWxsMEhpZmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1NFUV9TTUFMTF8wX0xPV0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMC5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuU0VRX1NNQUxMXzBfREVGQVVMVCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwPiBnZXRQYWNrZWRTZXFTbWFsbDBMb3dmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+KHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXywgcGFja2VkU2VxU21hbGwwTG93ZmllbGRfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBwYWNrZWRfc2VxX3NtYWxsXzBfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBnZXRQYWNrZWRTZXFTbWFsbDBMb3dmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemU7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1NFUV9TTUFMTF8wX01JREZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMC5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuU0VRX1NNQUxMXzBfREVGQVVMVCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwPiBnZXRQYWNrZWRTZXFTbWFsbDBNaWRmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+KHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXywgcGFja2VkU2VxU21hbGwwTWlkZmllbGRfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNlcVNtYWxsME1pZGZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTZXFTbWFsbDBNaWRmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBwYWNrZWRfc2VxX3NtYWxsXzBfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBnZXRQYWNrZWRTZXFTbWFsbDBNaWRmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRTZXFTbWFsbDBNaWRmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRTZXFTbWFsbDBNaWRmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemU7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1NFUV9TTUFMTF8wX0hJRklFTERfRklFTERfTlVNQkVSID0gMTAwMDAwMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2VkU2VxU21hbGwwSGlmaWVsZF87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwPiBwYWNrZWRTZXFTbWFsbDBIaWZpZWxkX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMC5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuU0VRX1NNQUxMXzBfREVGQVVMVCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2VxU21hbGwwSGlmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4gZ2V0UGFja2VkU2VxU21hbGwwSGlmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+KHBhY2tlZFNlcVNtYWxsMEhpZmllbGRfLCBwYWNrZWRTZXFTbWFsbDBIaWZpZWxkX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBwYWNrZWRfc2VxX3NtYWxsXzBfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNlcVNtYWxsMEhpZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2VxU21hbGwwSGlmaWVsZENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkU2VxU21hbGwwSGlmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBwYWNrZWRfc2VxX3NtYWxsXzBfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2VxU21hbGwwSGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgZ2V0UGFja2VkU2VxU21hbGwwSGlmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNlcVNtYWxsMEhpZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHBhY2tlZFNlcVNtYWxsMEhpZmllbGRfLmdldChpbmRleCkpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkU2VxU21hbGwwSGlmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemU7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0VRX1NNQUxMXzFfTE9XRklFTERfRklFTERfTlVNQkVSID0gNDsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGRfID0gMTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgb3B0aW9uYWxfc2VxX3NtYWxsXzFfbG93ZmllbGQgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTZXFTbWFsbDFMb3dmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTZXFTbWFsbDFMb3dmaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBvcHRpb25hbF9zZXFfc21hbGxfMV9sb3dmaWVsZCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZXFTbWFsbDFMb3dmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIGdldE9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGQoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKG9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGRfKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLlNFUV9TTUFMTF8xX0RFRkFVTFQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0VRX1NNQUxMXzFfTUlERklFTERfRklFTERfTlVNQkVSID0gMTAwNDsKICAgIHByaXZhdGUgaW50IG9wdGlvbmFsU2VxU21hbGwxTWlkZmllbGRfID0gMTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgb3B0aW9uYWxfc2VxX3NtYWxsXzFfbWlkZmllbGQgPSAxMDA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBvcHRpb25hbF9zZXFfc21hbGxfMV9taWRmaWVsZCA9IDEwMDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIGdldE9wdGlvbmFsU2VxU21hbGwxTWlkZmllbGQoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKG9wdGlvbmFsU2VxU21hbGwxTWlkZmllbGRfKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLlNFUV9TTUFMTF8xX0RFRkFVTFQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0VRX1NNQUxMXzFfSElGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDAwMDA0OwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZXFTbWFsbDFIaWZpZWxkXyA9IDE7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIG9wdGlvbmFsX3NlcV9zbWFsbF8xX2hpZmllbGQgPSAxMDAwMDA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTZXFTbWFsbDFIaWZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFNlcVNtYWxsMUhpZmllbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgb3B0aW9uYWxfc2VxX3NtYWxsXzFfaGlmaWVsZCA9IDEwMDAwMDQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZXFTbWFsbDFIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgZ2V0T3B0aW9uYWxTZXFTbWFsbDFIaWZpZWxkKCkgewogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLmZvck51bWJlcihvcHRpb25hbFNlcVNtYWxsMUhpZmllbGRfKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLlNFUV9TTUFMTF8xX0RFRkFVTFQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0VRX1NNQUxMXzFfTE9XRklFTERfRklFTERfTlVNQkVSID0gNTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPiByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuU0VRX1NNQUxMXzFfREVGQVVMVCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPiBnZXRSZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4ocmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF8sIHJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVwZWF0ZWRfc2VxX3NtYWxsXzFfbG93ZmllbGQgPSA1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgZ2V0UmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfLmdldChpbmRleCkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NFUV9TTUFMTF8xX01JREZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4gcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLlNFUV9TTUFMTF8xX0RFRkFVTFQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXBlYXRlZF9zZXFfc21hbGxfMV9taWRmaWVsZCA9IDEwMDU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4gZ2V0UmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDE+KHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfLCByZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXBlYXRlZF9zZXFfc21hbGxfMV9taWRmaWVsZCA9IDEwMDU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX21pZGZpZWxkID0gMTAwNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIGdldFJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkXy5nZXQoaW5kZXgpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TRVFfU01BTExfMV9ISUZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDAwMDU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZF87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPiByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDE+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMS5TRVFfU01BTExfMV9ERUZBVUxUIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVwZWF0ZWRfc2VxX3NtYWxsXzFfaGlmaWVsZCA9IDEwMDAwMDU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPiBnZXRSZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPihyZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfLCByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX2hpZmllbGQgPSAxMDAwMDA1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXBlYXRlZF9zZXFfc21hbGxfMV9oaWZpZWxkID0gMTAwMDAwNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgZ2V0UmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfLmdldChpbmRleCkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9TRVFfU01BTExfMV9MT1dGSUVMRF9GSUVMRF9OVU1CRVIgPSA2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPiBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLlNFUV9TTUFMTF8xX0RFRkFVTFQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBwYWNrZWRfc2VxX3NtYWxsXzFfbG93ZmllbGQgPSA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4gZ2V0UGFja2VkU2VxU21hbGwxTG93ZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPihwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF8sIHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBwYWNrZWRfc2VxX3NtYWxsXzFfbG93ZmllbGQgPSA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQYWNrZWRTZXFTbWFsbDFMb3dmaWVsZENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkU2VxU21hbGwxTG93ZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgZ2V0UGFja2VkU2VxU21hbGwxTG93ZmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocGFja2VkU2VxU21hbGwxTG93ZmllbGRfLmdldChpbmRleCkpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkU2VxU21hbGwxTG93ZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9TRVFfU01BTExfMV9NSURGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDA2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZF87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPiBwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLlNFUV9TTUFMTF8xX0RFRkFVTFQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBwYWNrZWRfc2VxX3NtYWxsXzFfbWlkZmllbGQgPSAxMDA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4gZ2V0UGFja2VkU2VxU21hbGwxTWlkZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPihwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZF8sIHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBwYWNrZWRfc2VxX3NtYWxsXzFfbWlkZmllbGQgPSAxMDA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQYWNrZWRTZXFTbWFsbDFNaWRmaWVsZENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkU2VxU21hbGwxTWlkZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX21pZGZpZWxkID0gMTAwNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgZ2V0UGFja2VkU2VxU21hbGwxTWlkZmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocGFja2VkU2VxU21hbGwxTWlkZmllbGRfLmdldChpbmRleCkpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkU2VxU21hbGwxTWlkZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9TRVFfU01BTExfMV9ISUZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDAwMDY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZFNlcVNtYWxsMUhpZmllbGRfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4gcGFja2VkU2VxU21hbGwxSGlmaWVsZF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLlNFUV9TTUFMTF8xX0RFRkFVTFQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBwYWNrZWRfc2VxX3NtYWxsXzFfaGlmaWVsZCA9IDEwMDAwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcVNtYWxsMUhpZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDE+IGdldFBhY2tlZFNlcVNtYWxsMUhpZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPihwYWNrZWRTZXFTbWFsbDFIaWZpZWxkXywgcGFja2VkU2VxU21hbGwxSGlmaWVsZF9jb252ZXJ0ZXJfKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX2hpZmllbGQgPSAxMDAwMDA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZXFTbWFsbDFIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNlcVNtYWxsMUhpZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZFNlcVNtYWxsMUhpZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX2hpZmllbGQgPSAxMDAwMDA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNlcVNtYWxsMUhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIGdldFBhY2tlZFNlcVNtYWxsMUhpZmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRTZXFTbWFsbDFIaWZpZWxkX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRTZXFTbWFsbDFIaWZpZWxkXy5nZXQoaW5kZXgpKTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZFNlcVNtYWxsMUhpZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NFUV9MQVJHRV9MT1dGSUVMRF9GSUVMRF9OVU1CRVIgPSA3OwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZXFMYXJnZUxvd2ZpZWxkXyA9IC0xOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIG9wdGlvbmFsX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNlcUxhcmdlTG93ZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIG9wdGlvbmFsX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZXFMYXJnZUxvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBnZXRPcHRpb25hbFNlcUxhcmdlTG93ZmllbGQoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLmZvck51bWJlcihvcHRpb25hbFNlcUxhcmdlTG93ZmllbGRfKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UuU0VRX0xBUkdFX0RFRkFVTFQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0VRX0xBUkdFX01JREZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDc7CiAgICBwcml2YXRlIGludCBvcHRpb25hbFNlcUxhcmdlTWlkZmllbGRfID0gLTE7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2Ugb3B0aW9uYWxfc2VxX2xhcmdlX21pZGZpZWxkID0gMTAwNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2Ugb3B0aW9uYWxfc2VxX2xhcmdlX21pZGZpZWxkID0gMTAwNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNlcUxhcmdlTWlkZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIGdldE9wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZCgpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UuZm9yTnVtYmVyKG9wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZF8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZS5TRVFfTEFSR0VfREVGQVVMVCA6IHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TRVFfTEFSR0VfSElGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDAwMDA3OwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZXFMYXJnZUhpZmllbGRfID0gLTE7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2Ugb3B0aW9uYWxfc2VxX2xhcmdlX2hpZmllbGQgPSAxMDAwMDA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTZXFMYXJnZUhpZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2VxTGFyZ2VIaWZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2Ugb3B0aW9uYWxfc2VxX2xhcmdlX2hpZmllbGQgPSAxMDAwMDA3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2VxTGFyZ2VIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBnZXRPcHRpb25hbFNlcUxhcmdlSGlmaWVsZCgpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UuZm9yTnVtYmVyKG9wdGlvbmFsU2VxTGFyZ2VIaWZpZWxkXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLlNFUV9MQVJHRV9ERUZBVUxUIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NFUV9MQVJHRV9MT1dGSUVMRF9GSUVMRF9OVU1CRVIgPSA4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPiByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRfY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UuZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UuU0VRX0xBUkdFX0RFRkFVTFQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2U+IGdldFJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4ocmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXywgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX2xvd2ZpZWxkID0gODs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBnZXRSZXBlYXRlZFNlcUxhcmdlTG93ZmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0VRX0xBUkdFX01JREZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZF87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2U+IHJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZS5TRVFfTEFSR0VfREVGQVVMVCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX21pZGZpZWxkID0gMTAwODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4gZ2V0UmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPihyZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRfLCByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX21pZGZpZWxkID0gMTAwODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSByZXBlYXRlZF9zZXFfbGFyZ2VfbWlkZmllbGQgPSAxMDA4OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIGdldFJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXy5nZXQoaW5kZXgpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TRVFfTEFSR0VfSElGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDAwMDA4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZFNlcUxhcmdlSGlmaWVsZF87CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2U+IHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2U+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLlNFUV9MQVJHRV9ERUZBVUxUIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSByZXBlYXRlZF9zZXFfbGFyZ2VfaGlmaWVsZCA9IDEwMDAwMDg7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4gZ2V0UmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2U+KHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkXywgcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX2hpZmllbGQgPSAxMDAwMDA4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFNlcUxhcmdlSGlmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwODs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIGdldFJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkXy5nZXQoaW5kZXgpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfU0VRX0xBUkdFX0xPV0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZFNlcUxhcmdlTG93ZmllbGRfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPiBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2U+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLlNFUV9MQVJHRV9ERUZBVUxUIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBwYWNrZWRfc2VxX2xhcmdlX2xvd2ZpZWxkID0gOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2VxTGFyZ2VMb3dmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPiBnZXRQYWNrZWRTZXFMYXJnZUxvd2ZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPihwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXywgcGFja2VkU2VxTGFyZ2VMb3dmaWVsZF9jb252ZXJ0ZXJfKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBwYWNrZWRfc2VxX2xhcmdlX2xvd2ZpZWxkID0gOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2VxTGFyZ2VMb3dmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQYWNrZWRTZXFMYXJnZUxvd2ZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2VxTGFyZ2VMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBnZXRQYWNrZWRTZXFMYXJnZUxvd2ZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkU2VxTGFyZ2VMb3dmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocGFja2VkU2VxTGFyZ2VMb3dmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfU0VRX0xBUkdFX01JREZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZFNlcUxhcmdlTWlkZmllbGRfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPiBwYWNrZWRTZXFMYXJnZU1pZGZpZWxkX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2U+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLlNFUV9MQVJHRV9ERUZBVUxUIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBwYWNrZWRfc2VxX2xhcmdlX21pZGZpZWxkID0gMTAwOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPiBnZXRQYWNrZWRTZXFMYXJnZU1pZGZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPihwYWNrZWRTZXFMYXJnZU1pZGZpZWxkXywgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZF9jb252ZXJ0ZXJfKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBwYWNrZWRfc2VxX2xhcmdlX21pZGZpZWxkID0gMTAwOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQYWNrZWRTZXFMYXJnZU1pZGZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRTZXFMYXJnZU1pZGZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9taWRmaWVsZCA9IDEwMDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBnZXRQYWNrZWRTZXFMYXJnZU1pZGZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkU2VxTGFyZ2VNaWRmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocGFja2VkU2VxTGFyZ2VNaWRmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRTZXFMYXJnZU1pZGZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfU0VRX0xBUkdFX0hJRklFTERfRklFTERfTlVNQkVSID0gMTAwMDAwOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2VkU2VxTGFyZ2VIaWZpZWxkXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4gcGFja2VkU2VxTGFyZ2VIaWZpZWxkX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2U+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLlNFUV9MQVJHRV9ERUZBVUxUIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBwYWNrZWRfc2VxX2xhcmdlX2hpZmllbGQgPSAxMDAwMDA5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZXFMYXJnZUhpZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4gZ2V0UGFja2VkU2VxTGFyZ2VIaWZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPihwYWNrZWRTZXFMYXJnZUhpZmllbGRfLCBwYWNrZWRTZXFMYXJnZUhpZmllbGRfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2VxTGFyZ2VIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNlcUxhcmdlSGlmaWVsZENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkU2VxTGFyZ2VIaWZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZXFMYXJnZUhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgZ2V0UGFja2VkU2VxTGFyZ2VIaWZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkU2VxTGFyZ2VIaWZpZWxkX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRTZXFMYXJnZUhpZmllbGRfLmdldChpbmRleCkpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkU2VxTGFyZ2VIaWZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9BUkJJVFJBUllfTE9XRklFTERfRklFTERfTlVNQkVSID0gMTA7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEFyYml0cmFyeUxvd2ZpZWxkXyA9IC0xMjMxMjM7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IG9wdGlvbmFsX2FyYml0cmFyeV9sb3dmaWVsZCA9IDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAyMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBvcHRpb25hbF9hcmJpdHJhcnlfbG93ZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEFyYml0cmFyeUxvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgZ2V0T3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZCgpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeS5mb3JOdW1iZXIob3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZF8pOwogICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuQVJCSVRSQVJZX0RFRkFVTFQgOiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQVJCSVRSQVJZX01JREZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMTA7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkXyA9IC0xMjMxMjM7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IG9wdGlvbmFsX2FyYml0cmFyeV9taWRmaWVsZCA9IDEwMTA7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IG9wdGlvbmFsX2FyYml0cmFyeV9taWRmaWVsZCA9IDEwMTA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxBcmJpdHJhcnlNaWRmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IGdldE9wdGlvbmFsQXJiaXRyYXJ5TWlkZmllbGQoKSB7CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuZm9yTnVtYmVyKG9wdGlvbmFsQXJiaXRyYXJ5TWlkZmllbGRfKTsKICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5LkFSQklUUkFSWV9ERUZBVUxUIDogcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0FSQklUUkFSWV9ISUZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDAwMTA7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEFyYml0cmFyeUhpZmllbGRfID0gLTEyMzEyMzsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgb3B0aW9uYWxfYXJiaXRyYXJ5X2hpZmllbGQgPSAxMDAwMDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEFyYml0cmFyeUhpZmllbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwODAwKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgb3B0aW9uYWxfYXJiaXRyYXJ5X2hpZmllbGQgPSAxMDAwMDEwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQXJiaXRyYXJ5SGlmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IGdldE9wdGlvbmFsQXJiaXRyYXJ5SGlmaWVsZCgpIHsKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeS5mb3JOdW1iZXIob3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkXyk7CiAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeS5BUkJJVFJBUllfREVGQVVMVCA6IHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9BUkJJVFJBUllfTE9XRklFTERfRklFTERfTlVNQkVSID0gMTE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5LkFSQklUUkFSWV9ERUZBVUxUIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X2xvd2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gZ2V0UmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+KHJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfLCByZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXBlYXRlZF9hcmJpdHJhcnlfbG93ZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X2xvd2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBnZXRSZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQVJCSVRSQVJZX01JREZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMTE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gcmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5LkFSQklUUkFSWV9ERUZBVUxUIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X21pZGZpZWxkID0gMTAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PiBnZXRSZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4ocmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZF8sIHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9taWRmaWVsZCA9IDEwMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9taWRmaWVsZCA9IDEwMTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBnZXRSZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQVJCSVRSQVJZX0hJRklFTERfRklFTERfTlVNQkVSID0gMTAwMDAxMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+IHJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5LkFSQklUUkFSWV9ERUZBVUxUIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X2hpZmllbGQgPSAxMDAwMDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gZ2V0UmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4ocmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkXywgcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXBlYXRlZF9hcmJpdHJhcnlfaGlmaWVsZCA9IDEwMDAwMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9oaWZpZWxkID0gMTAwMDAxMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgZ2V0UmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfLmdldChpbmRleCkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9BUkJJVFJBUllfTE9XRklFTERfRklFTERfTlVNQkVSID0gMTI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXzsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+IHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkX2NvbnZlcnRlcl8gPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IGNvbnZlcnQoamF2YS5sYW5nLkludGVnZXIgZnJvbSkgewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuQVJCSVRSQVJZX0RFRkFVTFQgOiByZXN1bHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X2xvd2ZpZWxkID0gMTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PiBnZXRQYWNrZWRBcmJpdHJhcnlMb3dmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+KHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXywgcGFja2VkQXJiaXRyYXJ5TG93ZmllbGRfY29udmVydGVyXyk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHBhY2tlZF9hcmJpdHJhcnlfbG93ZmllbGQgPSAxMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkQXJiaXRyYXJ5TG93ZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkQXJiaXRyYXJ5TG93ZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHBhY2tlZF9hcmJpdHJhcnlfbG93ZmllbGQgPSAxMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRBcmJpdHJhcnlMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgZ2V0UGFja2VkQXJiaXRyYXJ5TG93ZmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRBcmJpdHJhcnlMb3dmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocGFja2VkQXJiaXRyYXJ5TG93ZmllbGRfLmdldChpbmRleCkpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkQXJiaXRyYXJ5TG93ZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9BUkJJVFJBUllfTUlERklFTERfRklFTERfTlVNQkVSID0gMTAxMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2VkQXJiaXRyYXJ5TWlkZmllbGRfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gcGFja2VkQXJiaXRyYXJ5TWlkZmllbGRfY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgY29udmVydChqYXZhLmxhbmcuSW50ZWdlciBmcm9tKSB7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5LmZvck51bWJlcihmcm9tKTsKICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeS5BUkJJVFJBUllfREVGQVVMVCA6IHJlc3VsdDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHBhY2tlZF9hcmJpdHJhcnlfbWlkZmllbGQgPSAxMDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gZ2V0UGFja2VkQXJiaXRyYXJ5TWlkZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PihwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZF8sIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X21pZGZpZWxkID0gMTAxMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkQXJiaXRyYXJ5TWlkZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkQXJiaXRyYXJ5TWlkZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHBhY2tlZF9hcmJpdHJhcnlfbWlkZmllbGQgPSAxMDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBnZXRQYWNrZWRBcmJpdHJhcnlNaWRmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemU7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0FSQklUUkFSWV9ISUZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDAwMTI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZEFyYml0cmFyeUhpZmllbGRfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gcGFja2VkQXJiaXRyYXJ5SGlmaWVsZF9jb252ZXJ0ZXJfID0KICAgICAgICAgICAgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXIuQ29udmVydGVyPAogICAgICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4oKSB7CiAgICAgICAgICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuZm9yTnVtYmVyKGZyb20pOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5LkFSQklUUkFSWV9ERUZBVUxUIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9oaWZpZWxkID0gMTAwMDAxMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkQXJiaXRyYXJ5SGlmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gZ2V0UGFja2VkQXJiaXRyYXJ5SGlmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+KHBhY2tlZEFyYml0cmFyeUhpZmllbGRfLCBwYWNrZWRBcmJpdHJhcnlIaWZpZWxkX2NvbnZlcnRlcl8pOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X2hpZmllbGQgPSAxMDAwMDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRBcmJpdHJhcnlIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEFyYml0cmFyeUhpZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEFyYml0cmFyeUhpZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9oaWZpZWxkID0gMTAwMDAxMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRBcmJpdHJhcnlIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBnZXRQYWNrZWRBcmJpdHJhcnlIaWZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkQXJiaXRyYXJ5SGlmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocGFja2VkQXJiaXRyYXJ5SGlmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRBcmJpdHJhcnlIaWZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPVEhFUl9GSUVMRF9GSUVMRF9OVU1CRVIgPSA5OTsKICAgIHByaXZhdGUgaW50IG90aGVyRmllbGRfID0gMDsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvdGhlckZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3RoZXJGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQW4gYXJiaXRyYXJ5IGZpZWxkIHdlIGNhbiBhcHBlbmQgdG8gdG8gYnJlYWsgdGhlIHJ1bnMgb2YgcmVwZWF0ZWQgZmllbGRzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3RoZXJfZmllbGQgPSA5OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvdGhlckZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE90aGVyRmllbGQoKSB7CiAgICAgIHJldHVybiBvdGhlckZpZWxkXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5FeHRlbmRhYmxlTWVzc2FnZTxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlcj4uRXh0ZW5zaW9uV3JpdGVyCiAgICAgICAgICBleHRlbnNpb25Xcml0ZXIgPSBuZXdFeHRlbnNpb25Xcml0ZXIoKTsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgxLCBvcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkXyk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMiwgcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2VxU21hbGwwTG93ZmllbGRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2VxU21hbGwwTG93ZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bU5vVGFnKHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oNCwgb3B0aW9uYWxTZXFTbWFsbDFMb3dmaWVsZF8pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDUsIHJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg1MCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2VxU21hbGwxTG93ZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW1Ob1RhZyhwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDcsIG9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZF8pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oOCwgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTZXFMYXJnZUxvd2ZpZWxkTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg3NCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2VxTGFyZ2VMb3dmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2VxTGFyZ2VMb3dmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcocGFja2VkU2VxTGFyZ2VMb3dmaWVsZF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDEwLCBvcHRpb25hbEFyYml0cmFyeUxvd2ZpZWxkXyk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTEsIHJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg5OCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkQXJiaXRyYXJ5TG93ZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW1Ob1RhZyhwYWNrZWRBcmJpdHJhcnlMb3dmaWVsZF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMig5OSwgb3RoZXJGaWVsZF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTAwMSwgb3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZF8pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDEwMDIsIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNlcVNtYWxsME1pZGZpZWxkTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MDI2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRTZXFTbWFsbDBNaWRmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2VxU21hbGwwTWlkZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bU5vVGFnKHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTAwNCwgb3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZF8pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDEwMDUsIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MDUwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2VxU21hbGwxTWlkZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bU5vVGFnKHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTAwNywgb3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkXyk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgxMDA4LCByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNlcUxhcmdlTWlkZmllbGRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDgwNzQpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZFNlcUxhcmdlTWlkZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNlcUxhcmdlTWlkZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bU5vVGFnKHBhY2tlZFNlcUxhcmdlTWlkZmllbGRfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgxMDEwLCBvcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkXyk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTAxMSwgcmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkQXJiaXRyYXJ5TWlkZmllbGRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDgwOTgpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcocGFja2VkQXJiaXRyYXJ5TWlkZmllbGRfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bSgxMDAwMDAxLCBvcHRpb25hbFNlcVNtYWxsMEhpZmllbGRfKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDEwMDAwMDIsIHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2VxU21hbGwwSGlmaWVsZExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoODAwMDAyNik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2VxU21hbGwwSGlmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2VxU21hbGwwSGlmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcocGFja2VkU2VxU21hbGwwSGlmaWVsZF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDEwMDAwMDQsIG9wdGlvbmFsU2VxU21hbGwxSGlmaWVsZF8pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTAwMDAwNSwgcmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTZXFTbWFsbDFIaWZpZWxkTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MDAwMDUwKTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRTZXFTbWFsbDFIaWZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRTZXFTbWFsbDFIaWZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW1Ob1RhZyhwYWNrZWRTZXFTbWFsbDFIaWZpZWxkXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTAwMDAwNywgb3B0aW9uYWxTZXFMYXJnZUhpZmllbGRfKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTAwMDAwOCwgcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfLmdldChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNlcUxhcmdlSGlmaWVsZExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoODAwMDA3NCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkU2VxTGFyZ2VIaWZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRTZXFMYXJnZUhpZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlRW51bU5vVGFnKHBhY2tlZFNlcUxhcmdlSGlmaWVsZF8uZ2V0KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtKDEwMDAwMTAsIG9wdGlvbmFsQXJiaXRyYXJ5SGlmaWVsZF8pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW0oMTAwMDAxMSwgcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRBcmJpdHJhcnlIaWZpZWxkTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MDAwMDk4KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRBcmJpdHJhcnlIaWZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRBcmJpdHJhcnlIaWZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUVudW1Ob1RhZyhwYWNrZWRBcmJpdHJhcnlIaWZpZWxkXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDUzNjg3MDkxMiwgb3V0cHV0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSgxLCBvcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkXyk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkU2VxU21hbGwwTG93ZmllbGRMaXN0KCkuaXNFbXB0eSgpKSB7ICBzaXplICs9IDE7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH1wYWNrZWRTZXFTbWFsbDBMb3dmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoNCwgb3B0aW9uYWxTZXFTbWFsbDFMb3dmaWVsZF8pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2VxU21hbGwxTG93ZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkTGlzdCgpLmlzRW1wdHkoKSkgeyAgc2l6ZSArPSAxOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9cGFja2VkU2VxU21hbGwxTG93ZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDcsIG9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZF8pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIHJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2VxTGFyZ2VMb3dmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHBhY2tlZFNlcUxhcmdlTG93ZmllbGRfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRTZXFMYXJnZUxvd2ZpZWxkTGlzdCgpLmlzRW1wdHkoKSkgeyAgc2l6ZSArPSAxOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9cGFja2VkU2VxTGFyZ2VMb3dmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMTAsIG9wdGlvbmFsQXJiaXRyYXJ5TG93ZmllbGRfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIHJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocGFja2VkQXJiaXRyYXJ5TG93ZmllbGRfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRBcmJpdHJhcnlMb3dmaWVsZExpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gMTsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfXBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAxMDAwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoOTksIG90aGVyRmllbGRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMTAwMSwgb3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZF8pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2VxU21hbGwwTWlkZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhwYWNrZWRTZXFTbWFsbDBNaWRmaWVsZF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZFNlcVNtYWxsME1pZGZpZWxkTGlzdCgpLmlzRW1wdHkoKSkgeyAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9cGFja2VkU2VxU21hbGwwTWlkZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDEwMDQsIG9wdGlvbmFsU2VxU21hbGwxTWlkZmllbGRfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocGFja2VkU2VxU21hbGwxTWlkZmllbGRfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRTZXFTbWFsbDFNaWRmaWVsZExpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfXBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSgxMDA3LCBvcHRpb25hbFNlcUxhcmdlTWlkZmllbGRfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNlcUxhcmdlTWlkZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhwYWNrZWRTZXFMYXJnZU1pZGZpZWxkXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkU2VxTGFyZ2VNaWRmaWVsZExpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfXBhY2tlZFNlcUxhcmdlTWlkZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDA0MDApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDEwMTAsIG9wdGlvbmFsQXJiaXRyYXJ5TWlkZmllbGRfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocGFja2VkQXJiaXRyYXJ5TWlkZmllbGRfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRBcmJpdHJhcnlNaWRmaWVsZExpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gMjsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfXBhY2tlZEFyYml0cmFyeU1pZGZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZSgxMDAwMDAxLCBvcHRpb25hbFNlcVNtYWxsMEhpZmllbGRfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDQgKiByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNlcVNtYWxsMEhpZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhwYWNrZWRTZXFTbWFsbDBIaWZpZWxkXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkU2VxU21hbGwwSGlmaWVsZExpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gNDsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfXBhY2tlZFNlcVNtYWxsMEhpZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUVudW1TaXplKDEwMDAwMDQsIG9wdGlvbmFsU2VxU21hbGwxSGlmaWVsZF8pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkXy5nZXQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gNCAqIHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcGFja2VkU2VxU21hbGwxSGlmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHBhY2tlZFNlcVNtYWxsMUhpZmllbGRfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRTZXFTbWFsbDFIaWZpZWxkTGlzdCgpLmlzRW1wdHkoKSkgeyAgc2l6ZSArPSA0OwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlVUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9cGFja2VkU2VxU21hbGwxSGlmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDEwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMTAwMDAwNywgb3B0aW9uYWxTZXFMYXJnZUhpZmllbGRfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSA0ICogcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZFNlcUxhcmdlSGlmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVFbnVtU2l6ZU5vVGFnKHBhY2tlZFNlcUxhcmdlSGlmaWVsZF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZFNlcUxhcmdlSGlmaWVsZExpc3QoKS5pc0VtcHR5KCkpIHsgIHNpemUgKz0gNDsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZVVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfXBhY2tlZFNlcUxhcmdlSGlmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRW51bVNpemUoMTAwMDAxMCwgb3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkXyk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlRW51bVNpemVOb1RhZyhyZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfLmdldChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSA0ICogcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRBcmJpdHJhcnlIaWZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcocGFja2VkQXJiaXRyYXJ5SGlmaWVsZF8uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEFyYml0cmFyeUhpZmllbGRMaXN0KCkuaXNFbXB0eSgpKSB7ICBzaXplICs9IDQ7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH1wYWNrZWRBcmJpdHJhcnlIaWZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHNpemUgKz0gZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplKCk7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlcikgb2JqOwoKICAgICAgaWYgKGhhc09wdGlvbmFsU2VxU21hbGwwTG93ZmllbGQoKSAhPSBvdGhlci5oYXNPcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsU2VxU21hbGwwTG93ZmllbGQoKSkgewogICAgICAgIGlmIChvcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkXyAhPSBvdGhlci5vcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkKCkpIHsKICAgICAgICBpZiAob3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZF8gIT0gb3RoZXIub3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZF8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxTZXFTbWFsbDBIaWZpZWxkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxTZXFTbWFsbDBIaWZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsU2VxU21hbGwwSGlmaWVsZCgpKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsU2VxU21hbGwwSGlmaWVsZF8gIT0gb3RoZXIub3B0aW9uYWxTZXFTbWFsbDBIaWZpZWxkXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8uZXF1YWxzKG90aGVyLnJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfLmVxdWFscyhvdGhlci5yZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFyZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfLmVxdWFscyhvdGhlci5yZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXy5lcXVhbHMob3RoZXIucGFja2VkU2VxU21hbGwwTG93ZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXy5lcXVhbHMob3RoZXIucGFja2VkU2VxU21hbGwwTWlkZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXBhY2tlZFNlcVNtYWxsMEhpZmllbGRfLmVxdWFscyhvdGhlci5wYWNrZWRTZXFTbWFsbDBIaWZpZWxkXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsU2VxU21hbGwxTG93ZmllbGQoKSAhPSBvdGhlci5oYXNPcHRpb25hbFNlcVNtYWxsMUxvd2ZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsU2VxU21hbGwxTG93ZmllbGQoKSkgewogICAgICAgIGlmIChvcHRpb25hbFNlcVNtYWxsMUxvd2ZpZWxkXyAhPSBvdGhlci5vcHRpb25hbFNlcVNtYWxsMUxvd2ZpZWxkXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFNlcVNtYWxsMU1pZGZpZWxkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFNlcVNtYWxsMU1pZGZpZWxkKCkpIHsKICAgICAgICBpZiAob3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZF8gIT0gb3RoZXIub3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZF8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxTZXFTbWFsbDFIaWZpZWxkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxTZXFTbWFsbDFIaWZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsU2VxU21hbGwxSGlmaWVsZCgpKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsU2VxU21hbGwxSGlmaWVsZF8gIT0gb3RoZXIub3B0aW9uYWxTZXFTbWFsbDFIaWZpZWxkXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF8uZXF1YWxzKG90aGVyLnJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfLmVxdWFscyhvdGhlci5yZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFyZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfLmVxdWFscyhvdGhlci5yZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkXy5lcXVhbHMob3RoZXIucGFja2VkU2VxU21hbGwxTG93ZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkXy5lcXVhbHMob3RoZXIucGFja2VkU2VxU21hbGwxTWlkZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXBhY2tlZFNlcVNtYWxsMUhpZmllbGRfLmVxdWFscyhvdGhlci5wYWNrZWRTZXFTbWFsbDFIaWZpZWxkXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZCgpICE9IG90aGVyLmhhc09wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFNlcUxhcmdlTG93ZmllbGQoKSkgewogICAgICAgIGlmIChvcHRpb25hbFNlcUxhcmdlTG93ZmllbGRfICE9IG90aGVyLm9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZF8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZCgpKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZF8gIT0gb3RoZXIub3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFNlcUxhcmdlSGlmaWVsZCgpICE9IG90aGVyLmhhc09wdGlvbmFsU2VxTGFyZ2VIaWZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsU2VxTGFyZ2VIaWZpZWxkKCkpIHsKICAgICAgICBpZiAob3B0aW9uYWxTZXFMYXJnZUhpZmllbGRfICE9IG90aGVyLm9wdGlvbmFsU2VxTGFyZ2VIaWZpZWxkXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXy5lcXVhbHMob3RoZXIucmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFyZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRfLmVxdWFscyhvdGhlci5yZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkXy5lcXVhbHMob3RoZXIucmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXBhY2tlZFNlcUxhcmdlTG93ZmllbGRfLmVxdWFscyhvdGhlci5wYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFwYWNrZWRTZXFMYXJnZU1pZGZpZWxkXy5lcXVhbHMob3RoZXIucGFja2VkU2VxTGFyZ2VNaWRmaWVsZF8pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghcGFja2VkU2VxTGFyZ2VIaWZpZWxkXy5lcXVhbHMob3RoZXIucGFja2VkU2VxTGFyZ2VIaWZpZWxkXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsQXJiaXRyYXJ5TG93ZmllbGQoKSAhPSBvdGhlci5oYXNPcHRpb25hbEFyYml0cmFyeUxvd2ZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsQXJiaXRyYXJ5TG93ZmllbGQoKSkgewogICAgICAgIGlmIChvcHRpb25hbEFyYml0cmFyeUxvd2ZpZWxkXyAhPSBvdGhlci5vcHRpb25hbEFyYml0cmFyeUxvd2ZpZWxkXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxBcmJpdHJhcnlNaWRmaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkKCkpIHsKICAgICAgICBpZiAob3B0aW9uYWxBcmJpdHJhcnlNaWRmaWVsZF8gIT0gb3RoZXIub3B0aW9uYWxBcmJpdHJhcnlNaWRmaWVsZF8pIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsQXJiaXRyYXJ5SGlmaWVsZCgpKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsQXJiaXRyYXJ5SGlmaWVsZF8gIT0gb3RoZXIub3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkXykgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8uZXF1YWxzKG90aGVyLnJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfLmVxdWFscyhvdGhlci5yZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFyZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfLmVxdWFscyhvdGhlci5yZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXy5lcXVhbHMob3RoZXIucGFja2VkQXJiaXRyYXJ5TG93ZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXBhY2tlZEFyYml0cmFyeU1pZGZpZWxkXy5lcXVhbHMob3RoZXIucGFja2VkQXJiaXRyYXJ5TWlkZmllbGRfKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIXBhY2tlZEFyYml0cmFyeUhpZmllbGRfLmVxdWFscyhvdGhlci5wYWNrZWRBcmJpdHJhcnlIaWZpZWxkXykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc090aGVyRmllbGQoKSAhPSBvdGhlci5oYXNPdGhlckZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc090aGVyRmllbGQoKSkgewogICAgICAgIGlmIChnZXRPdGhlckZpZWxkKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3RoZXJGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzT3B0aW9uYWxTZXFTbWFsbDBMb3dmaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU0VRX1NNQUxMXzBfTE9XRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIG9wdGlvbmFsU2VxU21hbGwwTG93ZmllbGRfOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TRVFfU01BTExfMF9NSURGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgb3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZF87CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsU2VxU21hbGwwSGlmaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU0VRX1NNQUxMXzBfSElGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgb3B0aW9uYWxTZXFTbWFsbDBIaWZpZWxkXzsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0VRX1NNQUxMXzBfTE9XRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGRfLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NFUV9TTUFMTF8wX01JREZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NFUV9TTUFMTF8wX0hJRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2VxU21hbGwwTG93ZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9TRVFfU01BTExfMF9MT1dGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcGFja2VkU2VxU21hbGwwTG93ZmllbGRfLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNlcVNtYWxsME1pZGZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfU0VRX1NNQUxMXzBfTUlERklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTZXFTbWFsbDBIaWZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfU0VRX1NNQUxMXzBfSElGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcGFja2VkU2VxU21hbGwwSGlmaWVsZF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxTZXFTbWFsbDFMb3dmaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU0VRX1NNQUxMXzFfTE9XRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIG9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGRfOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFNlcVNtYWxsMU1pZGZpZWxkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TRVFfU01BTExfMV9NSURGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgb3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZF87CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsU2VxU21hbGwxSGlmaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU0VRX1NNQUxMXzFfSElGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgb3B0aW9uYWxTZXFTbWFsbDFIaWZpZWxkXzsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU0VRX1NNQUxMXzFfTE9XRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NFUV9TTUFMTF8xX01JREZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NFUV9TTUFMTF8xX0hJRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2VxU21hbGwxTG93ZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9TRVFfU01BTExfMV9MT1dGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcGFja2VkU2VxU21hbGwxTG93ZmllbGRfLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfU0VRX1NNQUxMXzFfTUlERklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRTZXFTbWFsbDFIaWZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfU0VRX1NNQUxMXzFfSElGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcGFja2VkU2VxU21hbGwxSGlmaWVsZF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxTZXFMYXJnZUxvd2ZpZWxkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9TRVFfTEFSR0VfTE9XRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIG9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZF87CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU0VRX0xBUkdFX01JREZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBvcHRpb25hbFNlcUxhcmdlTWlkZmllbGRfOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFNlcUxhcmdlSGlmaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU0VRX0xBUkdFX0hJRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIG9wdGlvbmFsU2VxTGFyZ2VIaWZpZWxkXzsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TRVFfTEFSR0VfTE9XRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TRVFfTEFSR0VfTUlERklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NFUV9MQVJHRV9ISUZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXBlYXRlZFNlcUxhcmdlSGlmaWVsZF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2VxTGFyZ2VMb3dmaWVsZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1NFUV9MQVJHRV9MT1dGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcGFja2VkU2VxTGFyZ2VMb3dmaWVsZF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2VxTGFyZ2VNaWRmaWVsZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX1NFUV9MQVJHRV9NSURGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkU2VxTGFyZ2VIaWZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfU0VRX0xBUkdFX0hJRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHBhY2tlZFNlcUxhcmdlSGlmaWVsZF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfQVJCSVRSQVJZX0xPV0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBvcHRpb25hbEFyYml0cmFyeUxvd2ZpZWxkXzsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxBcmJpdHJhcnlNaWRmaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfQVJCSVRSQVJZX01JREZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBvcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkXzsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9BUkJJVFJBUllfSElGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgb3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkXzsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQVJCSVRSQVJZX0xPV0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyByZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9BUkJJVFJBUllfTUlERklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQVJCSVRSQVJZX0hJRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkQXJiaXRyYXJ5TG93ZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9BUkJJVFJBUllfTE9XRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXy5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRBcmJpdHJhcnlNaWRmaWVsZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX0FSQklUUkFSWV9NSURGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcGFja2VkQXJiaXRyYXJ5TWlkZmllbGRfLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEFyYml0cmFyeUhpZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9BUkJJVFJBUllfSElGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgcGFja2VkQXJiaXRyYXJ5SGlmaWVsZF8uaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3RoZXJGaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1RIRVJfRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE90aGVyRmllbGQoKTsKICAgICAgfQogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBUaGlzIG1lc3NhZ2UgY29udGFpbnMgZGlmZmVyZW50IGtpbmQgb2YgZW51bXMgdG8gZXhlcmNpc2UgdGhlIGRpZmZlcmVudAogICAgICogcGFyc2VycyBpbiB0YWJsZS1kcml2ZW4uCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXJ9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciwgQnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0VudW1QYXJzZVRlc3Rlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FbnVtUGFyc2VUZXN0ZXJfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIGJpdEZpZWxkMV8gPSAwOwogICAgICAgIG9wdGlvbmFsU2VxU21hbGwwTG93ZmllbGRfID0gMDsKICAgICAgICBvcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkXyA9IDA7CiAgICAgICAgb3B0aW9uYWxTZXFTbWFsbDBIaWZpZWxkXyA9IDA7CiAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgcGFja2VkU2VxU21hbGwwSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGRfID0gMTsKICAgICAgICBvcHRpb25hbFNlcVNtYWxsMU1pZGZpZWxkXyA9IDE7CiAgICAgICAgb3B0aW9uYWxTZXFTbWFsbDFIaWZpZWxkXyA9IDE7CiAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDEwMDApOwogICAgICAgIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA0MDAwKTsKICAgICAgICBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDgwMDApOwogICAgICAgIHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAxMDAwMCk7CiAgICAgICAgcGFja2VkU2VxU21hbGwxSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZF8gPSAtMTsKICAgICAgICBvcHRpb25hbFNlcUxhcmdlTWlkZmllbGRfID0gLTE7CiAgICAgICAgb3B0aW9uYWxTZXFMYXJnZUhpZmllbGRfID0gLTE7CiAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwODAwMDAwKTsKICAgICAgICBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDIwMDAwMDApOwogICAgICAgIHBhY2tlZFNlcUxhcmdlSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9wdGlvbmFsQXJiaXRyYXJ5TG93ZmllbGRfID0gLTEyMzEyMzsKICAgICAgICBvcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkXyA9IC0xMjMxMjM7CiAgICAgICAgb3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkXyA9IC0xMjMxMjM7CiAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4NDAwMDAwMDApOwogICAgICAgIHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDgwMDAwMDAwKTsKICAgICAgICByZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBwYWNrZWRBcmJpdHJhcnlMb3dmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgcGFja2VkQXJiaXRyYXJ5SGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG90aGVyRmllbGRfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRW51bVBhcnNlVGVzdGVyX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIodGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIGlmIChiaXRGaWVsZDFfICE9IDApIHsgYnVpbGRQYXJ0aWFsMShyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWxSZXBlYXRlZEZpZWxkcyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciByZXN1bHQpIHsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIH0KICAgICAgICByZXN1bHQucmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8gPSByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkXzsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIH0KICAgICAgICByZXN1bHQucmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8gPSByZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkXzsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAyMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8gPSByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfOwogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDQwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkU2VxU21hbGwwTG93ZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocGFja2VkU2VxU21hbGwwTG93ZmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXyA9IHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXzsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5wYWNrZWRTZXFTbWFsbDBNaWRmaWVsZF8gPSBwYWNrZWRTZXFTbWFsbDBNaWRmaWVsZF87CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTZXFTbWFsbDBIaWZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHBhY2tlZFNlcVNtYWxsMEhpZmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnBhY2tlZFNlcVNtYWxsMEhpZmllbGRfID0gcGFja2VkU2VxU21hbGwwSGlmaWVsZF87CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfID0gcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF87CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDIwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfID0gcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZF87CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwNDAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5yZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfID0gcmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkXzsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5wYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF8gPSBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF87CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMTAwMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMTAwMDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQucGFja2VkU2VxU21hbGwxTWlkZmllbGRfID0gcGFja2VkU2VxU21hbGwxTWlkZmllbGRfOwogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkU2VxU21hbGwxSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChwYWNrZWRTZXFTbWFsbDFIaWZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5wYWNrZWRTZXFTbWFsbDFIaWZpZWxkXyA9IHBhY2tlZFNlcVNtYWxsMUhpZmllbGRfOwogICAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAyMDAwMDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQucmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXyA9IHJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZF87CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDA0MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5yZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRfID0gcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXzsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDgwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDgwMDAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5yZXBlYXRlZFNlcUxhcmdlSGlmaWVsZF8gPSByZXBlYXRlZFNlcUxhcmdlSGlmaWVsZF87CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHBhY2tlZFNlcUxhcmdlTG93ZmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAxMDAwMDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnBhY2tlZFNlcUxhcmdlTG93ZmllbGRfID0gcGFja2VkU2VxTGFyZ2VMb3dmaWVsZF87CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDIwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTZXFMYXJnZU1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHBhY2tlZFNlcUxhcmdlTWlkZmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAyMDAwMDAwKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnBhY2tlZFNlcUxhcmdlTWlkZmllbGRfID0gcGFja2VkU2VxTGFyZ2VNaWRmaWVsZF87CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTZXFMYXJnZUhpZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocGFja2VkU2VxTGFyZ2VIaWZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwNDAwMDAwMCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5wYWNrZWRTZXFMYXJnZUhpZmllbGRfID0gcGFja2VkU2VxTGFyZ2VIaWZpZWxkXzsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4NDAwMDAwMDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQucmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8gPSByZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkXzsKICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHg4MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4ODAwMDAwMDApOwogICAgICAgIH0KICAgICAgICByZXN1bHQucmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZF8gPSByZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkXzsKICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZF8gPSByZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfOwogICAgICAgIGlmICgoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkQXJiaXRyYXJ5TG93ZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocGFja2VkQXJiaXRyYXJ5TG93ZmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXyA9IHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXzsKICAgICAgICBpZiAoKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5wYWNrZWRBcmJpdHJhcnlNaWRmaWVsZF8gPSBwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZF87CiAgICAgICAgaWYgKCgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRBcmJpdHJhcnlIaWZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHBhY2tlZEFyYml0cmFyeUhpZmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnBhY2tlZEFyYml0cmFyeUhpZmllbGRfID0gcGFja2VkQXJiaXRyYXJ5SGlmaWVsZF87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsU2VxU21hbGwwTG93ZmllbGRfID0gb3B0aW9uYWxTZXFTbWFsbDBMb3dmaWVsZF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZF8gPSBvcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFNlcVNtYWxsMEhpZmllbGRfID0gb3B0aW9uYWxTZXFTbWFsbDBIaWZpZWxkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFNlcVNtYWxsMUxvd2ZpZWxkXyA9IG9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsU2VxU21hbGwxTWlkZmllbGRfID0gb3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTZXFTbWFsbDFIaWZpZWxkXyA9IG9wdGlvbmFsU2VxU21hbGwxSGlmaWVsZF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwNDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTZXFMYXJnZUxvd2ZpZWxkXyA9IG9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwODAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkXyA9IG9wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTZXFMYXJnZUhpZmllbGRfID0gb3B0aW9uYWxTZXFMYXJnZUhpZmllbGRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDA4MDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsQXJiaXRyYXJ5TG93ZmllbGRfID0gb3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MTAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxBcmJpdHJhcnlNaWRmaWVsZF8gPSBvcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgyMDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEFyYml0cmFyeUhpZmllbGRfID0gb3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDEocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQxXyA9IGJpdEZpZWxkMV87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQxXyAmIDB4MDAwMDAwMTApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3RoZXJGaWVsZF8gPSBvdGhlckZpZWxkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LmJpdEZpZWxkMF8gfD0gdG9fYml0RmllbGQwXzsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIsIFR5cGU+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBhZGRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFQ+IEJ1aWxkZXIgY2xlYXJFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLCBUPiBleHRlbnNpb24pIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlcikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsU2VxU21hbGwwTG93ZmllbGQob3RoZXIuZ2V0T3B0aW9uYWxTZXFTbWFsbDBMb3dmaWVsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsU2VxU21hbGwwTWlkZmllbGQoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZChvdGhlci5nZXRPcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxTZXFTbWFsbDBIaWZpZWxkKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsU2VxU21hbGwwSGlmaWVsZChvdGhlci5nZXRPcHRpb25hbFNlcVNtYWxsMEhpZmllbGQoKSk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGRfID0gb3RoZXIucmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkXyA9IG90aGVyLnJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8gPSBvdGhlci5yZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkU2VxU21hbGwwTG93ZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF8gPSBvdGhlci5wYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXy5hZGRBbGwob3RoZXIucGFja2VkU2VxU21hbGwwTG93ZmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRTZXFTbWFsbDBNaWRmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXyA9IG90aGVyLnBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkU2VxU21hbGwwTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkU2VxU21hbGwwTWlkZmllbGRfLmFkZEFsbChvdGhlci5wYWNrZWRTZXFTbWFsbDBNaWRmaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkU2VxU21hbGwwSGlmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkU2VxU21hbGwwSGlmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZFNlcVNtYWxsMEhpZmllbGRfID0gb3RoZXIucGFja2VkU2VxU21hbGwwSGlmaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsMEhpZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkU2VxU21hbGwwSGlmaWVsZF8uYWRkQWxsKG90aGVyLnBhY2tlZFNlcVNtYWxsMEhpZmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxTZXFTbWFsbDFMb3dmaWVsZCgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFNlcVNtYWxsMUxvd2ZpZWxkKG90aGVyLmdldE9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFNlcVNtYWxsMU1pZGZpZWxkKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsU2VxU21hbGwxTWlkZmllbGQob3RoZXIuZ2V0T3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsU2VxU21hbGwxSGlmaWVsZCgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFNlcVNtYWxsMUhpZmllbGQob3RoZXIuZ2V0T3B0aW9uYWxTZXFTbWFsbDFIaWZpZWxkKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkXyA9IG90aGVyLnJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMTAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZF8gPSBvdGhlci5yZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDIwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfID0gb3RoZXIucmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkU2VxU21hbGwxTG93ZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkU2VxU21hbGwxTG93ZmllbGRfID0gb3RoZXIucGFja2VkU2VxU21hbGwxTG93ZmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRTZXFTbWFsbDFMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF8uYWRkQWxsKG90aGVyLnBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRTZXFTbWFsbDFNaWRmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkU2VxU21hbGwxTWlkZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZF8gPSBvdGhlci5wYWNrZWRTZXFTbWFsbDFNaWRmaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkXy5hZGRBbGwob3RoZXIucGFja2VkU2VxU21hbGwxTWlkZmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZFNlcVNtYWxsMUhpZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFNlcVNtYWxsMUhpZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRTZXFTbWFsbDFIaWZpZWxkXyA9IG90aGVyLnBhY2tlZFNlcVNtYWxsMUhpZmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAyMDAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRTZXFTbWFsbDFIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFNlcVNtYWxsMUhpZmllbGRfLmFkZEFsbChvdGhlci5wYWNrZWRTZXFTbWFsbDFIaWZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZCgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFNlcUxhcmdlTG93ZmllbGQob3RoZXIuZ2V0T3B0aW9uYWxTZXFMYXJnZUxvd2ZpZWxkKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZChvdGhlci5nZXRPcHRpb25hbFNlcUxhcmdlTWlkZmllbGQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFNlcUxhcmdlSGlmaWVsZCgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbFNlcUxhcmdlSGlmaWVsZChvdGhlci5nZXRPcHRpb25hbFNlcUxhcmdlSGlmaWVsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZF8gPSBvdGhlci5yZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDIwMDAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZF8gPSBvdGhlci5yZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFNlcUxhcmdlSGlmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFNlcUxhcmdlSGlmaWVsZF8gPSBvdGhlci5yZXBlYXRlZFNlcUxhcmdlSGlmaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwODAwMDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZFNlcUxhcmdlTG93ZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZFNlcUxhcmdlTG93ZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXyA9IG90aGVyLnBhY2tlZFNlcUxhcmdlTG93ZmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRTZXFMYXJnZUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFNlcUxhcmdlTG93ZmllbGRfLmFkZEFsbChvdGhlci5wYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRTZXFMYXJnZU1pZGZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRTZXFMYXJnZU1pZGZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZF8gPSBvdGhlci5wYWNrZWRTZXFMYXJnZU1pZGZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDIwMDAwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkU2VxTGFyZ2VNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRTZXFMYXJnZU1pZGZpZWxkXy5hZGRBbGwob3RoZXIucGFja2VkU2VxTGFyZ2VNaWRmaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkU2VxTGFyZ2VIaWZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRTZXFMYXJnZUhpZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRTZXFMYXJnZUhpZmllbGRfID0gb3RoZXIucGFja2VkU2VxTGFyZ2VIaWZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkU2VxTGFyZ2VIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZFNlcUxhcmdlSGlmaWVsZF8uYWRkQWxsKG90aGVyLnBhY2tlZFNlcUxhcmdlSGlmaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEFyYml0cmFyeUxvd2ZpZWxkKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsQXJiaXRyYXJ5TG93ZmllbGQob3RoZXIuZ2V0T3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsQXJiaXRyYXJ5TWlkZmllbGQoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxBcmJpdHJhcnlNaWRmaWVsZChvdGhlci5nZXRPcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsQXJiaXRyYXJ5SGlmaWVsZChvdGhlci5nZXRPcHRpb25hbEFyYml0cmFyeUhpZmllbGQoKSk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfID0gb3RoZXIucmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkXyA9IG90aGVyLnJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHg4MDAwMDAwMCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZF8gPSBvdGhlci5yZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfOwogICAgICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFyYml0cmFyeUhpZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRBcmJpdHJhcnlMb3dmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkQXJiaXRyYXJ5TG93ZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRBcmJpdHJhcnlMb3dmaWVsZF8gPSBvdGhlci5wYWNrZWRBcmJpdHJhcnlMb3dmaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXy5hZGRBbGwob3RoZXIucGFja2VkQXJiaXRyYXJ5TG93ZmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEFyYml0cmFyeU1pZGZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkXyA9IG90aGVyLnBhY2tlZEFyYml0cmFyeU1pZGZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDQpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkQXJiaXRyYXJ5TWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkQXJiaXRyYXJ5TWlkZmllbGRfLmFkZEFsbChvdGhlci5wYWNrZWRBcmJpdHJhcnlNaWRmaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkQXJiaXRyYXJ5SGlmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkQXJiaXRyYXJ5SGlmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEFyYml0cmFyeUhpZmllbGRfID0gb3RoZXIucGFja2VkQXJiaXRyYXJ5SGlmaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMV8gPSAoYml0RmllbGQxXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZEFyYml0cmFyeUhpZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkQXJiaXRyYXJ5SGlmaWVsZF8uYWRkQWxsKG90aGVyLnBhY2tlZEFyYml0cmFyeUhpZmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3RoZXJGaWVsZCgpKSB7CiAgICAgICAgICBzZXRPdGhlckZpZWxkKG90aGVyLmdldE90aGVyRmllbGQoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VFeHRlbnNpb25GaWVsZHMob3RoZXIpOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIG9wdGlvbmFsU2VxU21hbGwwTG93ZmllbGRfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOAogICAgICAgICAgICAgIGNhc2UgMTY6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgyLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDIsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMywgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNAogICAgICAgICAgICAgIGNhc2UgMjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDMsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2VxU21hbGwwTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzI6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg0LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgb3B0aW9uYWxTZXFTbWFsbDFMb3dmaWVsZF8gPSB0bXBSYXc7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzMgogICAgICAgICAgICAgIGNhc2UgNDA6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg1LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MAogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDUsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNDIKICAgICAgICAgICAgICBjYXNlIDQ4OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoNiwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0OAogICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDYsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2VxU21hbGwxTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MAogICAgICAgICAgICAgIGNhc2UgNTY6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoNywgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIG9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZF8gPSB0bXBSYXc7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1NgogICAgICAgICAgICAgIGNhc2UgNjQ6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoOCwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY0CiAgICAgICAgICAgICAgY2FzZSA2NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDgsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY2CiAgICAgICAgICAgICAgY2FzZSA3MjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg5LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2VxTGFyZ2VMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3MgogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCg5LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNlcUxhcmdlTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDc0CiAgICAgICAgICAgICAgY2FzZSA4MDogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgb3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZF8gPSB0bXBSYXc7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MAogICAgICAgICAgICAgIGNhc2UgODg6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODgKICAgICAgICAgICAgICBjYXNlIDkwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICAgIGNhc2UgOTY6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMiwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5NgogICAgICAgICAgICAgIGNhc2UgOTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5LmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEyLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgcGFja2VkQXJiaXRyYXJ5TG93ZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgOTgKICAgICAgICAgICAgICBjYXNlIDc5MjogewogICAgICAgICAgICAgICAgb3RoZXJGaWVsZF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3OTIKICAgICAgICAgICAgICBjYXNlIDgwMDg6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDAxLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgb3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZF8gPSB0bXBSYXc7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDA4CiAgICAgICAgICAgICAgY2FzZSA4MDE2OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMTAwMiwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAxNgogICAgICAgICAgICAgIGNhc2UgODAxODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMTAwMiwgdG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDE4CiAgICAgICAgICAgICAgY2FzZSA4MDI0OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMTAwMywgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsME1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDI0CiAgICAgICAgICAgICAgY2FzZSA4MDI2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMC5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDAzLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsME1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgcGFja2VkU2VxU21hbGwwTWlkZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAyNgogICAgICAgICAgICAgIGNhc2UgODAzMjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwMDQsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBvcHRpb25hbFNlcVNtYWxsMU1pZGZpZWxkXyA9IHRtcFJhdzsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMzIKICAgICAgICAgICAgICBjYXNlIDgwNDA6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDA1LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDQwCiAgICAgICAgICAgICAgY2FzZSA4MDQyOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDA1LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwNDIKICAgICAgICAgICAgICBjYXNlIDgwNDg6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDA2LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2VxU21hbGwxTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcGFja2VkU2VxU21hbGwxTWlkZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwNDgKICAgICAgICAgICAgICBjYXNlIDgwNTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwMDYsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2VxU21hbGwxTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICBwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDUwCiAgICAgICAgICAgICAgY2FzZSA4MDU2OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwMDcsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBvcHRpb25hbFNlcUxhcmdlTWlkZmllbGRfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODA1NgogICAgICAgICAgICAgIGNhc2UgODA2NDogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDA4LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODA2NAogICAgICAgICAgICAgIGNhc2UgODA2NjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwMDgsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwNjYKICAgICAgICAgICAgICBjYXNlIDgwNzI6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMTAwOSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNlcUxhcmdlTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODA3MgogICAgICAgICAgICAgIGNhc2UgODA3NDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwMDksIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2VxTGFyZ2VNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIHBhY2tlZFNlcUxhcmdlTWlkZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODA3NAogICAgICAgICAgICAgIGNhc2UgODA4MDogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwMTAsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBvcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkXyA9IHRtcFJhdzsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwODAKICAgICAgICAgICAgICBjYXNlIDgwODg6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDExLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDg4CiAgICAgICAgICAgICAgY2FzZSA4MDkwOiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDExLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICByZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwOTAKICAgICAgICAgICAgICBjYXNlIDgwOTY6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDEyLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkQXJiaXRyYXJ5TWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcGFja2VkQXJiaXRyYXJ5TWlkZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwOTYKICAgICAgICAgICAgICBjYXNlIDgwOTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5LmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwMTIsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkQXJiaXRyYXJ5TWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICBwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KG9sZExpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDk4CiAgICAgICAgICAgICAgY2FzZSA4MDAwMDA4OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMTAwMDAwMSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIG9wdGlvbmFsU2VxU21hbGwwSGlmaWVsZF8gPSB0bXBSYXc7CiAgICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDAwMDA4CiAgICAgICAgICAgICAgY2FzZSA4MDAwMDE2OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMTAwMDAwMiwgdG1wUmF3KTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAwMTYKICAgICAgICAgICAgICBjYXNlIDgwMDAwMTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwMDAwMDIsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAwMTgKICAgICAgICAgICAgICBjYXNlIDgwMDAwMjQ6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDAwMDAzLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2VxU21hbGwwSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICBwYWNrZWRTZXFTbWFsbDBIaWZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDAwMDI0CiAgICAgICAgICAgICAgY2FzZSA4MDAwMDI2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgb2xkTGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIHdoaWxlKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMC5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDAwMDAzLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsMEhpZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICBwYWNrZWRTZXFTbWFsbDBIaWZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAwMjYKICAgICAgICAgICAgICBjYXNlIDgwMDAwMzI6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDAwMDA0LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgb3B0aW9uYWxTZXFTbWFsbDFIaWZpZWxkXyA9IHRtcFJhdzsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAwMzIKICAgICAgICAgICAgICBjYXNlIDgwMDAwNDA6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDAwMDA1LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMDA0MAogICAgICAgICAgICAgIGNhc2UgODAwMDA0MjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMTAwMDAwNSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMDA0MgogICAgICAgICAgICAgIGNhc2UgODAwMDA0ODogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwMDAwMDYsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRTZXFTbWFsbDFIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHBhY2tlZFNlcVNtYWxsMUhpZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAwNDgKICAgICAgICAgICAgICBjYXNlIDgwMDAwNTA6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwMDAwMDYsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2VxU21hbGwxSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIHBhY2tlZFNlcVNtYWxsMUhpZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMDA1MAogICAgICAgICAgICAgIGNhc2UgODAwMDA1NjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDAwMDA3LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgb3B0aW9uYWxTZXFMYXJnZUhpZmllbGRfID0gdG1wUmF3OwogICAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMDA1NgogICAgICAgICAgICAgIGNhc2UgODAwMDA2NDogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDAwMDA4LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAwNjQKICAgICAgICAgICAgICBjYXNlIDgwMDAwNjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDAwMDA4LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMDA2NgogICAgICAgICAgICAgIGNhc2UgODAwMDA3MjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDAwMDA5LCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2VxTGFyZ2VIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHBhY2tlZFNlcUxhcmdlSGlmaWVsZF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMDA3MgogICAgICAgICAgICAgIGNhc2UgODAwMDA3NDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwMDAwMDksIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkU2VxTGFyZ2VIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgICAgcGFja2VkU2VxTGFyZ2VIaWZpZWxkXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAwNzQKICAgICAgICAgICAgICBjYXNlIDgwMDAwODA6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDAwMDEwLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgb3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkXyA9IHRtcFJhdzsKICAgICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAwODAKICAgICAgICAgICAgICBjYXNlIDgwMDAwODg6IHsKICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHRtcFZhbHVlID0KICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxMDAwMDExLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZF8uYWRkKHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMDA4OAogICAgICAgICAgICAgIGNhc2UgODAwMDA5MDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSB0bXBWYWx1ZSA9CiAgICAgICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgbWVyZ2VVbmtub3duVmFyaW50RmllbGQoMTAwMDAxMSwgdG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEFyYml0cmFyeUhpZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICByZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMDA5MAogICAgICAgICAgICAgIGNhc2UgODAwMDA5NjogewogICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgIGlmICh0bXBWYWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwMDAwMTIsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRBcmJpdHJhcnlIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICAgIHBhY2tlZEFyYml0cmFyeUhpZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAwOTYKICAgICAgICAgICAgICBjYXNlIDgwMDAwOTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBvbGRMaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgd2hpbGUoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIGludCB0bXBSYXcgPSBpbnB1dC5yZWFkRW51bSgpOwogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5LmZvck51bWJlcih0bXBSYXcpOwogICAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICAgIG1lcmdlVW5rbm93blZhcmludEZpZWxkKDEwMDAwMTIsIHRtcFJhdyk7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkQXJiaXRyYXJ5SGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICAgIHBhY2tlZEFyYml0cmFyeUhpZmllbGRfLmFkZCh0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChvbGRMaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMDA5OAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMV87CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkXyA9IDA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBvcHRpb25hbF9zZXFfc21hbGxfMF9sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2VxU21hbGwwTG93ZmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgb3B0aW9uYWxfc2VxX3NtYWxsXzBfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZXFTbWFsbDBMb3dmaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBnZXRPcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuZm9yTnVtYmVyKG9wdGlvbmFsU2VxU21hbGwwTG93ZmllbGRfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuU0VRX1NNQUxMXzBfREVGQVVMVCA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgb3B0aW9uYWxfc2VxX3NtYWxsXzBfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTZXFTbWFsbDBMb3dmaWVsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvcHRpb25hbFNlcVNtYWxsMExvd2ZpZWxkXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBvcHRpb25hbF9zZXFfc21hbGxfMF9sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU2VxU21hbGwwTG93ZmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIG9wdGlvbmFsU2VxU21hbGwwTG93ZmllbGRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZF8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgb3B0aW9uYWxfc2VxX3NtYWxsXzBfbWlkZmllbGQgPSAxMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIG9wdGlvbmFsX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2VxU21hbGwwTWlkZmllbGQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgZ2V0T3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLmZvck51bWJlcihvcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLlNFUV9TTUFMTF8wX0RFRkFVTFQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIG9wdGlvbmFsX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU2VxU21hbGwwTWlkZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZF8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgb3B0aW9uYWxfc2VxX3NtYWxsXzBfbWlkZmllbGQgPSAxMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBvcHRpb25hbFNlcVNtYWxsME1pZGZpZWxkXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsU2VxU21hbGwwSGlmaWVsZF8gPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgb3B0aW9uYWxfc2VxX3NtYWxsXzBfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2VxU21hbGwwSGlmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2VxU21hbGwwSGlmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIG9wdGlvbmFsX3NlcV9zbWFsbF8wX2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZXFTbWFsbDBIaWZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIGdldE9wdGlvbmFsU2VxU21hbGwwSGlmaWVsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwLmZvck51bWJlcihvcHRpb25hbFNlcVNtYWxsMEhpZmllbGRfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAuU0VRX1NNQUxMXzBfREVGQVVMVCA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgb3B0aW9uYWxfc2VxX3NtYWxsXzBfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU2VxU21hbGwwSGlmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU2VxU21hbGwwSGlmaWVsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvcHRpb25hbFNlcVNtYWxsMEhpZmllbGRfID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIG9wdGlvbmFsX3NlcV9zbWFsbF8wX2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFNlcVNtYWxsMEhpZmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9wdGlvbmFsU2VxU21hbGwwSGlmaWVsZF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXBlYXRlZF9zZXFfc21hbGxfMF9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4gZ2V0UmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwPihyZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkXywgcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVwZWF0ZWRfc2VxX3NtYWxsXzBfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgZ2V0UmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVwZWF0ZWRfc2VxX3NtYWxsXzBfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVwZWF0ZWRfc2VxX3NtYWxsXzBfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNlcVNtYWxsMExvd2ZpZWxkKCkgewogICAgICAgIHJlcGVhdGVkU2VxU21hbGwwTG93ZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4ocmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVwZWF0ZWRfc2VxX3NtYWxsXzBfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IGdldFJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRMaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4ocmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8sIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXBlYXRlZF9zZXFfc21hbGxfMF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIGdldFJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXBlYXRlZF9zZXFfc21hbGxfMF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXBlYXRlZF9zZXFfc21hbGxfMF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwwTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTZXFTbWFsbDBNaWRmaWVsZCgpIHsKICAgICAgICByZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAxMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVwZWF0ZWRfc2VxX3NtYWxsXzBfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwPiBnZXRSZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRMaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4ocmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkXywgcmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXBlYXRlZF9zZXFfc21hbGxfMF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXBlYXRlZF9zZXFfc21hbGxfMF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBnZXRSZXBlYXRlZFNlcVNtYWxsMEhpZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcmVwZWF0ZWRfc2VxX3NtYWxsXzBfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNlcVNtYWxsMEhpZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHJlcGVhdGVkX3NlcV9zbWFsbF8wX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMEhpZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCByZXBlYXRlZF9zZXFfc21hbGxfMF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTZXFTbWFsbDBIaWZpZWxkKCkgewogICAgICAgIHJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcGFja2VkX3NlcV9zbWFsbF8wX2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IGdldFBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+KHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXywgcGFja2VkU2VxU21hbGwwTG93ZmllbGRfY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2VxU21hbGwwTG93ZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgZ2V0UGFja2VkU2VxU21hbGwwTG93ZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkU2VxU21hbGwwTG93ZmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUGFja2VkU2VxU21hbGwwTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUGFja2VkU2VxU21hbGwwTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcGFja2VkX3NlcV9zbWFsbF8wX2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRTZXFTbWFsbDBMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcGFja2VkX3NlcV9zbWFsbF8wX2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkKCkgewogICAgICAgIHBhY2tlZFNlcVNtYWxsMExvd2ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkU2VxU21hbGwwTWlkZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkU2VxU21hbGwwTWlkZmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBwYWNrZWRfc2VxX3NtYWxsXzBfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4gZ2V0UGFja2VkU2VxU21hbGwwTWlkZmllbGRMaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4ocGFja2VkU2VxU21hbGwwTWlkZmllbGRfLCBwYWNrZWRTZXFTbWFsbDBNaWRmaWVsZF9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcGFja2VkX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZXFTbWFsbDBNaWRmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2VxU21hbGwwTWlkZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2VxU21hbGwwTWlkZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcGFja2VkX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkU2VxU21hbGwwTWlkZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBnZXRQYWNrZWRTZXFTbWFsbDBNaWRmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2VxU21hbGwwTWlkZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcGFja2VkX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2VxU21hbGwwTWlkZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRTZXFTbWFsbDBNaWRmaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVQYWNrZWRTZXFTbWFsbDBNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcGFja2VkX3NlcV9zbWFsbF8wX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkU2VxU21hbGwwTWlkZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVQYWNrZWRTZXFTbWFsbDBNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBwYWNrZWRfc2VxX3NtYWxsXzBfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNlcVNtYWxsME1pZGZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkU2VxU21hbGwwTWlkZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMD4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkU2VxU21hbGwwTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcGFja2VkU2VxU21hbGwwTWlkZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBwYWNrZWRfc2VxX3NtYWxsXzBfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkU2VxU21hbGwwTWlkZmllbGQoKSB7CiAgICAgICAgcGFja2VkU2VxU21hbGwwTWlkZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2VkU2VxU21hbGwwSGlmaWVsZF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNlcVNtYWxsMEhpZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkU2VxU21hbGwwSGlmaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4ocGFja2VkU2VxU21hbGwwSGlmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcGFja2VkX3NlcV9zbWFsbF8wX2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcVNtYWxsMEhpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwPiBnZXRQYWNrZWRTZXFTbWFsbDBIaWZpZWxkTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+KHBhY2tlZFNlcVNtYWxsMEhpZmllbGRfLCBwYWNrZWRTZXFTbWFsbDBIaWZpZWxkX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBwYWNrZWRfc2VxX3NtYWxsXzBfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2VxU21hbGwwSGlmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2VxU21hbGwwSGlmaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRTZXFTbWFsbDBIaWZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkU2VxU21hbGwwSGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIGdldFBhY2tlZFNlcVNtYWxsMEhpZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNlcVNtYWxsMEhpZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHBhY2tlZFNlcVNtYWxsMEhpZmllbGRfLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCBwYWNrZWRfc2VxX3NtYWxsXzBfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNlcVNtYWxsMEhpZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRTZXFTbWFsbDBIaWZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsMEhpZmllbGRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTZXFTbWFsbDBIaWZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcGFja2VkX3NlcV9zbWFsbF8wX2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2VxU21hbGwwSGlmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNlcVNtYWxsMEhpZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVQYWNrZWRTZXFTbWFsbDBIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2VxU21hbGwwSGlmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDAgcGFja2VkX3NlcV9zbWFsbF8wX2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNlcVNtYWxsMEhpZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRTZXFTbWFsbDBIaWZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDA+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsMEhpZmllbGRJc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcGFja2VkU2VxU21hbGwwSGlmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIHBhY2tlZF9zZXFfc21hbGxfMF9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZFNlcVNtYWxsMEhpZmllbGQoKSB7CiAgICAgICAgcGFja2VkU2VxU21hbGwwSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFNlcVNtYWxsMUxvd2ZpZWxkXyA9IDE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBvcHRpb25hbF9zZXFfc21hbGxfMV9sb3dmaWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZSBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFNlcVNtYWxsMUxvd2ZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgb3B0aW9uYWxfc2VxX3NtYWxsXzFfbG93ZmllbGQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZXFTbWFsbDFMb3dmaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBnZXRPcHRpb25hbFNlcVNtYWxsMUxvd2ZpZWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuZm9yTnVtYmVyKG9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGRfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuU0VRX1NNQUxMXzFfREVGQVVMVCA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgb3B0aW9uYWxfc2VxX3NtYWxsXzFfbG93ZmllbGQgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFNlcVNtYWxsMUxvd2ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTZXFTbWFsbDFMb3dmaWVsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvcHRpb25hbFNlcVNtYWxsMUxvd2ZpZWxkXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBvcHRpb25hbF9zZXFfc21hbGxfMV9sb3dmaWVsZCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGRfID0gMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZF8gPSAxOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgb3B0aW9uYWxfc2VxX3NtYWxsXzFfbWlkZmllbGQgPSAxMDA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNlcVNtYWxsMU1pZGZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDQwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIG9wdGlvbmFsX3NlcV9zbWFsbF8xX21pZGZpZWxkID0gMTAwNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2VxU21hbGwxTWlkZmllbGQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgZ2V0T3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLmZvck51bWJlcihvcHRpb25hbFNlcVNtYWxsMU1pZGZpZWxkXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLlNFUV9TTUFMTF8xX0RFRkFVTFQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIG9wdGlvbmFsX3NlcV9zbWFsbF8xX21pZGZpZWxkID0gMTAwNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU2VxU21hbGwxTWlkZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgICAgb3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZF8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgb3B0aW9uYWxfc2VxX3NtYWxsXzFfbWlkZmllbGQgPSAxMDA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFNlcVNtYWxsMU1pZGZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTsKICAgICAgICBvcHRpb25hbFNlcVNtYWxsMU1pZGZpZWxkXyA9IDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsU2VxU21hbGwxSGlmaWVsZF8gPSAxOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgb3B0aW9uYWxfc2VxX3NtYWxsXzFfaGlmaWVsZCA9IDEwMDAwMDQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2VxU21hbGwxSGlmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2VxU21hbGwxSGlmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDgwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIG9wdGlvbmFsX3NlcV9zbWFsbF8xX2hpZmllbGQgPSAxMDAwMDA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTZXFTbWFsbDFIaWZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIGdldE9wdGlvbmFsU2VxU21hbGwxSGlmaWVsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxLmZvck51bWJlcihvcHRpb25hbFNlcVNtYWxsMUhpZmllbGRfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEuU0VRX1NNQUxMXzFfREVGQVVMVCA6IHJlc3VsdDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgb3B0aW9uYWxfc2VxX3NtYWxsXzFfaGlmaWVsZCA9IDEwMDAwMDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU2VxU21hbGwxSGlmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU2VxU21hbGwxSGlmaWVsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvcHRpb25hbFNlcVNtYWxsMUhpZmllbGRfID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIG9wdGlvbmFsX3NlcV9zbWFsbF8xX2hpZmllbGQgPSAxMDAwMDA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFNlcVNtYWxsMUhpZmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDA4MDApOwogICAgICAgIG9wdGlvbmFsU2VxU21hbGwxSGlmaWVsZF8gPSAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDEwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXBlYXRlZF9zZXFfc21hbGxfMV9sb3dmaWVsZCA9IDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4gZ2V0UmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPihyZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkXywgcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVwZWF0ZWRfc2VxX3NtYWxsXzFfbG93ZmllbGQgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgZ2V0UmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVwZWF0ZWRfc2VxX3NtYWxsXzFfbG93ZmllbGQgPSA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVwZWF0ZWRfc2VxX3NtYWxsXzFfbG93ZmllbGQgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNlcVNtYWxsMUxvd2ZpZWxkKCkgewogICAgICAgIHJlcGVhdGVkU2VxU21hbGwxTG93ZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4ocmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVwZWF0ZWRfc2VxX3NtYWxsXzFfbWlkZmllbGQgPSAxMDA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDE+IGdldFJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRMaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4ocmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZF8sIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX21pZGZpZWxkID0gMTAwNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXBlYXRlZF9zZXFfc21hbGxfMV9taWRmaWVsZCA9IDEwMDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIGdldFJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXBlYXRlZF9zZXFfc21hbGxfMV9taWRmaWVsZCA9IDEwMDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXBlYXRlZF9zZXFfc21hbGxfMV9taWRmaWVsZCA9IDEwMDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX21pZGZpZWxkID0gMTAwNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDE+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwxTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX21pZGZpZWxkID0gMTAwNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTZXFTbWFsbDFNaWRmaWVsZCgpIHsKICAgICAgICByZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMjAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVwZWF0ZWRfc2VxX3NtYWxsXzFfaGlmaWVsZCA9IDEwMDAwMDU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPiBnZXRSZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRMaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4ocmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkXywgcmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXBlYXRlZF9zZXFfc21hbGxfMV9oaWZpZWxkID0gMTAwMDAwNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXBlYXRlZF9zZXFfc21hbGxfMV9oaWZpZWxkID0gMTAwMDAwNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBnZXRSZXBlYXRlZFNlcVNtYWxsMUhpZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcmVwZWF0ZWRfc2VxX3NtYWxsXzFfaGlmaWVsZCA9IDEwMDAwMDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZF8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX2hpZmllbGQgPSAxMDAwMDA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNlcVNtYWxsMUhpZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHJlcGVhdGVkX3NlcV9zbWFsbF8xX2hpZmllbGQgPSAxMDAwMDA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDE+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZFNlcVNtYWxsMUhpZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSByZXBlYXRlZF9zZXFfc21hbGxfMV9oaWZpZWxkID0gMTAwMDAwNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTZXFTbWFsbDFIaWZpZWxkKCkgewogICAgICAgIHJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDQwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDE+IGdldFBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDE+KHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkXywgcGFja2VkU2VxU21hbGwxTG93ZmllbGRfY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHBhY2tlZF9zZXFfc21hbGxfMV9sb3dmaWVsZCA9IDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2VxU21hbGwxTG93ZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHBhY2tlZF9zZXFfc21hbGxfMV9sb3dmaWVsZCA9IDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgZ2V0UGFja2VkU2VxU21hbGwxTG93ZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHBhY2tlZF9zZXFfc21hbGxfMV9sb3dmaWVsZCA9IDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkU2VxU21hbGwxTG93ZmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUGFja2VkU2VxU21hbGwxTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHBhY2tlZF9zZXFfc21hbGxfMV9sb3dmaWVsZCA9IDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUGFja2VkU2VxU21hbGwxTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRTZXFTbWFsbDFMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDE+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkID0gNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkKCkgewogICAgICAgIHBhY2tlZFNlcVNtYWxsMUxvd2ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwODAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkU2VxU21hbGwxTWlkZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkU2VxU21hbGwxTWlkZmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBwYWNrZWRfc2VxX3NtYWxsXzFfbWlkZmllbGQgPSAxMDA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4gZ2V0UGFja2VkU2VxU21hbGwxTWlkZmllbGRMaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4ocGFja2VkU2VxU21hbGwxTWlkZmllbGRfLCBwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZF9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX21pZGZpZWxkID0gMTAwNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZXFTbWFsbDFNaWRmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2VxU21hbGwxTWlkZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2VxU21hbGwxTWlkZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX21pZGZpZWxkID0gMTAwNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkU2VxU21hbGwxTWlkZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBnZXRQYWNrZWRTZXFTbWFsbDFNaWRmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2VxU21hbGwxTWlkZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX21pZGZpZWxkID0gMTAwNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2VxU21hbGwxTWlkZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRTZXFTbWFsbDFNaWRmaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVQYWNrZWRTZXFTbWFsbDFNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX21pZGZpZWxkID0gMTAwNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkU2VxU21hbGwxTWlkZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVQYWNrZWRTZXFTbWFsbDFNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBwYWNrZWRfc2VxX3NtYWxsXzFfbWlkZmllbGQgPSAxMDA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNlcVNtYWxsMU1pZGZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkU2VxU21hbGwxTWlkZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkU2VxU21hbGwxTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcGFja2VkU2VxU21hbGwxTWlkZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBwYWNrZWRfc2VxX3NtYWxsXzFfbWlkZmllbGQgPSAxMDA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkU2VxU21hbGwxTWlkZmllbGQoKSB7CiAgICAgICAgcGFja2VkU2VxU21hbGwxTWlkZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDEwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2VkU2VxU21hbGwxSGlmaWVsZF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZFNlcVNtYWxsMUhpZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMDIwMDAwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkU2VxU21hbGwxSGlmaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4ocGFja2VkU2VxU21hbGwxSGlmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX2hpZmllbGQgPSAxMDAwMDA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcVNtYWxsMUhpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxPiBnZXRQYWNrZWRTZXFTbWFsbDFIaWZpZWxkTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDE+KHBhY2tlZFNlcVNtYWxsMUhpZmllbGRfLCBwYWNrZWRTZXFTbWFsbDFIaWZpZWxkX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBwYWNrZWRfc2VxX3NtYWxsXzFfaGlmaWVsZCA9IDEwMDAwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkU2VxU21hbGwxSGlmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkU2VxU21hbGwxSGlmaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRTZXFTbWFsbDFIaWZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHBhY2tlZF9zZXFfc21hbGxfMV9oaWZpZWxkID0gMTAwMDAwNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkU2VxU21hbGwxSGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIGdldFBhY2tlZFNlcVNtYWxsMUhpZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNlcVNtYWxsMUhpZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHBhY2tlZFNlcVNtYWxsMUhpZmllbGRfLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSBwYWNrZWRfc2VxX3NtYWxsXzFfaGlmaWVsZCA9IDEwMDAwMDYgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNlcVNtYWxsMUhpZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRTZXFTbWFsbDFIaWZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsMUhpZmllbGRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTZXFTbWFsbDFIaWZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX2hpZmllbGQgPSAxMDAwMDA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2VxU21hbGwxSGlmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNlcVNtYWxsMUhpZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVQYWNrZWRTZXFTbWFsbDFIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2VxU21hbGwxSGlmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDEgcGFja2VkX3NlcV9zbWFsbF8xX2hpZmllbGQgPSAxMDAwMDA2IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNlcVNtYWxsMUhpZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRTZXFTbWFsbDFIaWZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDE+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZFNlcVNtYWxsMUhpZmllbGRJc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcGFja2VkU2VxU21hbGwxSGlmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxIHBhY2tlZF9zZXFfc21hbGxfMV9oaWZpZWxkID0gMTAwMDAwNiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZFNlcVNtYWxsMUhpZmllbGQoKSB7CiAgICAgICAgcGFja2VkU2VxU21hbGwxSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMjAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFNlcUxhcmdlTG93ZmllbGRfID0gLTE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIG9wdGlvbmFsX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2Ugb3B0aW9uYWxfc2VxX2xhcmdlX2xvd2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIGdldE9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZS5mb3JOdW1iZXIob3B0aW9uYWxTZXFMYXJnZUxvd2ZpZWxkXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UuU0VRX0xBUkdFX0RFRkFVTFQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2Ugb3B0aW9uYWxfc2VxX2xhcmdlX2xvd2ZpZWxkID0gNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTZXFMYXJnZUxvd2ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTZXFMYXJnZUxvd2ZpZWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgb3B0aW9uYWxTZXFMYXJnZUxvd2ZpZWxkXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIG9wdGlvbmFsX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDA0MDAwMCk7CiAgICAgICAgb3B0aW9uYWxTZXFMYXJnZUxvd2ZpZWxkXyA9IC0xOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFNlcUxhcmdlTWlkZmllbGRfID0gLTE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIG9wdGlvbmFsX3NlcV9sYXJnZV9taWRmaWVsZCA9IDEwMDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDA4MDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2Ugb3B0aW9uYWxfc2VxX2xhcmdlX21pZGZpZWxkID0gMTAwNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIGdldE9wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZS5mb3JOdW1iZXIob3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UuU0VRX0xBUkdFX0RFRkFVTFQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2Ugb3B0aW9uYWxfc2VxX2xhcmdlX21pZGZpZWxkID0gMTAwNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgICAgb3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIG9wdGlvbmFsX3NlcV9sYXJnZV9taWRmaWVsZCA9IDEwMDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU2VxTGFyZ2VNaWRmaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDA4MDAwMCk7CiAgICAgICAgb3B0aW9uYWxTZXFMYXJnZU1pZGZpZWxkXyA9IC0xOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbFNlcUxhcmdlSGlmaWVsZF8gPSAtMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2Ugb3B0aW9uYWxfc2VxX2xhcmdlX2hpZmllbGQgPSAxMDAwMDA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFNlcUxhcmdlSGlmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU2VxTGFyZ2VIaWZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMTAwMDAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBvcHRpb25hbF9zZXFfbGFyZ2VfaGlmaWVsZCA9IDEwMDAwMDc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFNlcUxhcmdlSGlmaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIGdldE9wdGlvbmFsU2VxTGFyZ2VIaWZpZWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLmZvck51bWJlcihvcHRpb25hbFNlcUxhcmdlSGlmaWVsZF8pOwogICAgICAgIHJldHVybiByZXN1bHQgPT0gbnVsbCA/IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlLlNFUV9MQVJHRV9ERUZBVUxUIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIG9wdGlvbmFsX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTZXFMYXJnZUhpZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFNlcUxhcmdlSGlmaWVsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9wdGlvbmFsU2VxTGFyZ2VIaWZpZWxkXyA9IHZhbHVlLmdldE51bWJlcigpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIG9wdGlvbmFsX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTZXFMYXJnZUhpZmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAxMDAwMDApOwogICAgICAgIG9wdGlvbmFsU2VxTGFyZ2VIaWZpZWxkXyA9IC0xOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwMjAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX2xvd2ZpZWxkID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4gZ2V0UmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4ocmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXywgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSByZXBlYXRlZF9zZXFfbGFyZ2VfbG93ZmllbGQgPSA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgZ2V0UmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX2xvd2ZpZWxkID0gODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFNlcUxhcmdlTG93ZmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRfLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFNlcUxhcmdlTG93ZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU2VxTGFyZ2VMb3dmaWVsZCgpIHsKICAgICAgICByZXBlYXRlZFNlcUxhcmdlTG93ZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMjAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDQwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4ocmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9taWRmaWVsZCA9IDEwMDg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2U+IGdldFJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2U+KHJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZF8sIHJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZF9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSByZXBlYXRlZF9zZXFfbGFyZ2VfbWlkZmllbGQgPSAxMDA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX21pZGZpZWxkID0gMTAwODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIGdldFJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkX2NvbnZlcnRlcl8uY29udmVydChyZXBlYXRlZFNlcUxhcmdlTWlkZmllbGRfLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9taWRmaWVsZCA9IDEwMDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSByZXBlYXRlZF9zZXFfbGFyZ2VfbWlkZmllbGQgPSAxMDA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFNlcUxhcmdlTWlkZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNlcUxhcmdlTWlkZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSByZXBlYXRlZF9zZXFfbGFyZ2VfbWlkZmllbGQgPSAxMDA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSByZXBlYXRlZF9zZXFfbGFyZ2VfbWlkZmllbGQgPSAxMDA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNlcUxhcmdlTWlkZmllbGQoKSB7CiAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZU1pZGZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDQwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDAwODAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPiBnZXRSZXBlYXRlZFNlcUxhcmdlSGlmaWVsZExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2U+KHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkXywgcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX2hpZmllbGQgPSAxMDAwMDA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX2hpZmllbGQgPSAxMDAwMDA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBnZXRSZXBlYXRlZFNlcUxhcmdlSGlmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSByZXBlYXRlZF9zZXFfbGFyZ2VfaGlmaWVsZCA9IDEwMDAwMDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFNlcUxhcmdlSGlmaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRfLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHJlcGVhdGVkX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTZXFMYXJnZUhpZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFNlcUxhcmdlSGlmaWVsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFNlcUxhcmdlSGlmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSByZXBlYXRlZF9zZXFfbGFyZ2VfaGlmaWVsZCA9IDEwMDAwMDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFNlcUxhcmdlSGlmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU2VxTGFyZ2VIaWZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTZXFMYXJnZUhpZmllbGRJc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICByZXBlYXRlZFNlcUxhcmdlSGlmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcmVwZWF0ZWRfc2VxX2xhcmdlX2hpZmllbGQgPSAxMDAwMDA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFNlcUxhcmdlSGlmaWVsZCgpIHsKICAgICAgICByZXBlYXRlZFNlcUxhcmdlSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDA4MDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkU2VxTGFyZ2VMb3dmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDEwMDAwMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHBhY2tlZF9zZXFfbGFyZ2VfbG93ZmllbGQgPSA5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZFNlcUxhcmdlTG93ZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2U+IGdldFBhY2tlZFNlcUxhcmdlTG93ZmllbGRMaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPihwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXywgcGFja2VkU2VxTGFyZ2VMb3dmaWVsZF9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBwYWNrZWRfc2VxX2xhcmdlX2xvd2ZpZWxkID0gOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRTZXFMYXJnZUxvd2ZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZFNlcUxhcmdlTG93ZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBwYWNrZWRfc2VxX2xhcmdlX2xvd2ZpZWxkID0gOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkU2VxTGFyZ2VMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgZ2V0UGFja2VkU2VxTGFyZ2VMb3dmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2VxTGFyZ2VMb3dmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocGFja2VkU2VxTGFyZ2VMb3dmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9sb3dmaWVsZCA9IDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNlcUxhcmdlTG93ZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRTZXFMYXJnZUxvd2ZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUGFja2VkU2VxTGFyZ2VMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNlcUxhcmdlTG93ZmllbGRfLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHBhY2tlZF9zZXFfbGFyZ2VfbG93ZmllbGQgPSA5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2VxTGFyZ2VMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNlcUxhcmdlTG93ZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZFNlcUxhcmdlTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHBhY2tlZF9zZXFfbGFyZ2VfbG93ZmllbGQgPSA5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZFNlcUxhcmdlTG93ZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRTZXFMYXJnZUxvd2ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkU2VxTGFyZ2VMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHBhY2tlZFNlcUxhcmdlTG93ZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHBhY2tlZF9zZXFfbGFyZ2VfbG93ZmllbGQgPSA5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkU2VxTGFyZ2VMb3dmaWVsZCgpIHsKICAgICAgICBwYWNrZWRTZXFMYXJnZUxvd2ZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMTAwMDAwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZFNlcUxhcmdlTWlkZmllbGRfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRTZXFMYXJnZU1pZGZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMjAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFNlcUxhcmdlTWlkZmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHBhY2tlZFNlcUxhcmdlTWlkZmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9taWRmaWVsZCA9IDEwMDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4gZ2V0UGFja2VkU2VxTGFyZ2VNaWRmaWVsZExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2U+KHBhY2tlZFNlcUxhcmdlTWlkZmllbGRfLCBwYWNrZWRTZXFMYXJnZU1pZGZpZWxkX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHBhY2tlZF9zZXFfbGFyZ2VfbWlkZmllbGQgPSAxMDA5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZFNlcUxhcmdlTWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNlcUxhcmdlTWlkZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2VxTGFyZ2VNaWRmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHBhY2tlZF9zZXFfbGFyZ2VfbWlkZmllbGQgPSAxMDA5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZXFMYXJnZU1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBnZXRQYWNrZWRTZXFMYXJnZU1pZGZpZWxkKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRTZXFMYXJnZU1pZGZpZWxkX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRTZXFMYXJnZU1pZGZpZWxkXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBwYWNrZWRfc2VxX2xhcmdlX21pZGZpZWxkID0gMTAwOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZFNlcUxhcmdlTWlkZmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVQYWNrZWRTZXFMYXJnZU1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZF8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9taWRmaWVsZCA9IDEwMDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRTZXFMYXJnZU1pZGZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkU2VxTGFyZ2VNaWRmaWVsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUGFja2VkU2VxTGFyZ2VNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNlcUxhcmdlTWlkZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9taWRmaWVsZCA9IDEwMDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZFNlcUxhcmdlTWlkZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRTZXFMYXJnZU1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcGFja2VkU2VxTGFyZ2VNaWRmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9taWRmaWVsZCA9IDEwMDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRTZXFMYXJnZU1pZGZpZWxkKCkgewogICAgICAgIHBhY2tlZFNlcUxhcmdlTWlkZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAyMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcGFja2VkU2VxTGFyZ2VIaWZpZWxkXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkU2VxTGFyZ2VIaWZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwNDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZFNlcUxhcmdlSGlmaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4ocGFja2VkU2VxTGFyZ2VIaWZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHBhY2tlZF9zZXFfbGFyZ2VfaGlmaWVsZCA9IDEwMDAwMDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkU2VxTGFyZ2VIaWZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPiBnZXRQYWNrZWRTZXFMYXJnZUhpZmllbGRMaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlPihwYWNrZWRTZXFMYXJnZUhpZmllbGRfLCBwYWNrZWRTZXFMYXJnZUhpZmllbGRfY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRTZXFMYXJnZUhpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZFNlcUxhcmdlSGlmaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRTZXFMYXJnZUhpZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBwYWNrZWRfc2VxX2xhcmdlX2hpZmllbGQgPSAxMDAwMDA5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRTZXFMYXJnZUhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIGdldFBhY2tlZFNlcUxhcmdlSGlmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkU2VxTGFyZ2VIaWZpZWxkX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRTZXFMYXJnZUhpZmllbGRfLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHBhY2tlZF9zZXFfbGFyZ2VfaGlmaWVsZCA9IDEwMDAwMDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNlcUxhcmdlSGlmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZFNlcUxhcmdlSGlmaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZFNlcUxhcmdlSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZFNlcUxhcmdlSGlmaWVsZF8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2UgcGFja2VkX3NlcV9sYXJnZV9oaWZpZWxkID0gMTAwMDAwOSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZFNlcUxhcmdlSGlmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZFNlcUxhcmdlSGlmaWVsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUGFja2VkU2VxTGFyZ2VIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkU2VxTGFyZ2VIaWZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlIHBhY2tlZF9zZXFfbGFyZ2VfaGlmaWVsZCA9IDEwMDAwMDkgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkU2VxTGFyZ2VIaWZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkU2VxTGFyZ2VIaWZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkU2VxTGFyZ2VIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcGFja2VkU2VxTGFyZ2VIaWZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZSBwYWNrZWRfc2VxX2xhcmdlX2hpZmllbGQgPSAxMDAwMDA5IFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkU2VxTGFyZ2VIaWZpZWxkKCkgewogICAgICAgIHBhY2tlZFNlcUxhcmdlSGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDQwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEFyYml0cmFyeUxvd2ZpZWxkXyA9IC0xMjMxMjM7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBvcHRpb25hbF9hcmJpdHJhcnlfbG93ZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQXJiaXRyYXJ5TG93ZmllbGQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDgwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBvcHRpb25hbF9hcmJpdHJhcnlfbG93ZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQXJiaXRyYXJ5TG93ZmllbGQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgZ2V0T3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5LmZvck51bWJlcihvcHRpb25hbEFyYml0cmFyeUxvd2ZpZWxkXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5LkFSQklUUkFSWV9ERUZBVUxUIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBvcHRpb25hbF9hcmJpdHJhcnlfbG93ZmllbGQgPSAxMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQXJiaXRyYXJ5TG93ZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgb3B0aW9uYWxBcmJpdHJhcnlMb3dmaWVsZF8gPSB2YWx1ZS5nZXROdW1iZXIoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgb3B0aW9uYWxfYXJiaXRyYXJ5X2xvd2ZpZWxkID0gMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsQXJiaXRyYXJ5TG93ZmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDgwMDAwMDApOwogICAgICAgIG9wdGlvbmFsQXJiaXRyYXJ5TG93ZmllbGRfID0gLTEyMzEyMzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxBcmJpdHJhcnlNaWRmaWVsZF8gPSAtMTIzMTIzOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgb3B0aW9uYWxfYXJiaXRyYXJ5X21pZGZpZWxkID0gMTAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxBcmJpdHJhcnlNaWRmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQXJiaXRyYXJ5TWlkZmllbGQoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MTAwMDAwMDApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBvcHRpb25hbF9hcmJpdHJhcnlfbWlkZmllbGQgPSAxMDEwOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxBcmJpdHJhcnlNaWRmaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBnZXRPcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXN1bHQgPSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuZm9yTnVtYmVyKG9wdGlvbmFsQXJiaXRyYXJ5TWlkZmllbGRfKTsKICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkuQVJCSVRSQVJZX0RFRkFVTFQgOiByZXN1bHQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IG9wdGlvbmFsX2FyYml0cmFyeV9taWRmaWVsZCA9IDEwMTA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsQXJiaXRyYXJ5TWlkZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEFyYml0cmFyeU1pZGZpZWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9wdGlvbmFsQXJiaXRyYXJ5TWlkZmllbGRfID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IG9wdGlvbmFsX2FyYml0cmFyeV9taWRmaWVsZCA9IDEwMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsQXJiaXRyYXJ5TWlkZmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MTAwMDAwMDApOwogICAgICAgIG9wdGlvbmFsQXJiaXRyYXJ5TWlkZmllbGRfID0gLTEyMzEyMzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkXyA9IC0xMjMxMjM7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBvcHRpb25hbF9hcmJpdHJhcnlfaGlmaWVsZCA9IDEwMDAwMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQXJiaXRyYXJ5SGlmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQXJiaXRyYXJ5SGlmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgyMDAwMDAwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IG9wdGlvbmFsX2FyYml0cmFyeV9oaWZpZWxkID0gMTAwMDAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQXJiaXRyYXJ5SGlmaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBnZXRPcHRpb25hbEFyYml0cmFyeUhpZmllbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlc3VsdCA9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeS5mb3JOdW1iZXIob3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkXyk7CiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5LkFSQklUUkFSWV9ERUZBVUxUIDogcmVzdWx0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBvcHRpb25hbF9hcmJpdHJhcnlfaGlmaWVsZCA9IDEwMDAwMTA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsQXJiaXRyYXJ5SGlmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQXJiaXRyYXJ5SGlmaWVsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvcHRpb25hbEFyYml0cmFyeUhpZmllbGRfID0gdmFsdWUuZ2V0TnVtYmVyKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IG9wdGlvbmFsX2FyYml0cmFyeV9oaWZpZWxkID0gMTAwMDAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxBcmJpdHJhcnlIaWZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDIwMDAwMDAwKTsKICAgICAgICBvcHRpb25hbEFyYml0cmFyeUhpZmllbGRfID0gLTEyMzEyMzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDQwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4ocmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X2xvd2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gZ2V0UmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PihyZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkXywgcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF9jb252ZXJ0ZXJfKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X2xvd2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X2xvd2ZpZWxkID0gMTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IGdldFJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXBlYXRlZF9hcmJpdHJhcnlfbG93ZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8uc2V0KGluZGV4LCB2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9sb3dmaWVsZCA9IDExOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXBlYXRlZF9hcmJpdHJhcnlfbG93ZmllbGQgPSAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9sb3dmaWVsZCA9IDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEFyYml0cmFyeUxvd2ZpZWxkKCkgewogICAgICAgIHJlcGVhdGVkQXJiaXRyYXJ5TG93ZmllbGRfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDQwMDAwMDAwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gcmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZF8gPSBuZXcgamF2YS51dGlsLkFycmF5TGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4ocmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X21pZGZpZWxkID0gMTAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PiBnZXRSZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+KHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfLCByZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXBlYXRlZF9hcmJpdHJhcnlfbWlkZmllbGQgPSAxMDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9taWRmaWVsZCA9IDEwMTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IGdldFJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRfLmdldChpbmRleCkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXBlYXRlZF9hcmJpdHJhcnlfbWlkZmllbGQgPSAxMDExOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X21pZGZpZWxkID0gMTAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X21pZGZpZWxkID0gMTAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9taWRmaWVsZCA9IDEwMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQXJiaXRyYXJ5TWlkZmllbGQoKSB7CiAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlNaWRmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4ODAwMDAwMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiByZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEFyYml0cmFyeUhpZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihyZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfKTsKICAgICAgICAgIGJpdEZpZWxkMV8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9oaWZpZWxkID0gMTAwMDAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+IGdldFJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PihyZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfLCByZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfY29udmVydGVyXyk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9oaWZpZWxkID0gMTAwMDAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSByZXBlYXRlZF9hcmJpdHJhcnlfaGlmaWVsZCA9IDEwMDAwMTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgZ2V0UmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9oaWZpZWxkID0gMTAwMDAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEFyYml0cmFyeUhpZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEFyYml0cmFyeUhpZmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X2hpZmllbGQgPSAxMDAwMDExOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEFyYml0cmFyeUhpZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEFyYml0cmFyeUhpZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVSZXBlYXRlZEFyYml0cmFyeUhpZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEFyYml0cmFyeUhpZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHJlcGVhdGVkX2FyYml0cmFyeV9oaWZpZWxkID0gMTAwMDAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEFyYml0cmFyeUhpZmllbGRJc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcmVwZWF0ZWRfYXJiaXRyYXJ5X2hpZmllbGQgPSAxMDAwMDExOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEFyYml0cmFyeUhpZmllbGQoKSB7CiAgICAgICAgcmVwZWF0ZWRBcmJpdHJhcnlIaWZpZWxkXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDFfID0gKGJpdEZpZWxkMV8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkQXJiaXRyYXJ5TG93ZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCEoKGJpdEZpZWxkMV8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkQXJiaXRyYXJ5TG93ZmllbGRfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X2xvd2ZpZWxkID0gMTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkQXJiaXRyYXJ5TG93ZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PiBnZXRQYWNrZWRBcmJpdHJhcnlMb3dmaWVsZExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PihwYWNrZWRBcmJpdHJhcnlMb3dmaWVsZF8sIHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X2xvd2ZpZWxkID0gMTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkQXJiaXRyYXJ5TG93ZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHBhY2tlZF9hcmJpdHJhcnlfbG93ZmllbGQgPSAxMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkQXJiaXRyYXJ5TG93ZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBnZXRQYWNrZWRBcmJpdHJhcnlMb3dmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkQXJiaXRyYXJ5TG93ZmllbGRfY29udmVydGVyXy5jb252ZXJ0KHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9sb3dmaWVsZCA9IDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRBcmJpdHJhcnlMb3dmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkQXJiaXRyYXJ5TG93ZmllbGRfLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X2xvd2ZpZWxkID0gMTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRBcmJpdHJhcnlMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUGFja2VkQXJiaXRyYXJ5TG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRBcmJpdHJhcnlMb3dmaWVsZF8uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9sb3dmaWVsZCA9IDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZEFyYml0cmFyeUxvd2ZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkQXJiaXRyYXJ5TG93ZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkQXJiaXRyYXJ5TG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICBmb3IgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSB2YWx1ZSA6IHZhbHVlcykgewogICAgICAgICAgcGFja2VkQXJiaXRyYXJ5TG93ZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgfQogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X2xvd2ZpZWxkID0gMTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRBcmJpdHJhcnlMb3dmaWVsZCgpIHsKICAgICAgICBwYWNrZWRBcmJpdHJhcnlMb3dmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZF8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEFyYml0cmFyeU1pZGZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDFfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZF8pOwogICAgICAgICAgYml0RmllbGQxXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9taWRmaWVsZCA9IDEwMTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkQXJiaXRyYXJ5TWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PiBnZXRQYWNrZWRBcmJpdHJhcnlNaWRmaWVsZExpc3QoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyPAogICAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PihwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZF8sIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X21pZGZpZWxkID0gMTAxMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkQXJiaXRyYXJ5TWlkZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkQXJiaXRyYXJ5TWlkZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9taWRmaWVsZCA9IDEwMTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgZ2V0UGFja2VkQXJiaXRyYXJ5TWlkZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkX2NvbnZlcnRlcl8uY29udmVydChwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHBhY2tlZF9hcmJpdHJhcnlfbWlkZmllbGQgPSAxMDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEFyYml0cmFyeU1pZGZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZEFyYml0cmFyeU1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkQXJiaXRyYXJ5TWlkZmllbGRfLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X21pZGZpZWxkID0gMTAxMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUGFja2VkQXJiaXRyYXJ5TWlkZmllbGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVQYWNrZWRBcmJpdHJhcnlNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X21pZGZpZWxkID0gMTAxMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEFyYml0cmFyeU1pZGZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEFyYml0cmFyeU1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgdmFsdWUgOiB2YWx1ZXMpIHsKICAgICAgICAgIHBhY2tlZEFyYml0cmFyeU1pZGZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9taWRmaWVsZCA9IDEwMTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRBcmJpdHJhcnlNaWRmaWVsZCgpIHsKICAgICAgICBwYWNrZWRBcmJpdHJhcnlNaWRmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPiBwYWNrZWRBcmJpdHJhcnlIaWZpZWxkXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkQXJiaXRyYXJ5SGlmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQxXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRBcmJpdHJhcnlIaWZpZWxkXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PGphdmEubGFuZy5JbnRlZ2VyPihwYWNrZWRBcmJpdHJhcnlIaWZpZWxkXyk7CiAgICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X2hpZmllbGQgPSAxMDAwMDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEFyYml0cmFyeUhpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5PiBnZXRQYWNrZWRBcmJpdHJhcnlIaWZpZWxkTGlzdCgpIHsKICAgICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTGlzdEFkYXB0ZXI8CiAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+KHBhY2tlZEFyYml0cmFyeUhpZmllbGRfLCBwYWNrZWRBcmJpdHJhcnlIaWZpZWxkX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X2hpZmllbGQgPSAxMDAwMDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEFyYml0cmFyeUhpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEFyYml0cmFyeUhpZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkQXJiaXRyYXJ5SGlmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSBwYWNrZWRfYXJiaXRyYXJ5X2hpZmllbGQgPSAxMDAwMDEyIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRBcmJpdHJhcnlIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgZ2V0UGFja2VkQXJiaXRyYXJ5SGlmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkQXJiaXRyYXJ5SGlmaWVsZF9jb252ZXJ0ZXJfLmNvbnZlcnQocGFja2VkQXJiaXRyYXJ5SGlmaWVsZF8uZ2V0KGluZGV4KSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHBhY2tlZF9hcmJpdHJhcnlfaGlmaWVsZCA9IDEwMDAwMTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEFyYml0cmFyeUhpZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRBcmJpdHJhcnlIaWZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIGVuc3VyZVBhY2tlZEFyYml0cmFyeUhpZmllbGRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRBcmJpdHJhcnlIaWZpZWxkXy5zZXQoaW5kZXgsIHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9oaWZpZWxkID0gMTAwMDAxMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEFyYml0cmFyeUhpZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRBcmJpdHJhcnlIaWZpZWxkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlUGFja2VkQXJiaXRyYXJ5SGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEFyYml0cmFyeUhpZmllbGRfLmFkZCh2YWx1ZS5nZXROdW1iZXIoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHBhY2tlZF9hcmJpdHJhcnlfaGlmaWVsZCA9IDEwMDAwMTIgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkQXJiaXRyYXJ5SGlmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEFyYml0cmFyeUhpZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkQXJiaXRyYXJ5SGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGZvciAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5IHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICBwYWNrZWRBcmJpdHJhcnlIaWZpZWxkXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnkgcGFja2VkX2FyYml0cmFyeV9oaWZpZWxkID0gMTAwMDAxMiBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEFyYml0cmFyeUhpZmllbGQoKSB7CiAgICAgICAgcGFja2VkQXJiaXRyYXJ5SGlmaWVsZF8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMDgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvdGhlckZpZWxkXyA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBbiBhcmJpdHJhcnkgZmllbGQgd2UgY2FuIGFwcGVuZCB0byB0byBicmVhayB0aGUgcnVucyBvZiByZXBlYXRlZCBmaWVsZHMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdGhlcl9maWVsZCA9IDk5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvdGhlckZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3RoZXJGaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDFfICYgMHgwMDAwMDAxMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvdGhlckZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE90aGVyRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIG90aGVyRmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBbiBhcmJpdHJhcnkgZmllbGQgd2UgY2FuIGFwcGVuZCB0byB0byBicmVhayB0aGUgcnVucyBvZiByZXBlYXRlZCBmaWVsZHMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdGhlcl9maWVsZCA9IDk5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvdGhlckZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3RoZXJGaWVsZChpbnQgdmFsdWUpIHsKCiAgICAgICAgb3RoZXJGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDFfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck90aGVyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQxXyA9IChiaXRGaWVsZDFfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG90aGVyRmllbGRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3RlcikKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEVudW1QYXJzZVRlc3Rlcj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxFbnVtUGFyc2VUZXN0ZXI+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBFbnVtUGFyc2VUZXN0ZXIgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxFbnVtUGFyc2VUZXN0ZXI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RW51bVBhcnNlVGVzdGVyPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9BUkJJVFJBUllfRVhUX0ZJRUxEX05VTUJFUiA9IDIwMDAwMDA7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+IG9wdGlvbmFsQXJiaXRyYXJ5RXh0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAwLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5LmNsYXNzLAogICAgICAgICAgbnVsbCk7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9BUkJJVFJBUllfRVhUX0ZJRUxEX05VTUJFUiA9IDIwMDAwMDE7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3RlciwKICAgICAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhcnk+PiByZXBlYXRlZEFyYml0cmFyeUV4dCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMSwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeS5jbGFzcywKICAgICAgICAgIG51bGwpOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0FSQklUUkFSWV9FWFRfRklFTERfTlVNQkVSID0gMjAwMDAwMjsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLAogICAgICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeT4+IHBhY2tlZEFyYml0cmFyeUV4dCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMiwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeS5jbGFzcywKICAgICAgICAgIG51bGwpOwogIH0KCiAgcHVibGljIGludGVyZmFjZSBCb29sUGFyc2VUZXN0ZXJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuQm9vbFBhcnNlVGVzdGVyKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy4KICAgICAgICAgIEV4dGVuZGFibGVNZXNzYWdlT3JCdWlsZGVyPEJvb2xQYXJzZVRlc3Rlcj4gewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBvcHRpb25hbF9ib29sX2xvd2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQm9vbExvd2ZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEJvb2xMb3dmaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2xfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQm9vbExvd2ZpZWxkLgogICAgICovCiAgICBib29sZWFuIGdldE9wdGlvbmFsQm9vbExvd2ZpZWxkKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2xfbWlkZmllbGQgPSAxMDAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxCb29sTWlkZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsQm9vbE1pZGZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbF9taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCb29sTWlkZmllbGQuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0T3B0aW9uYWxCb29sTWlkZmllbGQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbF9oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQm9vbEhpZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsQm9vbEhpZmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBvcHRpb25hbF9ib29sX2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQm9vbEhpZmllbGQuCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0T3B0aW9uYWxCb29sSGlmaWVsZCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2xMb3dmaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+IGdldFJlcGVhdGVkQm9vbExvd2ZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2xfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbExvd2ZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRCb29sTG93ZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2xfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sTG93ZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBib29sZWFuIGdldFJlcGVhdGVkQm9vbExvd2ZpZWxkKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2xfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQm9vbE1pZGZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0UmVwZWF0ZWRCb29sTWlkZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCb29sTWlkZmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEJvb2xNaWRmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJvb2xNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0UmVwZWF0ZWRCb29sTWlkZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2xIaWZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0UmVwZWF0ZWRCb29sSGlmaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbEhpZmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEJvb2xIaWZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sSGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0UmVwZWF0ZWRCb29sSGlmaWVsZChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEJvb2xMb3dmaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+IGdldFBhY2tlZEJvb2xMb3dmaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEJvb2xMb3dmaWVsZC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEJvb2xMb3dmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2xfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEJvb2xMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGJvb2xlYW4gZ2V0UGFja2VkQm9vbExvd2ZpZWxkKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkQm9vbE1pZGZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0UGFja2VkQm9vbE1pZGZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkQm9vbE1pZGZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkQm9vbE1pZGZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbF9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkQm9vbE1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRQYWNrZWRCb29sTWlkZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2xfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEJvb2xIaWZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4gZ2V0UGFja2VkQm9vbEhpZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2xfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEJvb2xIaWZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkQm9vbEhpZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEJvb2xIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgYm9vbGVhbiBnZXRQYWNrZWRCb29sSGlmaWVsZChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvdGhlckZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPdGhlckZpZWxkKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBbiBhcmJpdHJhcnkgZmllbGQgd2UgY2FuIGFwcGVuZCB0byB0byBicmVhayB0aGUgcnVucyBvZiByZXBlYXRlZCBmaWVsZHMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdGhlcl9maWVsZCA9IDk5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG90aGVyRmllbGQuCiAgICAgKi8KICAgIGludCBnZXRPdGhlckZpZWxkKCk7CiAgfQogIC8qKgogICAqIDxwcmU+CiAgICogVGhpcyBtZXNzYWdlIGNvbnRhaW5zIGRpZmZlcmVudCBraW5kIG9mIGJvb2wgZmllbGRzIHRvIGV4ZXJjaXNlIHRoZSBkaWZmZXJlbnQKICAgKiBwYXJzZXJzIGluIHRhYmxlLWRyaXZlZC4KICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkJvb2xQYXJzZVRlc3Rlcn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJvb2xQYXJzZVRlc3RlciBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVNZXNzYWdlPAogICAgICAgIEJvb2xQYXJzZVRlc3Rlcj4gaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkJvb2xQYXJzZVRlc3RlcikKICAgICAgQm9vbFBhcnNlVGVzdGVyT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBCb29sUGFyc2VUZXN0ZXIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgQm9vbFBhcnNlVGVzdGVyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBCb29sUGFyc2VUZXN0ZXIoKSB7CiAgICAgIHJlcGVhdGVkQm9vbExvd2ZpZWxkXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcmVwZWF0ZWRCb29sTWlkZmllbGRfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICByZXBlYXRlZEJvb2xIaWZpZWxkXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcGFja2VkQm9vbExvd2ZpZWxkXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcGFja2VkQm9vbE1pZGZpZWxkXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcGFja2VkQm9vbEhpZmllbGRfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEJvb2xQYXJzZVRlc3RlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Jvb2xQYXJzZVRlc3Rlcl9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Jvb2xQYXJzZVRlc3Rlcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3Rlci5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQk9PTF9MT1dGSUVMRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBib29sZWFuIG9wdGlvbmFsQm9vbExvd2ZpZWxkXyA9IGZhbHNlOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2xfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxCb29sTG93ZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEJvb2xMb3dmaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2xfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQm9vbExvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRPcHRpb25hbEJvb2xMb3dmaWVsZCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsQm9vbExvd2ZpZWxkXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9CT09MX01JREZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDE7CiAgICBwcml2YXRlIGJvb2xlYW4gb3B0aW9uYWxCb29sTWlkZmllbGRfID0gZmFsc2U7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbF9taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEJvb2xNaWRmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQm9vbE1pZGZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbF9taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCb29sTWlkZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGdldE9wdGlvbmFsQm9vbE1pZGZpZWxkKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxCb29sTWlkZmllbGRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0JPT0xfSElGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDAwMDAxOwogICAgcHJpdmF0ZSBib29sZWFuIG9wdGlvbmFsQm9vbEhpZmllbGRfID0gZmFsc2U7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbF9oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQm9vbEhpZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEJvb2xIaWZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbF9oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJvb2xIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRPcHRpb25hbEJvb2xIaWZpZWxkKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxCb29sSGlmaWVsZF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQk9PTF9MT1dGSUVMRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgcmVwZWF0ZWRCb29sTG93ZmllbGRfID0KICAgICAgICBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRCb29sTG93ZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBnZXRSZXBlYXRlZEJvb2xMb3dmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJvb2xMb3dmaWVsZF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRCb29sTG93ZmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCb29sTG93ZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbExvd2ZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJvb2xMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBib29sZWFuIGdldFJlcGVhdGVkQm9vbExvd2ZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCb29sTG93ZmllbGRfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0JPT0xfTUlERklFTERfRklFTERfTlVNQkVSID0gMTAwMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHJlcGVhdGVkQm9vbE1pZGZpZWxkXyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2xfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQm9vbE1pZGZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZ2V0UmVwZWF0ZWRCb29sTWlkZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCb29sTWlkZmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2xfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbE1pZGZpZWxkLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkQm9vbE1pZGZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJvb2xNaWRmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2xfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRCb29sTWlkZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2xNaWRmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbE1pZGZpZWxkXy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9CT09MX0hJRklFTERfRklFTERfTlVNQkVSID0gMTAwMDAwMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHJlcGVhdGVkQm9vbEhpZmllbGRfID0KICAgICAgICBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2xIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgZ2V0UmVwZWF0ZWRCb29sSGlmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEJvb2xIaWZpZWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkQm9vbEhpZmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCb29sSGlmaWVsZENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRCb29sSGlmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2xfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJvb2xIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGJvb2xlYW4gZ2V0UmVwZWF0ZWRCb29sSGlmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbEhpZmllbGRfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9CT09MX0xPV0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCBwYWNrZWRCb29sTG93ZmllbGRfID0KICAgICAgICBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2xfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRCb29sTG93ZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBnZXRQYWNrZWRCb29sTG93ZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkQm9vbExvd2ZpZWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEJvb2xMb3dmaWVsZC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRCb29sTG93ZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEJvb2xMb3dmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRCb29sTG93ZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRQYWNrZWRCb29sTG93ZmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRCb29sTG93ZmllbGRfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkQm9vbExvd2ZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9CT09MX01JREZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCBwYWNrZWRCb29sTWlkZmllbGRfID0KICAgICAgICBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2xfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRCb29sTWlkZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICBnZXRQYWNrZWRCb29sTWlkZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gcGFja2VkQm9vbE1pZGZpZWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbF9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEJvb2xNaWRmaWVsZC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRCb29sTWlkZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEJvb2xNaWRmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRCb29sTWlkZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRQYWNrZWRCb29sTWlkZmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiBwYWNrZWRCb29sTWlkZmllbGRfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkQm9vbE1pZGZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9CT09MX0hJRklFTERfRklFTERfTlVNQkVSID0gMTAwMDAwMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHBhY2tlZEJvb2xIaWZpZWxkXyA9CiAgICAgICAgZW1wdHlCb29sZWFuTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRCb29sSGlmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgIGdldFBhY2tlZEJvb2xIaWZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEJvb2xIaWZpZWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbF9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkQm9vbEhpZmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkQm9vbEhpZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEJvb2xIaWZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2xfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkQm9vbEhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgYm9vbGVhbiBnZXRQYWNrZWRCb29sSGlmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEJvb2xIaWZpZWxkXy5nZXRCb29sZWFuKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEJvb2xIaWZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9USEVSX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDk5OwogICAgcHJpdmF0ZSBpbnQgb3RoZXJGaWVsZF8gPSAwOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQW4gYXJiaXRyYXJ5IGZpZWxkIHdlIGNhbiBhcHBlbmQgdG8gdG8gYnJlYWsgdGhlIHJ1bnMgb2YgcmVwZWF0ZWQgZmllbGRzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3RoZXJfZmllbGQgPSA5OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG90aGVyRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPdGhlckZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBBbiBhcmJpdHJhcnkgZmllbGQgd2UgY2FuIGFwcGVuZCB0byB0byBicmVhayB0aGUgcnVucyBvZiByZXBlYXRlZCBmaWVsZHMuCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdGhlcl9maWVsZCA9IDk5OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG90aGVyRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3RoZXJGaWVsZCgpIHsKICAgICAgcmV0dXJuIG90aGVyRmllbGRfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLkV4dGVuZGFibGVNZXNzYWdlPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyPi5FeHRlbnNpb25Xcml0ZXIKICAgICAgICAgIGV4dGVuc2lvbldyaXRlciA9IG5ld0V4dGVuc2lvbldyaXRlcigpOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDEsIG9wdGlvbmFsQm9vbExvd2ZpZWxkXyk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEJvb2xMb3dmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDIsIHJlcGVhdGVkQm9vbExvd2ZpZWxkXy5nZXRCb29sZWFuKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkQm9vbExvd2ZpZWxkTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygyNik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkQm9vbExvd2ZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRCb29sTG93ZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbE5vVGFnKHBhY2tlZEJvb2xMb3dmaWVsZF8uZ2V0Qm9vbGVhbihpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoOTksIG90aGVyRmllbGRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDEwMDEsIG9wdGlvbmFsQm9vbE1pZGZpZWxkXyk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEJvb2xNaWRmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDEwMDIsIHJlcGVhdGVkQm9vbE1pZGZpZWxkXy5nZXRCb29sZWFuKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkQm9vbE1pZGZpZWxkTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MDI2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRCb29sTWlkZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEJvb2xNaWRmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sTm9UYWcocGFja2VkQm9vbE1pZGZpZWxkXy5nZXRCb29sZWFuKGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sKDEwMDAwMDEsIG9wdGlvbmFsQm9vbEhpZmllbGRfKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkQm9vbEhpZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQm9vbCgxMDAwMDAyLCByZXBlYXRlZEJvb2xIaWZpZWxkXy5nZXRCb29sZWFuKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkQm9vbEhpZmllbGRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDgwMDAwMjYpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEJvb2xIaWZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRCb29sSGlmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVCb29sTm9UYWcocGFja2VkQm9vbEhpZmllbGRfLmdldEJvb2xlYW4oaSkpOwogICAgICB9CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDUzNjg3MDkxMiwgb3V0cHV0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCb29sU2l6ZSgxLCBvcHRpb25hbEJvb2xMb3dmaWVsZF8pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gMSAqIGdldFJlcGVhdGVkQm9vbExvd2ZpZWxkTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkQm9vbExvd2ZpZWxkTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDEgKiBnZXRQYWNrZWRCb29sTG93ZmllbGRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRCb29sTG93ZmllbGRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDE7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkQm9vbExvd2ZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoOTksIG90aGVyRmllbGRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQm9vbFNpemUoMTAwMSwgb3B0aW9uYWxCb29sTWlkZmllbGRfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBkYXRhU2l6ZSA9IDEgKiBnZXRSZXBlYXRlZEJvb2xNaWRmaWVsZExpc3QoKS5zaXplKCk7CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZEJvb2xNaWRmaWVsZExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSAxICogZ2V0UGFja2VkQm9vbE1pZGZpZWxkTGlzdCgpLnNpemUoKTsKICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkQm9vbE1pZGZpZWxkTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEJvb2xNaWRmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQm9vbFNpemUoMTAwMDAwMSwgb3B0aW9uYWxCb29sSGlmaWVsZF8pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGRhdGFTaXplID0gMSAqIGdldFJlcGVhdGVkQm9vbEhpZmllbGRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSA0ICogZ2V0UmVwZWF0ZWRCb29sSGlmaWVsZExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZGF0YVNpemUgPSAxICogZ2V0UGFja2VkQm9vbEhpZmllbGRMaXN0KCkuc2l6ZSgpOwogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRCb29sSGlmaWVsZExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gNDsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRCb29sSGlmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlcikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIpIG9iajsKCiAgICAgIGlmIChoYXNPcHRpb25hbEJvb2xMb3dmaWVsZCgpICE9IG90aGVyLmhhc09wdGlvbmFsQm9vbExvd2ZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsQm9vbExvd2ZpZWxkKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxCb29sTG93ZmllbGQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEJvb2xMb3dmaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsQm9vbE1pZGZpZWxkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxCb29sTWlkZmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxCb29sTWlkZmllbGQoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEJvb2xNaWRmaWVsZCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsQm9vbE1pZGZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxCb29sSGlmaWVsZCgpICE9IG90aGVyLmhhc09wdGlvbmFsQm9vbEhpZmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxCb29sSGlmaWVsZCgpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsQm9vbEhpZmllbGQoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRPcHRpb25hbEJvb2xIaWZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFJlcGVhdGVkQm9vbExvd2ZpZWxkTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQm9vbExvd2ZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkQm9vbE1pZGZpZWxkTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkQm9vbE1pZGZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkQm9vbEhpZmllbGRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRCb29sSGlmaWVsZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRCb29sTG93ZmllbGRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkQm9vbExvd2ZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEJvb2xNaWRmaWVsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRCb29sTWlkZmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkQm9vbEhpZmllbGRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UGFja2VkQm9vbEhpZmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPdGhlckZpZWxkKCkgIT0gb3RoZXIuaGFzT3RoZXJGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPdGhlckZpZWxkKCkpIHsKICAgICAgICBpZiAoZ2V0T3RoZXJGaWVsZCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE90aGVyRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RXh0ZW5zaW9uRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldEV4dGVuc2lvbkZpZWxkcygpKSkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsQm9vbExvd2ZpZWxkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9CT09MX0xPV0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hCb29sZWFuKAogICAgICAgICAgICBnZXRPcHRpb25hbEJvb2xMb3dmaWVsZCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxCb29sTWlkZmllbGQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0JPT0xfTUlERklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldE9wdGlvbmFsQm9vbE1pZGZpZWxkKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEJvb2xIaWZpZWxkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9CT09MX0hJRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaEJvb2xlYW4oCiAgICAgICAgICAgIGdldE9wdGlvbmFsQm9vbEhpZmllbGQoKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkQm9vbExvd2ZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9CT09MX0xPV0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEJvb2xMb3dmaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEJvb2xNaWRmaWVsZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQk9PTF9NSURGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRCb29sTWlkZmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRCb29sSGlmaWVsZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfQk9PTF9ISUZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEJvb2xIaWZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEJvb2xMb3dmaWVsZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUEFDS0VEX0JPT0xfTE9XRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEJvb2xMb3dmaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRCb29sTWlkZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9CT09MX01JREZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQYWNrZWRCb29sTWlkZmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkQm9vbEhpZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9CT09MX0hJRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEJvb2xIaWZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc090aGVyRmllbGQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9USEVSX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPdGhlckZpZWxkKCk7CiAgICAgIH0KICAgICAgaGFzaCA9IGhhc2hGaWVsZHMoaGFzaCwgZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlciBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlciBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlciBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogVGhpcyBtZXNzYWdlIGNvbnRhaW5zIGRpZmZlcmVudCBraW5kIG9mIGJvb2wgZmllbGRzIHRvIGV4ZXJjaXNlIHRoZSBkaWZmZXJlbnQKICAgICAqIHBhcnNlcnMgaW4gdGFibGUtZHJpdmVkLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuQm9vbFBhcnNlVGVzdGVyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIsIEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkJvb2xQYXJzZVRlc3RlcikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3Rlck9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Cb29sUGFyc2VUZXN0ZXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQm9vbFBhcnNlVGVzdGVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3Rlci5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbEJvb2xMb3dmaWVsZF8gPSBmYWxzZTsKICAgICAgICBvcHRpb25hbEJvb2xNaWRmaWVsZF8gPSBmYWxzZTsKICAgICAgICBvcHRpb25hbEJvb2xIaWZpZWxkXyA9IGZhbHNlOwogICAgICAgIHJlcGVhdGVkQm9vbExvd2ZpZWxkXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICByZXBlYXRlZEJvb2xNaWRmaWVsZF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRCb29sSGlmaWVsZF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgcGFja2VkQm9vbExvd2ZpZWxkXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBwYWNrZWRCb29sTWlkZmllbGRfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIHBhY2tlZEJvb2xIaWZpZWxkXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBvdGhlckZpZWxkXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Jvb2xQYXJzZVRlc3Rlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlciBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3Rlci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsQm9vbExvd2ZpZWxkXyA9IG9wdGlvbmFsQm9vbExvd2ZpZWxkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbEJvb2xNaWRmaWVsZF8gPSBvcHRpb25hbEJvb2xNaWRmaWVsZF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxCb29sSGlmaWVsZF8gPSBvcHRpb25hbEJvb2xIaWZpZWxkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkQm9vbExvd2ZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRCb29sTG93ZmllbGRfID0gcmVwZWF0ZWRCb29sTG93ZmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRCb29sTWlkZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZEJvb2xNaWRmaWVsZF8gPSByZXBlYXRlZEJvb2xNaWRmaWVsZF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xIaWZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRCb29sSGlmaWVsZF8gPSByZXBlYXRlZEJvb2xIaWZpZWxkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEJvb2xMb3dmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZEJvb2xMb3dmaWVsZF8gPSBwYWNrZWRCb29sTG93ZmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkQm9vbE1pZGZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucGFja2VkQm9vbE1pZGZpZWxkXyA9IHBhY2tlZEJvb2xNaWRmaWVsZF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRCb29sSGlmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZEJvb2xIaWZpZWxkXyA9IHBhY2tlZEJvb2xIaWZpZWxkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vdGhlckZpZWxkXyA9IG90aGVyRmllbGRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlciwgVHlwZT4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlciwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VD4gQnVpbGRlciBjbGVhckV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIsIFQ+IGV4dGVuc2lvbikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckV4dGVuc2lvbihleHRlbnNpb24pOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlcilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlciBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3Rlci5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsQm9vbExvd2ZpZWxkKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsQm9vbExvd2ZpZWxkKG90aGVyLmdldE9wdGlvbmFsQm9vbExvd2ZpZWxkKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxCb29sTWlkZmllbGQoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxCb29sTWlkZmllbGQob3RoZXIuZ2V0T3B0aW9uYWxCb29sTWlkZmllbGQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEJvb2xIaWZpZWxkKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsQm9vbEhpZmllbGQob3RoZXIuZ2V0T3B0aW9uYWxCb29sSGlmaWVsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEJvb2xMb3dmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRCb29sTG93ZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZEJvb2xMb3dmaWVsZF8gPSBvdGhlci5yZXBlYXRlZEJvb2xMb3dmaWVsZF87CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbExvd2ZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbExvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbExvd2ZpZWxkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRCb29sTG93ZmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkQm9vbE1pZGZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZEJvb2xNaWRmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbE1pZGZpZWxkXyA9IG90aGVyLnJlcGVhdGVkQm9vbE1pZGZpZWxkXzsKICAgICAgICAgICAgcmVwZWF0ZWRCb29sTWlkZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRCb29sTWlkZmllbGRfLmFkZEFsbChvdGhlci5yZXBlYXRlZEJvb2xNaWRmaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRCb29sSGlmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRCb29sSGlmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbEhpZmllbGRfID0gb3RoZXIucmVwZWF0ZWRCb29sSGlmaWVsZF87CiAgICAgICAgICAgIHJlcGVhdGVkQm9vbEhpZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEJvb2xIaWZpZWxkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRCb29sSGlmaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucGFja2VkQm9vbExvd2ZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRCb29sTG93ZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRCb29sTG93ZmllbGRfID0gb3RoZXIucGFja2VkQm9vbExvd2ZpZWxkXzsKICAgICAgICAgICAgcGFja2VkQm9vbExvd2ZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZEJvb2xMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICBwYWNrZWRCb29sTG93ZmllbGRfLmFkZEFsbChvdGhlci5wYWNrZWRCb29sTG93ZmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnBhY2tlZEJvb2xNaWRmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkQm9vbE1pZGZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkQm9vbE1pZGZpZWxkXyA9IG90aGVyLnBhY2tlZEJvb2xNaWRmaWVsZF87CiAgICAgICAgICAgIHBhY2tlZEJvb2xNaWRmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRCb29sTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcGFja2VkQm9vbE1pZGZpZWxkXy5hZGRBbGwob3RoZXIucGFja2VkQm9vbE1pZGZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRCb29sSGlmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocGFja2VkQm9vbEhpZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgICBwYWNrZWRCb29sSGlmaWVsZF8gPSBvdGhlci5wYWNrZWRCb29sSGlmaWVsZF87CiAgICAgICAgICAgIHBhY2tlZEJvb2xIaWZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVBhY2tlZEJvb2xIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEJvb2xIaWZpZWxkXy5hZGRBbGwob3RoZXIucGFja2VkQm9vbEhpZmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3RoZXJGaWVsZCgpKSB7CiAgICAgICAgICBzZXRPdGhlckZpZWxkKG90aGVyLmdldE90aGVyRmllbGQoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VFeHRlbnNpb25GaWVsZHMob3RoZXIpOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEJvb2xMb3dmaWVsZF8gPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICBib29sZWFuIHYgPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkQm9vbExvd2ZpZWxkXy5hZGRCb29sZWFuKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbExvd2ZpZWxkSXNNdXRhYmxlKGFsbG9jIC8gMSk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkQm9vbExvd2ZpZWxkXy5hZGRCb29sZWFuKGlucHV0LnJlYWRCb29sKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgYm9vbGVhbiB2ID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEJvb2xMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkQm9vbExvd2ZpZWxkXy5hZGRCb29sZWFuKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEJvb2xMb3dmaWVsZElzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRCb29sTG93ZmllbGRfLmFkZEJvb2xlYW4oaW5wdXQucmVhZEJvb2woKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDc5MjogewogICAgICAgICAgICAgICAgb3RoZXJGaWVsZF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3OTIKICAgICAgICAgICAgICBjYXNlIDgwMDg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsQm9vbE1pZGZpZWxkXyA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwOAogICAgICAgICAgICAgIGNhc2UgODAxNjogewogICAgICAgICAgICAgICAgYm9vbGVhbiB2ID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbE1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEJvb2xNaWRmaWVsZF8uYWRkQm9vbGVhbih2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDE2CiAgICAgICAgICAgICAgY2FzZSA4MDE4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sTWlkZmllbGRJc011dGFibGUoYWxsb2MgLyAxKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRCb29sTWlkZmllbGRfLmFkZEJvb2xlYW4oaW5wdXQucmVhZEJvb2woKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAxOAogICAgICAgICAgICAgIGNhc2UgODAyNDogewogICAgICAgICAgICAgICAgYm9vbGVhbiB2ID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEJvb2xNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkQm9vbE1pZGZpZWxkXy5hZGRCb29sZWFuKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMjQKICAgICAgICAgICAgICBjYXNlIDgwMjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgaW50IGFsbG9jID0gbGVuZ3RoID4gNDA5NiA/IDQwOTYgOiBsZW5ndGg7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRCb29sTWlkZmllbGRJc011dGFibGUoYWxsb2MgLyAxKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkQm9vbE1pZGZpZWxkXy5hZGRCb29sZWFuKGlucHV0LnJlYWRCb29sKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMjYKICAgICAgICAgICAgICBjYXNlIDgwMDAwMDg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsQm9vbEhpZmllbGRfID0gaW5wdXQucmVhZEJvb2woKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDAwMDA4CiAgICAgICAgICAgICAgY2FzZSA4MDAwMDE2OiB7CiAgICAgICAgICAgICAgICBib29sZWFuIHYgPSBpbnB1dC5yZWFkQm9vbCgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRCb29sSGlmaWVsZF8uYWRkQm9vbGVhbih2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDAwMDE2CiAgICAgICAgICAgICAgY2FzZSA4MDAwMDE4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGludCBhbGxvYyA9IGxlbmd0aCA+IDQwOTYgPyA0MDk2IDogbGVuZ3RoOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSGlmaWVsZElzTXV0YWJsZShhbGxvYyAvIDEpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEJvb2xIaWZpZWxkXy5hZGRCb29sZWFuKGlucHV0LnJlYWRCb29sKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAwMTgKICAgICAgICAgICAgICBjYXNlIDgwMDAwMjQ6IHsKICAgICAgICAgICAgICAgIGJvb2xlYW4gdiA9IGlucHV0LnJlYWRCb29sKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRCb29sSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkQm9vbEhpZmllbGRfLmFkZEJvb2xlYW4odik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMDAyNAogICAgICAgICAgICAgIGNhc2UgODAwMDAyNjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBpbnQgYWxsb2MgPSBsZW5ndGggPiA0MDk2ID8gNDA5NiA6IGxlbmd0aDsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEJvb2xIaWZpZWxkSXNNdXRhYmxlKGFsbG9jIC8gMSk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZEJvb2xIaWZpZWxkXy5hZGRCb29sZWFuKGlucHV0LnJlYWRCb29sKCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQobGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAwMjYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBib29sZWFuIG9wdGlvbmFsQm9vbExvd2ZpZWxkXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2xfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEJvb2xMb3dmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsQm9vbExvd2ZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBvcHRpb25hbF9ib29sX2xvd2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQm9vbExvd2ZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRPcHRpb25hbEJvb2xMb3dmaWVsZCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxCb29sTG93ZmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2xfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEJvb2xMb3dmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsQm9vbExvd2ZpZWxkKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxCb29sTG93ZmllbGRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2xfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEJvb2xMb3dmaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb3B0aW9uYWxCb29sTG93ZmllbGRfID0gZmFsc2U7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgYm9vbGVhbiBvcHRpb25hbEJvb2xNaWRmaWVsZF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBvcHRpb25hbF9ib29sX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxCb29sTWlkZmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEJvb2xNaWRmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbF9taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJvb2xNaWRmaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZ2V0T3B0aW9uYWxCb29sTWlkZmllbGQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsQm9vbE1pZGZpZWxkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBvcHRpb25hbF9ib29sX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxCb29sTWlkZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEJvb2xNaWRmaWVsZChib29sZWFuIHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsQm9vbE1pZGZpZWxkXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBvcHRpb25hbF9ib29sX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxCb29sTWlkZmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9wdGlvbmFsQm9vbE1pZGZpZWxkXyA9IGZhbHNlOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGJvb2xlYW4gb3B0aW9uYWxCb29sSGlmaWVsZF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYm9vbCBvcHRpb25hbF9ib29sX2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEJvb2xIaWZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxCb29sSGlmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbF9oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsQm9vbEhpZmllbGQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGdldE9wdGlvbmFsQm9vbEhpZmllbGQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsQm9vbEhpZmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBib29sIG9wdGlvbmFsX2Jvb2xfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsQm9vbEhpZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEJvb2xIaWZpZWxkKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxCb29sSGlmaWVsZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJvb2wgb3B0aW9uYWxfYm9vbF9oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxCb29sSGlmaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwNCk7CiAgICAgICAgb3B0aW9uYWxCb29sSGlmaWVsZF8gPSBmYWxzZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHJlcGVhdGVkQm9vbExvd2ZpZWxkXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQm9vbExvd2ZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRCb29sTG93ZmllbGRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xMb3dmaWVsZF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRCb29sTG93ZmllbGRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEJvb2xMb3dmaWVsZElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQm9vbExvd2ZpZWxkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRCb29sTG93ZmllbGRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkQm9vbExvd2ZpZWxkXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2xMb3dmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldFJlcGVhdGVkQm9vbExvd2ZpZWxkTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEJvb2xMb3dmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEJvb2xMb3dmaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJvb2xMb3dmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCb29sTG93ZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sTG93ZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJvb2xMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2xMb3dmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sTG93ZmllbGRfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2xfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQm9vbExvd2ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRCb29sTG93ZmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJvb2xMb3dmaWVsZF8uc2V0Qm9vbGVhbihpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRCb29sTG93ZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEJvb2xMb3dmaWVsZChib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbExvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCb29sTG93ZmllbGRfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkQm9vbExvd2ZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRCb29sTG93ZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEJvb2xMb3dmaWVsZF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRCb29sTG93ZmllbGQoKSB7CiAgICAgICAgcmVwZWF0ZWRCb29sTG93ZmllbGRfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHJlcGVhdGVkQm9vbE1pZGZpZWxkXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkQm9vbE1pZGZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRCb29sTWlkZmllbGRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xNaWRmaWVsZF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRCb29sTWlkZmllbGRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEJvb2xNaWRmaWVsZElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQm9vbE1pZGZpZWxkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRCb29sTWlkZmllbGRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkQm9vbE1pZGZpZWxkXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEJvb2xNaWRmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4KICAgICAgICAgIGdldFJlcGVhdGVkQm9vbE1pZGZpZWxkTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEJvb2xNaWRmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEJvb2xNaWRmaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJvb2xNaWRmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRCb29sTWlkZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sTWlkZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEJvb2xNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRSZXBlYXRlZEJvb2xNaWRmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sTWlkZmllbGRfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2xfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkQm9vbE1pZGZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRCb29sTWlkZmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJvb2xNaWRmaWVsZF8uc2V0Qm9vbGVhbihpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRCb29sTWlkZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEJvb2xNaWRmaWVsZChib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbE1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCb29sTWlkZmllbGRfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkQm9vbE1pZGZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRCb29sTWlkZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEJvb2xNaWRmaWVsZF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRCb29sTWlkZmllbGQoKSB7CiAgICAgICAgcmVwZWF0ZWRCb29sTWlkZmllbGRfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHJlcGVhdGVkQm9vbEhpZmllbGRfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRCb29sSGlmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQm9vbEhpZmllbGRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xIaWZpZWxkXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEJvb2xIaWZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRCb29sSGlmaWVsZElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkQm9vbEhpZmllbGRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEJvb2xIaWZpZWxkXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEJvb2xIaWZpZWxkXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkQm9vbEhpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRSZXBlYXRlZEJvb2xIaWZpZWxkTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEJvb2xIaWZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbEhpZmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2xfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEJvb2xIaWZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEJvb2xIaWZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkQm9vbEhpZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkQm9vbEhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gZ2V0UmVwZWF0ZWRCb29sSGlmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRCb29sSGlmaWVsZF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJvb2xIaWZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRCb29sSGlmaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEJvb2xIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRCb29sSGlmaWVsZF8uc2V0Qm9vbGVhbihpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCByZXBlYXRlZF9ib29sX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEJvb2xIaWZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRCb29sSGlmaWVsZChib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkQm9vbEhpZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEJvb2xIaWZpZWxkXy5hZGRCb29sZWFuKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcmVwZWF0ZWRfYm9vbF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkQm9vbEhpZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEJvb2xIaWZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRCb29sSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEJvb2xIaWZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHJlcGVhdGVkX2Jvb2xfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkQm9vbEhpZmllbGQoKSB7CiAgICAgICAgcmVwZWF0ZWRCb29sSGlmaWVsZF8gPSBlbXB0eUJvb2xlYW5MaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuQm9vbGVhbkxpc3QgcGFja2VkQm9vbExvd2ZpZWxkXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEJvb2xMb3dmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEJvb2xMb3dmaWVsZF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEJvb2xMb3dmaWVsZF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkQm9vbExvd2ZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkQm9vbExvd2ZpZWxkSXNNdXRhYmxlKGludCBjYXBhY2l0eSkgewogICAgICAgIGlmICghcGFja2VkQm9vbExvd2ZpZWxkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkQm9vbExvd2ZpZWxkXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRCb29sTG93ZmllbGRfLCBjYXBhY2l0eSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkQm9vbExvd2ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPgogICAgICAgICAgZ2V0UGFja2VkQm9vbExvd2ZpZWxkTGlzdCgpIHsKICAgICAgICBwYWNrZWRCb29sTG93ZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkQm9vbExvd2ZpZWxkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkQm9vbExvd2ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRCb29sTG93ZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkQm9vbExvd2ZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2xfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRCb29sTG93ZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gZ2V0UGFja2VkQm9vbExvd2ZpZWxkKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRCb29sTG93ZmllbGRfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkQm9vbExvd2ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkQm9vbExvd2ZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEJvb2xMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEJvb2xMb3dmaWVsZF8uc2V0Qm9vbGVhbihpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRCb29sTG93ZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRCb29sTG93ZmllbGQoYm9vbGVhbiB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRCb29sTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRCb29sTG93ZmllbGRfLmFkZEJvb2xlYW4odmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkQm9vbExvd2ZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkQm9vbExvd2ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuQm9vbGVhbj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkQm9vbExvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEJvb2xMb3dmaWVsZF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRCb29sTG93ZmllbGQoKSB7CiAgICAgICAgcGFja2VkQm9vbExvd2ZpZWxkXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Cb29sZWFuTGlzdCBwYWNrZWRCb29sTWlkZmllbGRfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkQm9vbE1pZGZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkQm9vbE1pZGZpZWxkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkQm9vbE1pZGZpZWxkXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRCb29sTWlkZmllbGRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRCb29sTWlkZmllbGRJc011dGFibGUoaW50IGNhcGFjaXR5KSB7CiAgICAgICAgaWYgKCFwYWNrZWRCb29sTWlkZmllbGRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRCb29sTWlkZmllbGRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEJvb2xNaWRmaWVsZF8sIGNhcGFjaXR5KTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRCb29sTWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRQYWNrZWRCb29sTWlkZmllbGRMaXN0KCkgewogICAgICAgIHBhY2tlZEJvb2xNaWRmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRCb29sTWlkZmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRCb29sTWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEJvb2xNaWRmaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRCb29sTWlkZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbF9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEJvb2xNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRQYWNrZWRCb29sTWlkZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEJvb2xNaWRmaWVsZF8uZ2V0Qm9vbGVhbihpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2xfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRCb29sTWlkZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRCb29sTWlkZmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkQm9vbE1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkQm9vbE1pZGZpZWxkXy5zZXRCb29sZWFuKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEJvb2xNaWRmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEJvb2xNaWRmaWVsZChib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEJvb2xNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEJvb2xNaWRmaWVsZF8uYWRkQm9vbGVhbih2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRCb29sTWlkZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxQYWNrZWRCb29sTWlkZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRCb29sTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkQm9vbE1pZGZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEJvb2xNaWRmaWVsZCgpIHsKICAgICAgICBwYWNrZWRCb29sTWlkZmllbGRfID0gZW1wdHlCb29sZWFuTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkJvb2xlYW5MaXN0IHBhY2tlZEJvb2xIaWZpZWxkXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEJvb2xIaWZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkQm9vbEhpZmllbGRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRCb29sSGlmaWVsZF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkQm9vbEhpZmllbGRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRCb29sSGlmaWVsZElzTXV0YWJsZShpbnQgY2FwYWNpdHkpIHsKICAgICAgICBpZiAoIXBhY2tlZEJvb2xIaWZpZWxkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcGFja2VkQm9vbEhpZmllbGRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEJvb2xIaWZpZWxkXywgY2FwYWNpdHkpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2xfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkQm9vbEhpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+CiAgICAgICAgICBnZXRQYWNrZWRCb29sSGlmaWVsZExpc3QoKSB7CiAgICAgICAgcGFja2VkQm9vbEhpZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcGFja2VkQm9vbEhpZmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEJvb2xIaWZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRCb29sSGlmaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRCb29sSGlmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRCb29sSGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBnZXRQYWNrZWRCb29sSGlmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcGFja2VkQm9vbEhpZmllbGRfLmdldEJvb2xlYW4oaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRCb29sSGlmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEJvb2xIaWZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBib29sZWFuIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEJvb2xIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkQm9vbEhpZmllbGRfLnNldEJvb2xlYW4oaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGJvb2wgcGFja2VkX2Jvb2xfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRCb29sSGlmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEJvb2xIaWZpZWxkKGJvb2xlYW4gdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkQm9vbEhpZmllbGRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRCb29sSGlmaWVsZF8uYWRkQm9vbGVhbih2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBib29sIHBhY2tlZF9ib29sX2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZEJvb2xIaWZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkQm9vbEhpZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Cb29sZWFuPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRCb29sSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRCb29sSGlmaWVsZF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgYm9vbCBwYWNrZWRfYm9vbF9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEJvb2xIaWZpZWxkKCkgewogICAgICAgIHBhY2tlZEJvb2xIaWZpZWxkXyA9IGVtcHR5Qm9vbGVhbkxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDEwMCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG90aGVyRmllbGRfIDsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG90aGVyRmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPdGhlckZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQW4gYXJiaXRyYXJ5IGZpZWxkIHdlIGNhbiBhcHBlbmQgdG8gdG8gYnJlYWsgdGhlIHJ1bnMgb2YgcmVwZWF0ZWQgZmllbGRzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3RoZXJfZmllbGQgPSA5OTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG90aGVyRmllbGQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3RoZXJGaWVsZCgpIHsKICAgICAgICByZXR1cm4gb3RoZXJGaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG90aGVyRmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPdGhlckZpZWxkKGludCB2YWx1ZSkgewoKICAgICAgICBvdGhlckZpZWxkXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogQW4gYXJiaXRyYXJ5IGZpZWxkIHdlIGNhbiBhcHBlbmQgdG8gdG8gYnJlYWsgdGhlIHJ1bnMgb2YgcmVwZWF0ZWQgZmllbGRzLgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3RoZXJfZmllbGQgPSA5OTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3RoZXJGaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDIwMCk7CiAgICAgICAgb3RoZXJGaWVsZF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkJvb2xQYXJzZVRlc3RlcikKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQm9vbFBhcnNlVGVzdGVyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8Qm9vbFBhcnNlVGVzdGVyPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPEJvb2xQYXJzZVRlc3Rlcj4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJvb2xQYXJzZVRlc3RlciBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJvb2xQYXJzZVRlc3Rlcj4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxCb29sUGFyc2VUZXN0ZXI+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0JPT0xfRVhUX0ZJRUxEX05VTUJFUiA9IDIwMDAwMDA7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuQm9vbFBhcnNlVGVzdGVyIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlciwKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbj4gb3B0aW9uYWxCb29sRXh0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Cb29sUGFyc2VUZXN0ZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAwLAogICAgICAgICAgamF2YS5sYW5nLkJvb2xlYW4uY2xhc3MsCiAgICAgICAgICBudWxsKTsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0JPT0xfRVhUX0ZJRUxEX05VTUJFUiA9IDIwMDAwMDE7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuQm9vbFBhcnNlVGVzdGVyIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJvb2xQYXJzZVRlc3RlciwKICAgICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4+IHJlcGVhdGVkQm9vbEV4dCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMSwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLmNsYXNzLAogICAgICAgICAgbnVsbCk7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfQk9PTF9FWFRfRklFTERfTlVNQkVSID0gMjAwMDAwMjsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5Cb29sUGFyc2VUZXN0ZXIgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyLAogICAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPj4gcGFja2VkQm9vbEV4dCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQm9vbFBhcnNlVGVzdGVyLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMiwKICAgICAgICAgIGphdmEubGFuZy5Cb29sZWFuLmNsYXNzLAogICAgICAgICAgbnVsbCk7CiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEludDMyUGFyc2VUZXN0ZXJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuSW50MzJQYXJzZVRlc3RlcikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxJbnQzMlBhcnNlVGVzdGVyPiB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl9sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyTG93ZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzJMb3dmaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl9sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMkxvd2ZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxJbnQzMkxvd2ZpZWxkKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl9taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMyTWlkZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzJNaWRmaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl9taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMk1pZGZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0T3B0aW9uYWxJbnQzMk1pZGZpZWxkKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzJIaWZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDMySGlmaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMySGlmaWVsZC4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzJIaWZpZWxkKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMl9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMkxvd2ZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRJbnQzMkxvd2ZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMl9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMkxvd2ZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkxvd2ZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMkxvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW50MzJMb3dmaWVsZChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzJNaWRmaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFJlcGVhdGVkSW50MzJNaWRmaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzJNaWRmaWVsZC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW50MzJNaWRmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzJNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDMyTWlkZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzJIaWZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UmVwZWF0ZWRJbnQzMkhpZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzJIaWZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkhpZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzJIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkSW50MzJIaWZpZWxkKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzJfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQzMkxvd2ZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkSW50MzJMb3dmaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50MzJMb3dmaWVsZC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEludDMyTG93ZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzJfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDMyTG93ZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkSW50MzJMb3dmaWVsZChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50MzJNaWRmaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IGdldFBhY2tlZEludDMyTWlkZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDMyTWlkZmllbGQuCiAgICAgKi8KICAgIGludCBnZXRQYWNrZWRJbnQzMk1pZGZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQzMk1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEludDMyTWlkZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50MzJIaWZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4gZ2V0UGFja2VkSW50MzJIaWZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzJfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDMySGlmaWVsZC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEludDMySGlmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQzMkhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkSW50MzJIaWZpZWxkKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQW4gYXJiaXRyYXJ5IGZpZWxkIHdlIGNhbiBhcHBlbmQgdG8gdG8gYnJlYWsgdGhlIHJ1bnMgb2YgcmVwZWF0ZWQgZmllbGRzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3RoZXJfZmllbGQgPSA5OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG90aGVyRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc090aGVyRmllbGQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3RoZXJGaWVsZC4KICAgICAqLwogICAgaW50IGdldE90aGVyRmllbGQoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuSW50MzJQYXJzZVRlc3Rlcn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEludDMyUGFyc2VUZXN0ZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgICBJbnQzMlBhcnNlVGVzdGVyPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuSW50MzJQYXJzZVRlc3RlcikKICAgICAgSW50MzJQYXJzZVRlc3Rlck9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgSW50MzJQYXJzZVRlc3Rlci5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBJbnQzMlBhcnNlVGVzdGVyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlciwgPz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgSW50MzJQYXJzZVRlc3RlcigpIHsKICAgICAgcmVwZWF0ZWRJbnQzMkxvd2ZpZWxkXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICByZXBlYXRlZEludDMyTWlkZmllbGRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHJlcGVhdGVkSW50MzJIaWZpZWxkXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRJbnQzMkxvd2ZpZWxkXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRJbnQzMk1pZGZpZWxkXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwYWNrZWRJbnQzMkhpZmllbGRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgSW50MzJQYXJzZVRlc3RlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDMyUGFyc2VUZXN0ZXJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbnQzMlBhcnNlVGVzdGVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyX0xPV0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyTG93ZmllbGRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMkxvd2ZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMkxvd2ZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyX2xvd2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyTG93ZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMkxvd2ZpZWxkKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMkxvd2ZpZWxkXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQzMl9NSURGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDAxOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMk1pZGZpZWxkXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzJNaWRmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzJNaWRmaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl9taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMk1pZGZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzJNaWRmaWVsZCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzJNaWRmaWVsZF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UMzJfSElGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDAwMDAxOwogICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMkhpZmllbGRfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDMySGlmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzJIaWZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyX2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzJIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzJIaWZpZWxkKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMkhpZmllbGRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDMyX0xPV0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkSW50MzJMb3dmaWVsZF8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMl9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMkxvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRJbnQzMkxvd2ZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJMb3dmaWVsZF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMyTG93ZmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkxvd2ZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMyTG93ZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMkxvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyTG93ZmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMyTG93ZmllbGRfLmdldEludChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfSU5UMzJfTUlERklFTERfRklFTERfTlVNQkVSID0gMTAwMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRJbnQzMk1pZGZpZWxkXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMyTWlkZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRSZXBlYXRlZEludDMyTWlkZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMk1pZGZpZWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzJNaWRmaWVsZC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyTWlkZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJNaWRmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMl9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDMyTWlkZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzJNaWRmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJNaWRmaWVsZF8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTlQzMl9ISUZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDAwMDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkSW50MzJIaWZpZWxkXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzJIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UmVwZWF0ZWRJbnQzMkhpZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMkhpZmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDMySGlmaWVsZC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMySGlmaWVsZENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMkhpZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDMySGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkhpZmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDMySGlmaWVsZF8uZ2V0SW50KGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfSU5UMzJfTE9XRklFTERfRklFTERfTlVNQkVSID0gMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkSW50MzJMb3dmaWVsZF8gPQogICAgICAgIGVtcHR5SW50TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzJfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQzMkxvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UGFja2VkSW50MzJMb3dmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQzMkxvd2ZpZWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50MzJMb3dmaWVsZC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQzMkxvd2ZpZWxkQ291bnQoKSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQzMkxvd2ZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkSW50MzJMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50MzJMb3dmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDMyTG93ZmllbGRfLmdldEludChpbmRleCk7CiAgICB9CiAgICBwcml2YXRlIGludCBwYWNrZWRJbnQzMkxvd2ZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IC0xOwoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9JTlQzMl9NSURGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRJbnQzMk1pZGZpZWxkXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDMyTWlkZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICBnZXRQYWNrZWRJbnQzMk1pZGZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDMyTWlkZmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzJfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQzMk1pZGZpZWxkLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMyTWlkZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDMyTWlkZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQzMk1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQzMk1pZGZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkSW50MzJNaWRmaWVsZF8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEludDMyTWlkZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gLTE7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0lOVDMyX0hJRklFTERfRklFTERfTlVNQkVSID0gMTAwMDAwMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcGFja2VkSW50MzJIaWZpZWxkXyA9CiAgICAgICAgZW1wdHlJbnRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcGFja2VkSW50MzJIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgZ2V0UGFja2VkSW50MzJIaWZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDMySGlmaWVsZF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50MzJIaWZpZWxkLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMySGlmaWVsZENvdW50KCkgewogICAgICByZXR1cm4gcGFja2VkSW50MzJIaWZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQzMkhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMySGlmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDMySGlmaWVsZF8uZ2V0SW50KGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEludDMySGlmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPVEhFUl9GSUVMRF9GSUVMRF9OVU1CRVIgPSA5OTsKICAgIHByaXZhdGUgaW50IG90aGVyRmllbGRfID0gMDsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvdGhlckZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3RoZXJGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQW4gYXJiaXRyYXJ5IGZpZWxkIHdlIGNhbiBhcHBlbmQgdG8gdG8gYnJlYWsgdGhlIHJ1bnMgb2YgcmVwZWF0ZWQgZmllbGRzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3RoZXJfZmllbGQgPSA5OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvdGhlckZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE90aGVyRmllbGQoKSB7CiAgICAgIHJldHVybiBvdGhlckZpZWxkXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5FeHRlbmRhYmxlTWVzc2FnZTxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXI+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIG9wdGlvbmFsSW50MzJMb3dmaWVsZF8pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMkxvd2ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIHJlcGVhdGVkSW50MzJMb3dmaWVsZF8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkSW50MzJMb3dmaWVsZExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoMjYpOwogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKHBhY2tlZEludDMyTG93ZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEludDMyTG93ZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzJOb1RhZyhwYWNrZWRJbnQzMkxvd2ZpZWxkXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDk5LCBvdGhlckZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMTAwMSwgb3B0aW9uYWxJbnQzMk1pZGZpZWxkXyk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDMyTWlkZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMTAwMiwgcmVwZWF0ZWRJbnQzMk1pZGZpZWxkXy5nZXRJbnQoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRJbnQzMk1pZGZpZWxkTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MDI2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRJbnQzMk1pZGZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRJbnQzMk1pZGZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDMyTm9UYWcocGFja2VkSW50MzJNaWRmaWVsZF8uZ2V0SW50KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigxMDAwMDAxLCBvcHRpb25hbEludDMySGlmaWVsZF8pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQzMkhpZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMTAwMDAwMiwgcmVwZWF0ZWRJbnQzMkhpZmllbGRfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEludDMySGlmaWVsZExpc3QoKS5zaXplKCkgPiAwKSB7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcoODAwMDAyNik7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcocGFja2VkSW50MzJIaWZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRJbnQzMkhpZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzJOb1RhZyhwYWNrZWRJbnQzMkhpZmllbGRfLmdldEludChpKSk7CiAgICAgIH0KICAgICAgZXh0ZW5zaW9uV3JpdGVyLndyaXRlVW50aWwoNTM2ODcwOTEyLCBvdXRwdXQpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxLCBvcHRpb25hbEludDMyTG93ZmllbGRfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50MzJMb3dmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhyZXBlYXRlZEludDMyTG93ZmllbGRfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRJbnQzMkxvd2ZpZWxkTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEludDMyTG93ZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcocGFja2VkSW50MzJMb3dmaWVsZF8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEludDMyTG93ZmllbGRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDE7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkSW50MzJMb3dmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDk5LCBvdGhlckZpZWxkXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZSgxMDAxLCBvcHRpb25hbEludDMyTWlkZmllbGRfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50MzJNaWRmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhyZXBlYXRlZEludDMyTWlkZmllbGRfLmdldEludChpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRJbnQzMk1pZGZpZWxkTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEludDMyTWlkZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcocGFja2VkSW50MzJNaWRmaWVsZF8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFBhY2tlZEludDMyTWlkZmllbGRMaXN0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgICBzaXplICs9IDI7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgICAuY29tcHV0ZUludDMyU2l6ZU5vVGFnKGRhdGFTaXplKTsKICAgICAgICB9CiAgICAgICAgcGFja2VkSW50MzJNaWRmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEwMDAwMDEsIG9wdGlvbmFsSW50MzJIaWZpZWxkXyk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZEludDMySGlmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhyZXBlYXRlZEludDMySGlmaWVsZF8uZ2V0SW50KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDQgKiBnZXRSZXBlYXRlZEludDMySGlmaWVsZExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRJbnQzMkhpZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcocGFja2VkSW50MzJIaWZpZWxkXy5nZXRJbnQoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkSW50MzJIaWZpZWxkTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSA0OwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEludDMySGlmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXIpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlciBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXIpIG9iajsKCiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyTG93ZmllbGQoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDMyTG93ZmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMkxvd2ZpZWxkKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQzMkxvd2ZpZWxkKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQzMkxvd2ZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMk1pZGZpZWxkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMk1pZGZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzJNaWRmaWVsZCgpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50MzJNaWRmaWVsZCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzJNaWRmaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzJIaWZpZWxkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQzMkhpZmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMkhpZmllbGQoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMySGlmaWVsZCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50MzJIaWZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFJlcGVhdGVkSW50MzJMb3dmaWVsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEludDMyTG93ZmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQzMk1pZGZpZWxkTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkSW50MzJNaWRmaWVsZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDMySGlmaWVsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEludDMySGlmaWVsZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRJbnQzMkxvd2ZpZWxkTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEludDMyTG93ZmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkSW50MzJNaWRmaWVsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRJbnQzMk1pZGZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEludDMySGlmaWVsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRJbnQzMkhpZmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPdGhlckZpZWxkKCkgIT0gb3RoZXIuaGFzT3RoZXJGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPdGhlckZpZWxkKCkpIHsKICAgICAgICBpZiAoZ2V0T3RoZXJGaWVsZCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE90aGVyRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RXh0ZW5zaW9uRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldEV4dGVuc2lvbkZpZWxkcygpKSkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzJMb3dmaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UMzJfTE9XRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzJMb3dmaWVsZCgpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDMyTWlkZmllbGQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lOVDMyX01JREZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbEludDMyTWlkZmllbGQoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQzMkhpZmllbGQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0lOVDMyX0hJRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzJIaWZpZWxkKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkSW50MzJMb3dmaWVsZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UMzJfTE9XRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50MzJMb3dmaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEludDMyTWlkZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0lOVDMyX01JREZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEludDMyTWlkZmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQzMkhpZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0lOVDMyX0hJRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50MzJIaWZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEludDMyTG93ZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9JTlQzMl9MT1dGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkSW50MzJMb3dmaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRJbnQzMk1pZGZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfSU5UMzJfTUlERklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEludDMyTWlkZmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkSW50MzJIaWZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfSU5UMzJfSElGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkSW50MzJIaWZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc090aGVyRmllbGQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9USEVSX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPdGhlckZpZWxkKCk7CiAgICAgIH0KICAgICAgaGFzaCA9IGhhc2hGaWVsZHMoaGFzaCwgZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlciBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuSW50MzJQYXJzZVRlc3Rlcn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlciwgQnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuSW50MzJQYXJzZVRlc3RlcikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfSW50MzJQYXJzZVRlc3Rlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbnQzMlBhcnNlVGVzdGVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3Rlci5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyTG93ZmllbGRfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyTWlkZmllbGRfID0gMDsKICAgICAgICBvcHRpb25hbEludDMySGlmaWVsZF8gPSAwOwogICAgICAgIHJlcGVhdGVkSW50MzJMb3dmaWVsZF8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICByZXBlYXRlZEludDMyTWlkZmllbGRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRJbnQzMkhpZmllbGRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgcGFja2VkSW50MzJMb3dmaWVsZF8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBwYWNrZWRJbnQzMk1pZGZpZWxkXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIHBhY2tlZEludDMySGlmaWVsZF8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBvdGhlckZpZWxkXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDMyUGFyc2VUZXN0ZXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3Rlci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlciByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXIodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzJMb3dmaWVsZF8gPSBvcHRpb25hbEludDMyTG93ZmllbGRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzJNaWRmaWVsZF8gPSBvcHRpb25hbEludDMyTWlkZmllbGRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzJIaWZpZWxkXyA9IG9wdGlvbmFsSW50MzJIaWZpZWxkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50MzJMb3dmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW50MzJMb3dmaWVsZF8gPSByZXBlYXRlZEludDMyTG93ZmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQzMk1pZGZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbnQzMk1pZGZpZWxkXyA9IHJlcGVhdGVkSW50MzJNaWRmaWVsZF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEludDMySGlmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW50MzJIaWZpZWxkXyA9IHJlcGVhdGVkSW50MzJIaWZpZWxkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEludDMyTG93ZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRJbnQzMkxvd2ZpZWxkXyA9IHBhY2tlZEludDMyTG93ZmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkSW50MzJNaWRmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZEludDMyTWlkZmllbGRfID0gcGFja2VkSW50MzJNaWRmaWVsZF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRJbnQzMkhpZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRJbnQzMkhpZmllbGRfID0gcGFja2VkSW50MzJIaWZpZWxkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vdGhlckZpZWxkXyA9IG90aGVyRmllbGRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXIsIFR5cGU+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgaW50IGluZGV4LCBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgYWRkRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXIsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VD4gQnVpbGRlciBjbGVhckV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyLCBUPiBleHRlbnNpb24pIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlcilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDMyUGFyc2VUZXN0ZXIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQzMkxvd2ZpZWxkKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzJMb3dmaWVsZChvdGhlci5nZXRPcHRpb25hbEludDMyTG93ZmllbGQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDMyTWlkZmllbGQoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQzMk1pZGZpZWxkKG90aGVyLmdldE9wdGlvbmFsSW50MzJNaWRmaWVsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50MzJIaWZpZWxkKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50MzJIaWZpZWxkKG90aGVyLmdldE9wdGlvbmFsSW50MzJIaWZpZWxkKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW50MzJMb3dmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRJbnQzMkxvd2ZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMkxvd2ZpZWxkXyA9IG90aGVyLnJlcGVhdGVkSW50MzJMb3dmaWVsZF87CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJMb3dmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMyTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMkxvd2ZpZWxkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRJbnQzMkxvd2ZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDMyTWlkZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkSW50MzJNaWRmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJNaWRmaWVsZF8gPSBvdGhlci5yZXBlYXRlZEludDMyTWlkZmllbGRfOwogICAgICAgICAgICByZXBlYXRlZEludDMyTWlkZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMk1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50MzJNaWRmaWVsZF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW50MzJNaWRmaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbnQzMkhpZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkSW50MzJIaWZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMkhpZmllbGRfID0gb3RoZXIucmVwZWF0ZWRJbnQzMkhpZmllbGRfOwogICAgICAgICAgICByZXBlYXRlZEludDMySGlmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEludDMySGlmaWVsZF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW50MzJIaWZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRJbnQzMkxvd2ZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRJbnQzMkxvd2ZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkSW50MzJMb3dmaWVsZF8gPSBvdGhlci5wYWNrZWRJbnQzMkxvd2ZpZWxkXzsKICAgICAgICAgICAgcGFja2VkSW50MzJMb3dmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMkxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEludDMyTG93ZmllbGRfLmFkZEFsbChvdGhlci5wYWNrZWRJbnQzMkxvd2ZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRJbnQzMk1pZGZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRJbnQzMk1pZGZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkSW50MzJNaWRmaWVsZF8gPSBvdGhlci5wYWNrZWRJbnQzMk1pZGZpZWxkXzsKICAgICAgICAgICAgcGFja2VkSW50MzJNaWRmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMk1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEludDMyTWlkZmllbGRfLmFkZEFsbChvdGhlci5wYWNrZWRJbnQzMk1pZGZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRJbnQzMkhpZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEludDMySGlmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEludDMySGlmaWVsZF8gPSBvdGhlci5wYWNrZWRJbnQzMkhpZmllbGRfOwogICAgICAgICAgICBwYWNrZWRJbnQzMkhpZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50MzJIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEludDMySGlmaWVsZF8uYWRkQWxsKG90aGVyLnBhY2tlZEludDMySGlmaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPdGhlckZpZWxkKCkpIHsKICAgICAgICAgIHNldE90aGVyRmllbGQob3RoZXIuZ2V0T3RoZXJGaWVsZCgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzJMb3dmaWVsZF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQzMkxvd2ZpZWxkXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyTG93ZmllbGRfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50MzJMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkSW50MzJMb3dmaWVsZF8uYWRkSW50KHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMkxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZEludDMyTG93ZmllbGRfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDc5MjogewogICAgICAgICAgICAgICAgb3RoZXJGaWVsZF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3OTIKICAgICAgICAgICAgICBjYXNlIDgwMDg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50MzJNaWRmaWVsZF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDA4CiAgICAgICAgICAgICAgY2FzZSA4MDE2OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMk1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyTWlkZmllbGRfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDE2CiAgICAgICAgICAgICAgY2FzZSA4MDE4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEludDMyTWlkZmllbGRfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAxOAogICAgICAgICAgICAgIGNhc2UgODAyNDogewogICAgICAgICAgICAgICAgaW50IHYgPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEludDMyTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZEludDMyTWlkZmllbGRfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDI0CiAgICAgICAgICAgICAgY2FzZSA4MDI2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEludDMyTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkSW50MzJNaWRmaWVsZF8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDI2CiAgICAgICAgICAgICAgY2FzZSA4MDAwMDA4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMySGlmaWVsZF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDAwMDA4CiAgICAgICAgICAgICAgY2FzZSA4MDAwMDE2OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMkhpZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50MzJIaWZpZWxkXy5hZGRJbnQodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMDAxNgogICAgICAgICAgICAgIGNhc2UgODAwMDAxODogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IGxpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMySGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICByZXBlYXRlZEludDMySGlmaWVsZF8uYWRkSW50KGlucHV0LnJlYWRJbnQzMigpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDAwMDE4CiAgICAgICAgICAgICAgY2FzZSA4MDAwMDI0OiB7CiAgICAgICAgICAgICAgICBpbnQgdiA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50MzJIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRJbnQzMkhpZmllbGRfLmFkZEludCh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDAwMDI0CiAgICAgICAgICAgICAgY2FzZSA4MDAwMDI2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEludDMySGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRJbnQzMkhpZmllbGRfLmFkZEludChpbnB1dC5yZWFkSW50MzIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMDAyNgogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyTG93ZmllbGRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyX2xvd2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMkxvd2ZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQzMkxvd2ZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMkxvd2ZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzJMb3dmaWVsZCgpIHsKICAgICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMkxvd2ZpZWxkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDMyTG93ZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbEludDMyTG93ZmllbGQoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzJMb3dmaWVsZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyX2xvd2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMkxvd2ZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvcHRpb25hbEludDMyTG93ZmllbGRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMk1pZGZpZWxkXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl9taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzJNaWRmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzJNaWRmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50MzJNaWRmaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyTWlkZmllbGQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzJNaWRmaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQzMk1pZGZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMk1pZGZpZWxkKGludCB2YWx1ZSkgewoKICAgICAgICBvcHRpb25hbEludDMyTWlkZmllbGRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl9taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzJNaWRmaWVsZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb3B0aW9uYWxJbnQzMk1pZGZpZWxkXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IG9wdGlvbmFsSW50MzJIaWZpZWxkXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvcHRpb25hbF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMkhpZmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMySGlmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG9wdGlvbmFsX2ludDMyX2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMkhpZmllbGQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0T3B0aW9uYWxJbnQzMkhpZmllbGQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzJIaWZpZWxkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50MzJIaWZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQzMkhpZmllbGQoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzJIaWZpZWxkXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3B0aW9uYWxfaW50MzJfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsSW50MzJIaWZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBvcHRpb25hbEludDMySGlmaWVsZF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCByZXBlYXRlZEludDMyTG93ZmllbGRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEludDMyTG93ZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZEludDMyTG93ZmllbGRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEludDMyTG93ZmllbGRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkSW50MzJMb3dmaWVsZF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50MzJMb3dmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkSW50MzJMb3dmaWVsZExpc3QoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMkxvd2ZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJMb3dmaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50MzJMb3dmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkxvd2ZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJMb3dmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMl9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQzMkxvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkxvd2ZpZWxkKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDMyTG93ZmllbGRfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDMyTG93ZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDMyTG93ZmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDMyTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDMyTG93ZmllbGRfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDMyTG93ZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEludDMyTG93ZmllbGQoaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50MzJMb3dmaWVsZF8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHJlcGVhdGVkSW50MzJMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW50MzJMb3dmaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZEludDMyTG93ZmllbGRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRJbnQzMkxvd2ZpZWxkKCkgewogICAgICAgIHJlcGVhdGVkSW50MzJMb3dmaWVsZF8gPSBlbXB0eUludExpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5JbnRMaXN0IHJlcGVhdGVkSW50MzJNaWRmaWVsZF8gPSBlbXB0eUludExpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW50MzJNaWRmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkSW50MzJNaWRmaWVsZF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50MzJNaWRmaWVsZF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRJbnQzMk1pZGZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQzMk1pZGZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UmVwZWF0ZWRJbnQzMk1pZGZpZWxkTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEludDMyTWlkZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMk1pZGZpZWxkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMk1pZGZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyTWlkZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQzMk1pZGZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDMyTWlkZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDMyTWlkZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJNaWRmaWVsZF8uZ2V0SW50KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50MzJNaWRmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW50MzJNaWRmaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgaW50IHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50MzJNaWRmaWVsZF8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMl9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50MzJNaWRmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW50MzJNaWRmaWVsZChpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMk1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQzMk1pZGZpZWxkXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRJbnQzMk1pZGZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRJbnQzMk1pZGZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuSW50ZWdlcj4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMk1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW50MzJNaWRmaWVsZF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEludDMyTWlkZmllbGQoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMk1pZGZpZWxkXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkludExpc3QgcmVwZWF0ZWRJbnQzMkhpZmllbGRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZEludDMySGlmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkSW50MzJIaWZpZWxkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQzMkhpZmllbGRfID0gbWFrZU11dGFibGVDb3B5KHJlcGVhdGVkSW50MzJIaWZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcmVwZWF0ZWRfaW50MzJfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDMySGlmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4KICAgICAgICAgIGdldFJlcGVhdGVkSW50MzJIaWZpZWxkTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEludDMySGlmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEludDMySGlmaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQzMkhpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50MzJIaWZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJIaWZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50MzJIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQzMkhpZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50MzJIaWZpZWxkXy5nZXRJbnQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDMySGlmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkSW50MzJIaWZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMkhpZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDMySGlmaWVsZF8uc2V0SW50KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQzMkhpZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEludDMySGlmaWVsZChpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQzMkhpZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDMySGlmaWVsZF8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHJlcGVhdGVkX2ludDMyX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRJbnQzMkhpZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEludDMySGlmaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50MzJIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW50MzJIaWZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiByZXBlYXRlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRJbnQzMkhpZmllbGQoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQzMkhpZmllbGRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRJbnQzMkxvd2ZpZWxkXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkSW50MzJMb3dmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEludDMyTG93ZmllbGRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRJbnQzMkxvd2ZpZWxkXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRJbnQzMkxvd2ZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQzMkxvd2ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UGFja2VkSW50MzJMb3dmaWVsZExpc3QoKSB7CiAgICAgICAgcGFja2VkSW50MzJMb3dmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRJbnQzMkxvd2ZpZWxkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQzMkxvd2ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQzMkxvd2ZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDMyTG93ZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkSW50MzJMb3dmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMyTG93ZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDMyTG93ZmllbGRfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDMyTG93ZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRJbnQzMkxvd2ZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50MzJMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEludDMyTG93ZmllbGRfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDMyTG93ZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRJbnQzMkxvd2ZpZWxkKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMkxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkSW50MzJMb3dmaWVsZF8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkSW50MzJMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEludDMyTG93ZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMkxvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEludDMyTG93ZmllbGRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRJbnQzMkxvd2ZpZWxkKCkgewogICAgICAgIHBhY2tlZEludDMyTG93ZmllbGRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRJbnQzMk1pZGZpZWxkXyA9IGVtcHR5SW50TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUGFja2VkSW50MzJNaWRmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEludDMyTWlkZmllbGRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRJbnQzMk1pZGZpZWxkXyA9IG1ha2VNdXRhYmxlQ29weShwYWNrZWRJbnQzMk1pZGZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQzMk1pZGZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPgogICAgICAgICAgZ2V0UGFja2VkSW50MzJNaWRmaWVsZExpc3QoKSB7CiAgICAgICAgcGFja2VkSW50MzJNaWRmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRJbnQzMk1pZGZpZWxkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQzMk1pZGZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQzMk1pZGZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDMyTWlkZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkSW50MzJNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDMyTWlkZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDMyTWlkZmllbGRfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDMyTWlkZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRQYWNrZWRJbnQzMk1pZGZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50MzJNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEludDMyTWlkZmllbGRfLnNldEludChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDMyTWlkZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRJbnQzMk1pZGZpZWxkKGludCB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMk1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkSW50MzJNaWRmaWVsZF8uYWRkSW50KHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkSW50MzJNaWRmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEludDMyTWlkZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5JbnRlZ2VyPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVQYWNrZWRJbnQzMk1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEludDMyTWlkZmllbGRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJQYWNrZWRJbnQzMk1pZGZpZWxkKCkgewogICAgICAgIHBhY2tlZEludDMyTWlkZmllbGRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuSW50TGlzdCBwYWNrZWRJbnQzMkhpZmllbGRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRJbnQzMkhpZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFwYWNrZWRJbnQzMkhpZmllbGRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICBwYWNrZWRJbnQzMkhpZmllbGRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEludDMySGlmaWVsZF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQzMkhpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+CiAgICAgICAgICBnZXRQYWNrZWRJbnQzMkhpZmllbGRMaXN0KCkgewogICAgICAgIHBhY2tlZEludDMySGlmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiBwYWNrZWRJbnQzMkhpZmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQzMiBwYWNrZWRfaW50MzJfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50MzJIaWZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQzMkhpZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkSW50MzJIaWZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcGFja2VkSW50MzJIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGFja2VkSW50MzJIaWZpZWxkKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRJbnQzMkhpZmllbGRfLmdldEludChpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGFja2VkSW50MzJIaWZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkSW50MzJIaWZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50MzJIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkSW50MzJIaWZpZWxkXy5zZXRJbnQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDMySGlmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEludDMySGlmaWVsZChpbnQgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50MzJIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkSW50MzJIaWZpZWxkXy5hZGRJbnQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50MzIgcGFja2VkX2ludDMyX2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHBhY2tlZEludDMySGlmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFBhY2tlZEludDMySGlmaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkludGVnZXI+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEludDMySGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCBwYWNrZWRJbnQzMkhpZmllbGRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDMyIHBhY2tlZF9pbnQzMl9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEludDMySGlmaWVsZCgpIHsKICAgICAgICBwYWNrZWRJbnQzMkhpZmllbGRfID0gZW1wdHlJbnRMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvdGhlckZpZWxkXyA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBbiBhcmJpdHJhcnkgZmllbGQgd2UgY2FuIGFwcGVuZCB0byB0byBicmVhayB0aGUgcnVucyBvZiByZXBlYXRlZCBmaWVsZHMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdGhlcl9maWVsZCA9IDk5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvdGhlckZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3RoZXJGaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvdGhlckZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE90aGVyRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIG90aGVyRmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBbiBhcmJpdHJhcnkgZmllbGQgd2UgY2FuIGFwcGVuZCB0byB0byBicmVhayB0aGUgcnVucyBvZiByZXBlYXRlZCBmaWVsZHMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdGhlcl9maWVsZCA9IDk5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvdGhlckZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3RoZXJGaWVsZChpbnQgdmFsdWUpIHsKCiAgICAgICAgb3RoZXJGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck90aGVyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG90aGVyRmllbGRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5JbnQzMlBhcnNlVGVzdGVyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5JbnQzMlBhcnNlVGVzdGVyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8SW50MzJQYXJzZVRlc3Rlcj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxJbnQzMlBhcnNlVGVzdGVyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgSW50MzJQYXJzZVRlc3RlciBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEludDMyUGFyc2VUZXN0ZXI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8SW50MzJQYXJzZVRlc3Rlcj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyX0VYVF9GSUVMRF9OVU1CRVIgPSAyMDAwMDAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LkludDMyUGFyc2VUZXN0ZXIgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlciwKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gb3B0aW9uYWxJbnQzMkV4dCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3Rlci5nZXREZWZhdWx0SW5zdGFuY2UoKSwKICAgICAgICAgIDAsCiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICAgIG51bGwpOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfSU5UMzJfRVhUX0ZJRUxEX05VTUJFUiA9IDIwMDAwMDE7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuSW50MzJQYXJzZVRlc3RlciB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyLAogICAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPj4gcmVwZWF0ZWRJbnQzMkV4dCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3Rlci5nZXREZWZhdWx0SW5zdGFuY2UoKSwKICAgICAgICAgIDEsCiAgICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICAgIG51bGwpOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0lOVDMyX0VYVF9GSUVMRF9OVU1CRVIgPSAyMDAwMDAyOwogICAgLyoqCiAgICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LkludDMyUGFyc2VUZXN0ZXIgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50MzJQYXJzZVRlc3RlciwKICAgICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IHBhY2tlZEludDMyRXh0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQzMlBhcnNlVGVzdGVyLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMiwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgICAgbnVsbCk7CiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIEludDY0UGFyc2VUZXN0ZXJPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuSW50NjRQYXJzZVRlc3RlcikKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxJbnQ2NFBhcnNlVGVzdGVyPiB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF9sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDY0TG93ZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50NjRMb3dmaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF9sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NExvd2ZpZWxkLgogICAgICovCiAgICBsb25nIGdldE9wdGlvbmFsSW50NjRMb3dmaWVsZCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfbWlkZmllbGQgPSAxMDAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQ2NE1pZGZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbEludDY0TWlkZmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfbWlkZmllbGQgPSAxMDAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjRNaWRmaWVsZC4KICAgICAqLwogICAgbG9uZyBnZXRPcHRpb25hbEludDY0TWlkZmllbGQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0X2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQ2NEhpZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50NjRIaWZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0X2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjRIaWZpZWxkLgogICAgICovCiAgICBsb25nIGdldE9wdGlvbmFsSW50NjRIaWZpZWxkKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0UmVwZWF0ZWRJbnQ2NExvd2ZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRJbnQ2NExvd2ZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgbG9uZyBnZXRSZXBlYXRlZEludDY0TG93ZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0X21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDY0TWlkZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZEludDY0TWlkZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0X21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDY0TWlkZmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDY0TWlkZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDY0TWlkZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkSW50NjRNaWRmaWVsZChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NEhpZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRSZXBlYXRlZEludDY0SGlmaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NEhpZmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZEludDY0SGlmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0X2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQ2NEhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFJlcGVhdGVkSW50NjRIaWZpZWxkKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQ2NExvd2ZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4gZ2V0UGFja2VkSW50NjRMb3dmaWVsZExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50NjRMb3dmaWVsZC4KICAgICAqLwogICAgaW50IGdldFBhY2tlZEludDY0TG93ZmllbGRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDY0TG93ZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBsb25nIGdldFBhY2tlZEludDY0TG93ZmllbGQoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NF9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDY0TWlkZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRQYWNrZWRJbnQ2NE1pZGZpZWxkTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQ2NE1pZGZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkSW50NjRNaWRmaWVsZENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NF9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkSW50NjRNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UGFja2VkSW50NjRNaWRmaWVsZChpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSBwYWNrZWRJbnQ2NEhpZmllbGQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPiBnZXRQYWNrZWRJbnQ2NEhpZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NF9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcGFja2VkSW50NjRIaWZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UGFja2VkSW50NjRIaWZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHBhY2tlZEludDY0SGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGxvbmcgZ2V0UGFja2VkSW50NjRIaWZpZWxkKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQW4gYXJiaXRyYXJ5IGZpZWxkIHdlIGNhbiBhcHBlbmQgdG8gdG8gYnJlYWsgdGhlIHJ1bnMgb2YgcmVwZWF0ZWQgZmllbGRzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3RoZXJfZmllbGQgPSA5OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG90aGVyRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc090aGVyRmllbGQoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3RoZXJGaWVsZC4KICAgICAqLwogICAgaW50IGdldE90aGVyRmllbGQoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuSW50NjRQYXJzZVRlc3Rlcn0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEludDY0UGFyc2VUZXN0ZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgICBJbnQ2NFBhcnNlVGVzdGVyPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuSW50NjRQYXJzZVRlc3RlcikKICAgICAgSW50NjRQYXJzZVRlc3Rlck9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgSW50NjRQYXJzZVRlc3Rlci5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBJbnQ2NFBhcnNlVGVzdGVyKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlciwgPz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgSW50NjRQYXJzZVRlc3RlcigpIHsKICAgICAgcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRJbnQ2NE1pZGZpZWxkXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcmVwZWF0ZWRJbnQ2NEhpZmllbGRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwYWNrZWRJbnQ2NExvd2ZpZWxkXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcGFja2VkSW50NjRNaWRmaWVsZF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHBhY2tlZEludDY0SGlmaWVsZF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgSW50NjRQYXJzZVRlc3RlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDY0UGFyc2VUZXN0ZXJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbnQ2NFBhcnNlVGVzdGVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDY0X0xPV0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxJbnQ2NExvd2ZpZWxkXyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF9sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEludDY0TG93ZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDY0TG93ZmllbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjRMb3dmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxJbnQ2NExvd2ZpZWxkKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQ2NExvd2ZpZWxkXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTlQ2NF9NSURGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDAxOwogICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsSW50NjRNaWRmaWVsZF8gPSAwTDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfbWlkZmllbGQgPSAxMDAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQ2NE1pZGZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQ2NE1pZGZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0X21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDY0TWlkZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjRNaWRmaWVsZCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsSW50NjRNaWRmaWVsZF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UNjRfSElGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDAwMDAxOwogICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsSW50NjRIaWZpZWxkXyA9IDBMOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF9oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50NjRIaWZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQ2NEhpZmllbGQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NEhpZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjRIaWZpZWxkKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQ2NEhpZmllbGRfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDY0X0xPV0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEludDY0TG93ZmllbGRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0X2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDY0TG93ZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZEludDY0TG93ZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50NjRMb3dmaWVsZC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDY0TG93ZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRMb3dmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDY0TG93ZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEludDY0TG93ZmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0TG93ZmllbGRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDY0X01JREZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEludDY0TWlkZmllbGRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0X21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDY0TWlkZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRSZXBlYXRlZEludDY0TWlkZmllbGRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NE1pZGZpZWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkSW50NjRNaWRmaWVsZC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDY0TWlkZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRNaWRmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDY0TWlkZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEludDY0TWlkZmllbGQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZEludDY0TWlkZmllbGRfLmdldExvbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDY0X0hJRklFTERfRklFTERfTlVNQkVSID0gMTAwMDAwMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkSW50NjRIaWZpZWxkXyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDY0SGlmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFJlcGVhdGVkSW50NjRIaWZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRIaWZpZWxkXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NEhpZmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQ2NEhpZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRIaWZpZWxkXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0X2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQ2NEhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEludDY0SGlmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRIaWZpZWxkXy5nZXRMb25nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfSU5UNjRfTE9XRklFTERfRklFTERfTlVNQkVSID0gMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZEludDY0TG93ZmllbGRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NF9sb3dmaWVsZCA9IDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDY0TG93ZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRQYWNrZWRJbnQ2NExvd2ZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDY0TG93ZmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQ2NExvd2ZpZWxkLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDY0TG93ZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDY0TG93ZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQ2NExvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UGFja2VkSW50NjRMb3dmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDY0TG93ZmllbGRfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkSW50NjRMb3dmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfSU5UNjRfTUlERklFTERfRklFTERfTlVNQkVSID0gMTAwMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHBhY2tlZEludDY0TWlkZmllbGRfID0KICAgICAgICBlbXB0eUxvbmdMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NF9taWRmaWVsZCA9IDEwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDY0TWlkZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICBnZXRQYWNrZWRJbnQ2NE1pZGZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDY0TWlkZmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQ2NE1pZGZpZWxkLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDY0TWlkZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDY0TWlkZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQ2NE1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UGFja2VkSW50NjRNaWRmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDY0TWlkZmllbGRfLmdldExvbmcoaW5kZXgpOwogICAgfQogICAgcHJpdmF0ZSBpbnQgcGFja2VkSW50NjRNaWRmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfSU5UNjRfSElGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDAwMDAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkSW50NjRIaWZpZWxkXyA9CiAgICAgICAgZW1wdHlMb25nTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDY0SGlmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgIGdldFBhY2tlZEludDY0SGlmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiBwYWNrZWRJbnQ2NEhpZmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDY0SGlmaWVsZC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRQYWNrZWRJbnQ2NEhpZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHBhY2tlZEludDY0SGlmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcGFja2VkSW50NjRIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGxvbmcgZ2V0UGFja2VkSW50NjRIaWZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcGFja2VkSW50NjRIaWZpZWxkXy5nZXRMb25nKGluZGV4KTsKICAgIH0KICAgIHByaXZhdGUgaW50IHBhY2tlZEludDY0SGlmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSAtMTsKCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPVEhFUl9GSUVMRF9GSUVMRF9OVU1CRVIgPSA5OTsKICAgIHByaXZhdGUgaW50IG90aGVyRmllbGRfID0gMDsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvdGhlckZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3RoZXJGaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogQW4gYXJiaXRyYXJ5IGZpZWxkIHdlIGNhbiBhcHBlbmQgdG8gdG8gYnJlYWsgdGhlIHJ1bnMgb2YgcmVwZWF0ZWQgZmllbGRzLgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgb3RoZXJfZmllbGQgPSA5OTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvdGhlckZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldE90aGVyRmllbGQoKSB7CiAgICAgIHJldHVybiBvdGhlckZpZWxkXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBnZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5FeHRlbmRhYmxlTWVzc2FnZTxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXI+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDEsIG9wdGlvbmFsSW50NjRMb3dmaWVsZF8pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDIsIHJlcGVhdGVkSW50NjRMb3dmaWVsZF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEludDY0TG93ZmllbGRMaXN0KCkuc2l6ZSgpID4gMCkgewogICAgICAgIG91dHB1dC53cml0ZVVJbnQzMk5vVGFnKDI2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRJbnQ2NExvd2ZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRJbnQ2NExvd2ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDY0Tm9UYWcocGFja2VkSW50NjRMb3dmaWVsZF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoOTksIG90aGVyRmllbGRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgxMDAxLCBvcHRpb25hbEludDY0TWlkZmllbGRfKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50NjRNaWRmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgxMDAyLCByZXBlYXRlZEludDY0TWlkZmllbGRfLmdldExvbmcoaSkpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRJbnQ2NE1pZGZpZWxkTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MDI2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRJbnQ2NE1pZGZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRJbnQ2NE1pZGZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDY0Tm9UYWcocGFja2VkSW50NjRNaWRmaWVsZF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50NjQoMTAwMDAwMSwgb3B0aW9uYWxJbnQ2NEhpZmllbGRfKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50NjRIaWZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZUludDY0KDEwMDAwMDIsIHJlcGVhdGVkSW50NjRIaWZpZWxkXy5nZXRMb25nKGkpKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkSW50NjRIaWZpZWxkTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyg4MDAwMDI2KTsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZyhwYWNrZWRJbnQ2NEhpZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEludDY0SGlmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NE5vVGFnKHBhY2tlZEludDY0SGlmaWVsZF8uZ2V0TG9uZyhpKSk7CiAgICAgIH0KICAgICAgZXh0ZW5zaW9uV3JpdGVyLndyaXRlVW50aWwoNTM2ODcwOTEyLCBvdXRwdXQpOwogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSgxLCBvcHRpb25hbEludDY0TG93ZmllbGRfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkSW50NjRMb3dmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemVOb1RhZyhyZXBlYXRlZEludDY0TG93ZmllbGRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkSW50NjRMb3dmaWVsZExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYWNrZWRJbnQ2NExvd2ZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZU5vVGFnKHBhY2tlZEludDY0TG93ZmllbGRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkSW50NjRMb3dmaWVsZExpc3QoKS5pc0VtcHR5KCkpIHsKICAgICAgICAgIHNpemUgKz0gMTsKICAgICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH0KICAgICAgICBwYWNrZWRJbnQ2NExvd2ZpZWxkTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoOTksIG90aGVyRmllbGRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplKDEwMDEsIG9wdGlvbmFsSW50NjRNaWRmaWVsZF8pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQ2NE1pZGZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZU5vVGFnKHJlcGVhdGVkSW50NjRNaWRmaWVsZF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRJbnQ2NE1pZGZpZWxkTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEludDY0TWlkZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplTm9UYWcocGFja2VkSW50NjRNaWRmaWVsZF8uZ2V0TG9uZyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgaWYgKCFnZXRQYWNrZWRJbnQ2NE1pZGZpZWxkTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSAyOwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEludDY0TWlkZmllbGRNZW1vaXplZFNlcmlhbGl6ZWRTaXplID0gZGF0YVNpemU7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUludDY0U2l6ZSgxMDAwMDAxLCBvcHRpb25hbEludDY0SGlmaWVsZF8pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRJbnQ2NEhpZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplTm9UYWcocmVwZWF0ZWRJbnQ2NEhpZmllbGRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gNCAqIGdldFJlcGVhdGVkSW50NjRIaWZpZWxkTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBhY2tlZEludDY0SGlmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVJbnQ2NFNpemVOb1RhZyhwYWNrZWRJbnQ2NEhpZmllbGRfLmdldExvbmcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIGlmICghZ2V0UGFja2VkSW50NjRIaWZpZWxkTGlzdCgpLmlzRW1wdHkoKSkgewogICAgICAgICAgc2l6ZSArPSA0OwogICAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemVOb1RhZyhkYXRhU2l6ZSk7CiAgICAgICAgfQogICAgICAgIHBhY2tlZEludDY0SGlmaWVsZE1lbW9pemVkU2VyaWFsaXplZFNpemUgPSBkYXRhU2l6ZTsKICAgICAgfQogICAgICBzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXIpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlciBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXIpIG9iajsKCiAgICAgIGlmIChoYXNPcHRpb25hbEludDY0TG93ZmllbGQoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDY0TG93ZmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQ2NExvd2ZpZWxkKCkpIHsKICAgICAgICBpZiAoZ2V0T3B0aW9uYWxJbnQ2NExvd2ZpZWxkKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQ2NExvd2ZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQ2NE1pZGZpZWxkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQ2NE1pZGZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50NjRNaWRmaWVsZCgpKSB7CiAgICAgICAgaWYgKGdldE9wdGlvbmFsSW50NjRNaWRmaWVsZCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50NjRNaWRmaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsSW50NjRIaWZpZWxkKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxJbnQ2NEhpZmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQ2NEhpZmllbGQoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDY0SGlmaWVsZCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE9wdGlvbmFsSW50NjRIaWZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFJlcGVhdGVkSW50NjRMb3dmaWVsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEludDY0TG93ZmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRJbnQ2NE1pZGZpZWxkTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkSW50NjRNaWRmaWVsZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZEludDY0SGlmaWVsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZEludDY0SGlmaWVsZExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRQYWNrZWRJbnQ2NExvd2ZpZWxkTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFBhY2tlZEludDY0TG93ZmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UGFja2VkSW50NjRNaWRmaWVsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRJbnQ2NE1pZGZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFBhY2tlZEludDY0SGlmaWVsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRQYWNrZWRJbnQ2NEhpZmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPdGhlckZpZWxkKCkgIT0gb3RoZXIuaGFzT3RoZXJGaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPdGhlckZpZWxkKCkpIHsKICAgICAgICBpZiAoZ2V0T3RoZXJGaWVsZCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldE90aGVyRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RXh0ZW5zaW9uRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldEV4dGVuc2lvbkZpZWxkcygpKSkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50NjRMb3dmaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UNjRfTE9XRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuaGFzaExvbmcoCiAgICAgICAgICAgIGdldE9wdGlvbmFsSW50NjRMb3dmaWVsZCgpKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxJbnQ2NE1pZGZpZWxkKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9JTlQ2NF9NSURGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0T3B0aW9uYWxJbnQ2NE1pZGZpZWxkKCkpOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEludDY0SGlmaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfSU5UNjRfSElGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5oYXNoTG9uZygKICAgICAgICAgICAgZ2V0T3B0aW9uYWxJbnQ2NEhpZmllbGQoKSk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkSW50NjRMb3dmaWVsZENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfSU5UNjRfTE9XRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50NjRMb3dmaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZEludDY0TWlkZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0lOVDY0X01JREZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZEludDY0TWlkZmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRJbnQ2NEhpZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX0lOVDY0X0hJRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkSW50NjRIaWZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFBhY2tlZEludDY0TG93ZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBBQ0tFRF9JTlQ2NF9MT1dGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkSW50NjRMb3dmaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRQYWNrZWRJbnQ2NE1pZGZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfSU5UNjRfTUlERklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFBhY2tlZEludDY0TWlkZmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UGFja2VkSW50NjRIaWZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBQQUNLRURfSU5UNjRfSElGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UGFja2VkSW50NjRIaWZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc090aGVyRmllbGQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9USEVSX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPdGhlckZpZWxkKCk7CiAgICAgIH0KICAgICAgaGFzaCA9IGhhc2hGaWVsZHMoaGFzaCwgZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlciBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXIgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXIgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXIgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuSW50NjRQYXJzZVRlc3Rlcn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlciwgQnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuSW50NjRQYXJzZVRlc3RlcikKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXJPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfSW50NjRQYXJzZVRlc3Rlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbnQ2NFBhcnNlVGVzdGVyX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3Rlci5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbEludDY0TG93ZmllbGRfID0gMEw7CiAgICAgICAgb3B0aW9uYWxJbnQ2NE1pZGZpZWxkXyA9IDBMOwogICAgICAgIG9wdGlvbmFsSW50NjRIaWZpZWxkXyA9IDBMOwogICAgICAgIHJlcGVhdGVkSW50NjRMb3dmaWVsZF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NE1pZGZpZWxkXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICByZXBlYXRlZEludDY0SGlmaWVsZF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcGFja2VkSW50NjRMb3dmaWVsZF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcGFja2VkSW50NjRNaWRmaWVsZF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgcGFja2VkSW50NjRIaWZpZWxkXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBvdGhlckZpZWxkXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDY0UGFyc2VUZXN0ZXJfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3Rlci5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlciByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlciBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXIodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50NjRMb3dmaWVsZF8gPSBvcHRpb25hbEludDY0TG93ZmllbGRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50NjRNaWRmaWVsZF8gPSBvcHRpb25hbEludDY0TWlkZmllbGRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50NjRIaWZpZWxkXyA9IG9wdGlvbmFsSW50NjRIaWZpZWxkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50NjRMb3dmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW50NjRMb3dmaWVsZF8gPSByZXBlYXRlZEludDY0TG93ZmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQ2NE1pZGZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRJbnQ2NE1pZGZpZWxkXyA9IHJlcGVhdGVkSW50NjRNaWRmaWVsZF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZEludDY0SGlmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkSW50NjRIaWZpZWxkXyA9IHJlcGVhdGVkSW50NjRIaWZpZWxkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHBhY2tlZEludDY0TG93ZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRJbnQ2NExvd2ZpZWxkXyA9IHBhY2tlZEludDY0TG93ZmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcGFja2VkSW50NjRNaWRmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnBhY2tlZEludDY0TWlkZmllbGRfID0gcGFja2VkSW50NjRNaWRmaWVsZF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICBwYWNrZWRJbnQ2NEhpZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5wYWNrZWRJbnQ2NEhpZmllbGRfID0gcGFja2VkSW50NjRIaWZpZWxkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vdGhlckZpZWxkXyA9IG90aGVyRmllbGRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXIsIFR5cGU+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgaW50IGluZGV4LCBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEV4dGVuc2lvbihleHRlbnNpb24sIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgYWRkRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXIsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VD4gQnVpbGRlciBjbGVhckV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyLCBUPiBleHRlbnNpb24pIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXIpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlcilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkludDY0UGFyc2VUZXN0ZXIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQ2NExvd2ZpZWxkKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50NjRMb3dmaWVsZChvdGhlci5nZXRPcHRpb25hbEludDY0TG93ZmllbGQoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEludDY0TWlkZmllbGQoKSkgewogICAgICAgICAgc2V0T3B0aW9uYWxJbnQ2NE1pZGZpZWxkKG90aGVyLmdldE9wdGlvbmFsSW50NjRNaWRmaWVsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsSW50NjRIaWZpZWxkKCkpIHsKICAgICAgICAgIHNldE9wdGlvbmFsSW50NjRIaWZpZWxkKG90aGVyLmdldE9wdGlvbmFsSW50NjRIaWZpZWxkKCkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkSW50NjRMb3dmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRJbnQ2NExvd2ZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkXyA9IG90aGVyLnJlcGVhdGVkSW50NjRMb3dmaWVsZF87CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRMb3dmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0TG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRJbnQ2NExvd2ZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZEludDY0TWlkZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkSW50NjRNaWRmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRNaWRmaWVsZF8gPSBvdGhlci5yZXBlYXRlZEludDY0TWlkZmllbGRfOwogICAgICAgICAgICByZXBlYXRlZEludDY0TWlkZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NE1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkSW50NjRNaWRmaWVsZF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW50NjRNaWRmaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRJbnQ2NEhpZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkSW50NjRIaWZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NEhpZmllbGRfID0gb3RoZXIucmVwZWF0ZWRJbnQ2NEhpZmllbGRfOwogICAgICAgICAgICByZXBlYXRlZEludDY0SGlmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZEludDY0SGlmaWVsZF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkSW50NjRIaWZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRJbnQ2NExvd2ZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRJbnQ2NExvd2ZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkSW50NjRMb3dmaWVsZF8gPSBvdGhlci5wYWNrZWRJbnQ2NExvd2ZpZWxkXzsKICAgICAgICAgICAgcGFja2VkSW50NjRMb3dmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NExvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEludDY0TG93ZmllbGRfLmFkZEFsbChvdGhlci5wYWNrZWRJbnQ2NExvd2ZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRJbnQ2NE1pZGZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChwYWNrZWRJbnQ2NE1pZGZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcGFja2VkSW50NjRNaWRmaWVsZF8gPSBvdGhlci5wYWNrZWRJbnQ2NE1pZGZpZWxkXzsKICAgICAgICAgICAgcGFja2VkSW50NjRNaWRmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NE1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEludDY0TWlkZmllbGRfLmFkZEFsbChvdGhlci5wYWNrZWRJbnQ2NE1pZGZpZWxkXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5wYWNrZWRJbnQ2NEhpZmllbGRfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHBhY2tlZEludDY0SGlmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHBhY2tlZEludDY0SGlmaWVsZF8gPSBvdGhlci5wYWNrZWRJbnQ2NEhpZmllbGRfOwogICAgICAgICAgICBwYWNrZWRJbnQ2NEhpZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50NjRIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHBhY2tlZEludDY0SGlmaWVsZF8uYWRkQWxsKG90aGVyLnBhY2tlZEludDY0SGlmaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPdGhlckZpZWxkKCkpIHsKICAgICAgICAgIHNldE90aGVyRmllbGQob3RoZXIuZ2V0T3RoZXJGaWVsZCgpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZUV4dGVuc2lvbkZpZWxkcyhvdGhlcik7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50NjRMb3dmaWVsZF8gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0TG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50NjRMb3dmaWVsZF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NExvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50NjRMb3dmaWVsZF8uYWRkTG9uZyhpbnB1dC5yZWFkSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI0OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEludDY0TG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHBhY2tlZEludDY0TG93ZmllbGRfLmFkZExvbmcodik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEludDY0TG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgcGFja2VkSW50NjRMb3dmaWVsZF8uYWRkTG9uZyhpbnB1dC5yZWFkSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjYKICAgICAgICAgICAgICBjYXNlIDc5MjogewogICAgICAgICAgICAgICAgb3RoZXJGaWVsZF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3OTIKICAgICAgICAgICAgICBjYXNlIDgwMDg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsSW50NjRNaWRmaWVsZF8gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDA4CiAgICAgICAgICAgICAgY2FzZSA4MDE2OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRJbnQ2NE1pZGZpZWxkXy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMTYKICAgICAgICAgICAgICBjYXNlIDgwMTg6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NE1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50NjRNaWRmaWVsZF8uYWRkTG9uZyhpbnB1dC5yZWFkSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAxOAogICAgICAgICAgICAgIGNhc2UgODAyNDogewogICAgICAgICAgICAgICAgbG9uZyB2ID0gaW5wdXQucmVhZEludDY0KCk7CiAgICAgICAgICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NE1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICBwYWNrZWRJbnQ2NE1pZGZpZWxkXy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMjQKICAgICAgICAgICAgICBjYXNlIDgwMjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50NjRNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgd2hpbGUgKGlucHV0LmdldEJ5dGVzVW50aWxMaW1pdCgpID4gMCkgewogICAgICAgICAgICAgICAgICBwYWNrZWRJbnQ2NE1pZGZpZWxkXy5hZGRMb25nKGlucHV0LnJlYWRJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDI2CiAgICAgICAgICAgICAgY2FzZSA4MDAwMDA4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDY0SGlmaWVsZF8gPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDAwMDA4CiAgICAgICAgICAgICAgY2FzZSA4MDAwMDE2OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZEludDY0SGlmaWVsZF8uYWRkTG9uZyh2KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDAwMDE2CiAgICAgICAgICAgICAgY2FzZSA4MDAwMDE4OiB7CiAgICAgICAgICAgICAgICBpbnQgbGVuZ3RoID0gaW5wdXQucmVhZFJhd1ZhcmludDMyKCk7CiAgICAgICAgICAgICAgICBpbnQgbGltaXQgPSBpbnB1dC5wdXNoTGltaXQobGVuZ3RoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkSW50NjRIaWZpZWxkXy5hZGRMb25nKGlucHV0LnJlYWRJbnQ2NCgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlucHV0LnBvcExpbWl0KGxpbWl0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDAwMDE4CiAgICAgICAgICAgICAgY2FzZSA4MDAwMDI0OiB7CiAgICAgICAgICAgICAgICBsb25nIHYgPSBpbnB1dC5yZWFkSW50NjQoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVBhY2tlZEludDY0SGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcGFja2VkSW50NjRIaWZpZWxkXy5hZGRMb25nKHYpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAwMjQKICAgICAgICAgICAgICBjYXNlIDgwMDAwMjY6IHsKICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSBpbnB1dC5yZWFkUmF3VmFyaW50MzIoKTsKICAgICAgICAgICAgICAgIGludCBsaW1pdCA9IGlucHV0LnB1c2hMaW1pdChsZW5ndGgpOwogICAgICAgICAgICAgICAgZW5zdXJlUGFja2VkSW50NjRIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICB3aGlsZSAoaW5wdXQuZ2V0Qnl0ZXNVbnRpbExpbWl0KCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgIHBhY2tlZEludDY0SGlmaWVsZF8uYWRkTG9uZyhpbnB1dC5yZWFkSW50NjQoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpbnB1dC5wb3BMaW1pdChsaW1pdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAwMDAyNgogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGxvbmcgb3B0aW9uYWxJbnQ2NExvd2ZpZWxkXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF9sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50NjRMb3dmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50NjRMb3dmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0X2xvd2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsSW50NjRMb3dmaWVsZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGxvbmcgZ2V0T3B0aW9uYWxJbnQ2NExvd2ZpZWxkKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDY0TG93ZmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF9sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsSW50NjRMb3dmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50NjRMb3dmaWVsZChsb25nIHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50NjRMb3dmaWVsZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0X2xvd2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQ2NExvd2ZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvcHRpb25hbEludDY0TG93ZmllbGRfID0gMEw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgbG9uZyBvcHRpb25hbEludDY0TWlkZmllbGRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0X21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQ2NE1pZGZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxJbnQ2NE1pZGZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfbWlkZmllbGQgPSAxMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NE1pZGZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgbG9uZyBnZXRPcHRpb25hbEludDY0TWlkZmllbGQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50NjRNaWRmaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0X21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQ2NE1pZGZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxJbnQ2NE1pZGZpZWxkKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQ2NE1pZGZpZWxkXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50NjQgb3B0aW9uYWxfaW50NjRfbWlkZmllbGQgPSAxMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEludDY0TWlkZmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9wdGlvbmFsSW50NjRNaWRmaWVsZF8gPSAwTDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBsb25nIG9wdGlvbmFsSW50NjRIaWZpZWxkXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF9oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQ2NEhpZmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDY0SGlmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0X2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQ2NEhpZmllbGQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBsb25nIGdldE9wdGlvbmFsSW50NjRIaWZpZWxkKCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEludDY0SGlmaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDY0IG9wdGlvbmFsX2ludDY0X2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbEludDY0SGlmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50NjRIaWZpZWxkKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgb3B0aW9uYWxJbnQ2NEhpZmllbGRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQ2NCBvcHRpb25hbF9pbnQ2NF9oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQ2NEhpZmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9wdGlvbmFsSW50NjRIaWZpZWxkXyA9IDBMOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW50NjRMb3dmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkSW50NjRMb3dmaWVsZF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHJlcGVhdGVkSW50NjRMb3dmaWVsZF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRJbnQ2NExvd2ZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRJbnQ2NExvd2ZpZWxkTGlzdCgpIHsKICAgICAgICByZXBlYXRlZEludDY0TG93ZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZEludDY0TG93ZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0X2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZEludDY0TG93ZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRJbnQ2NExvd2ZpZWxkKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDY0TG93ZmllbGRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRJbnQ2NExvd2ZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50NjRMb3dmaWVsZF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDY0TG93ZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEludDY0TG93ZmllbGQobG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0TG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZEludDY0TG93ZmllbGRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRJbnQ2NExvd2ZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NExvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkSW50NjRMb3dmaWVsZF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEludDY0TG93ZmllbGQoKSB7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NExvd2ZpZWxkXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5Mb25nTGlzdCByZXBlYXRlZEludDY0TWlkZmllbGRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRJbnQ2NE1pZGZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRJbnQ2NE1pZGZpZWxkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRJbnQ2NE1pZGZpZWxkXyA9IG1ha2VNdXRhYmxlQ29weShyZXBlYXRlZEludDY0TWlkZmllbGRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZEludDY0TWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRSZXBlYXRlZEludDY0TWlkZmllbGRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkSW50NjRNaWRmaWVsZF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZEludDY0TWlkZmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDY0TWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkSW50NjRNaWRmaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZEludDY0TWlkZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkSW50NjRNaWRmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgbG9uZyBnZXRSZXBlYXRlZEludDY0TWlkZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRNaWRmaWVsZF8uZ2V0TG9uZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0X21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZEludDY0TWlkZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDY0TWlkZmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NE1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NE1pZGZpZWxkXy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkSW50NjRNaWRmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkSW50NjRNaWRmaWVsZChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50NjRNaWRmaWVsZF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEludDY0TWlkZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZEludDY0TWlkZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIGphdmEubGFuZy5Mb25nPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0TWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRJbnQ2NE1pZGZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkSW50NjRNaWRmaWVsZCgpIHsKICAgICAgICByZXBlYXRlZEludDY0TWlkZmllbGRfID0gZW1wdHlMb25nTGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxvbmdMaXN0IHJlcGVhdGVkSW50NjRIaWZpZWxkXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkSW50NjRIaWZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRJbnQ2NEhpZmllbGRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZEludDY0SGlmaWVsZF8gPSBtYWtlTXV0YWJsZUNvcHkocmVwZWF0ZWRJbnQ2NEhpZmllbGRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkSW50NjRIaWZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPgogICAgICAgICAgZ2V0UmVwZWF0ZWRJbnQ2NEhpZmllbGRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkSW50NjRIaWZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRIaWZpZWxkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZEludDY0SGlmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRJbnQ2NEhpZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRJbnQ2NEhpZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRJbnQ2NEhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UmVwZWF0ZWRJbnQ2NEhpZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkSW50NjRIaWZpZWxkXy5nZXRMb25nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIHNldCB0aGUgdmFsdWUgYXQuCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQ2NEhpZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEludDY0SGlmaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVSZXBlYXRlZEludDY0SGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkSW50NjRIaWZpZWxkXy5zZXRMb25nKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCByZXBlYXRlZF9pbnQ2NF9oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRJbnQ2NEhpZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEludDY0SGlmaWVsZChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVJlcGVhdGVkSW50NjRIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRJbnQ2NEhpZmllbGRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcmVwZWF0ZWRfaW50NjRfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZEludDY0SGlmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkSW50NjRIaWZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRJbnQ2NEhpZmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcmVwZWF0ZWRJbnQ2NEhpZmllbGRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHJlcGVhdGVkX2ludDY0X2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZEludDY0SGlmaWVsZCgpIHsKICAgICAgICByZXBlYXRlZEludDY0SGlmaWVsZF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMjApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkSW50NjRMb3dmaWVsZF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRJbnQ2NExvd2ZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkSW50NjRMb3dmaWVsZF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEludDY0TG93ZmllbGRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEludDY0TG93ZmllbGRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDY0TG93ZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRQYWNrZWRJbnQ2NExvd2ZpZWxkTGlzdCgpIHsKICAgICAgICBwYWNrZWRJbnQ2NExvd2ZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDY0TG93ZmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDY0TG93ZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDY0TG93ZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkSW50NjRMb3dmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQ2NExvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZEludDY0TG93ZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDY0TG93ZmllbGRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfbG93ZmllbGQgPSAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRJbnQ2NExvd2ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkSW50NjRMb3dmaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NExvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkSW50NjRMb3dmaWVsZF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDY0TG93ZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRJbnQ2NExvd2ZpZWxkKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50NjRMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEludDY0TG93ZmllbGRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRJbnQ2NExvd2ZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkSW50NjRMb3dmaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEludDY0TG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkSW50NjRMb3dmaWVsZF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X2xvd2ZpZWxkID0gMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEludDY0TG93ZmllbGQoKSB7CiAgICAgICAgcGFja2VkSW50NjRMb3dmaWVsZF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkSW50NjRNaWRmaWVsZF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVQYWNrZWRJbnQ2NE1pZGZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcGFja2VkSW50NjRNaWRmaWVsZF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEludDY0TWlkZmllbGRfID0gbWFrZU11dGFibGVDb3B5KHBhY2tlZEludDY0TWlkZmllbGRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDY0TWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+CiAgICAgICAgICBnZXRQYWNrZWRJbnQ2NE1pZGZpZWxkTGlzdCgpIHsKICAgICAgICBwYWNrZWRJbnQ2NE1pZGZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDY0TWlkZmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHBhY2tlZEludDY0TWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDY0TWlkZmllbGRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcGFja2VkSW50NjRNaWRmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQ2NE1pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBsb25nIGdldFBhY2tlZEludDY0TWlkZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDY0TWlkZmllbGRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfbWlkZmllbGQgPSAxMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBwYWNrZWRJbnQ2NE1pZGZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UGFja2VkSW50NjRNaWRmaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NE1pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcGFja2VkSW50NjRNaWRmaWVsZF8uc2V0TG9uZyhpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDY0TWlkZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRQYWNrZWRJbnQ2NE1pZGZpZWxkKGxvbmcgdmFsdWUpIHsKCiAgICAgICAgZW5zdXJlUGFja2VkSW50NjRNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEludDY0TWlkZmllbGRfLmFkZExvbmcodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSBwYWNrZWRJbnQ2NE1pZGZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkSW50NjRNaWRmaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5JdGVyYWJsZTw/IGV4dGVuZHMgamF2YS5sYW5nLkxvbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVBhY2tlZEludDY0TWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgIHZhbHVlcywgcGFja2VkSW50NjRNaWRmaWVsZF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X21pZGZpZWxkID0gMTAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBhY2tlZEludDY0TWlkZmllbGQoKSB7CiAgICAgICAgcGFja2VkSW50NjRNaWRmaWVsZF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuTG9uZ0xpc3QgcGFja2VkSW50NjRIaWZpZWxkXyA9IGVtcHR5TG9uZ0xpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVBhY2tlZEludDY0SGlmaWVsZElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXBhY2tlZEludDY0SGlmaWVsZF8uaXNNb2RpZmlhYmxlKCkpIHsKICAgICAgICAgIHBhY2tlZEludDY0SGlmaWVsZF8gPSBtYWtlTXV0YWJsZUNvcHkocGFja2VkSW50NjRIaWZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHBhY2tlZEludDY0SGlmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4KICAgICAgICAgIGdldFBhY2tlZEludDY0SGlmaWVsZExpc3QoKSB7CiAgICAgICAgcGFja2VkSW50NjRIaWZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgcmV0dXJuIHBhY2tlZEludDY0SGlmaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NF9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiBwYWNrZWRJbnQ2NEhpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFBhY2tlZEludDY0SGlmaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiBwYWNrZWRJbnQ2NEhpZmllbGRfLnNpemUoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBwYWNrZWRJbnQ2NEhpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0UGFja2VkSW50NjRIaWZpZWxkKGludCBpbmRleCkgewogICAgICAgIHJldHVybiBwYWNrZWRJbnQ2NEhpZmllbGRfLmdldExvbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDY0SGlmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBhY2tlZEludDY0SGlmaWVsZCgKICAgICAgICAgIGludCBpbmRleCwgbG9uZyB2YWx1ZSkgewoKICAgICAgICBlbnN1cmVQYWNrZWRJbnQ2NEhpZmllbGRJc011dGFibGUoKTsKICAgICAgICBwYWNrZWRJbnQ2NEhpZmllbGRfLnNldExvbmcoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIGludDY0IHBhY2tlZF9pbnQ2NF9oaWZpZWxkID0gMTAwMDAwMyBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhY2tlZEludDY0SGlmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFBhY2tlZEludDY0SGlmaWVsZChsb25nIHZhbHVlKSB7CgogICAgICAgIGVuc3VyZVBhY2tlZEludDY0SGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHBhY2tlZEludDY0SGlmaWVsZF8uYWRkTG9uZyh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBpbnQ2NCBwYWNrZWRfaW50NjRfaGlmaWVsZCA9IDEwMDAwMDMgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcGFja2VkSW50NjRIaWZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUGFja2VkSW50NjRIaWZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBqYXZhLmxhbmcuTG9uZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUGFja2VkSW50NjRIaWZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHBhY2tlZEludDY0SGlmaWVsZF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgaW50NjQgcGFja2VkX2ludDY0X2hpZmllbGQgPSAxMDAwMDAzIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUGFja2VkSW50NjRIaWZpZWxkKCkgewogICAgICAgIHBhY2tlZEludDY0SGlmaWVsZF8gPSBlbXB0eUxvbmdMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBvdGhlckZpZWxkXyA7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBbiBhcmJpdHJhcnkgZmllbGQgd2UgY2FuIGFwcGVuZCB0byB0byBicmVhayB0aGUgcnVucyBvZiByZXBlYXRlZCBmaWVsZHMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdGhlcl9maWVsZCA9IDk5OzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvdGhlckZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3RoZXJGaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvdGhlckZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE90aGVyRmllbGQoKSB7CiAgICAgICAgcmV0dXJuIG90aGVyRmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBBbiBhcmJpdHJhcnkgZmllbGQgd2UgY2FuIGFwcGVuZCB0byB0byBicmVhayB0aGUgcnVucyBvZiByZXBlYXRlZCBmaWVsZHMuCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBvdGhlcl9maWVsZCA9IDk5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvdGhlckZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3RoZXJGaWVsZChpbnQgdmFsdWUpIHsKCiAgICAgICAgb3RoZXJGaWVsZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIEFuIGFyYml0cmFyeSBmaWVsZCB3ZSBjYW4gYXBwZW5kIHRvIHRvIGJyZWFrIHRoZSBydW5zIG9mIHJlcGVhdGVkIGZpZWxkcy4KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIG90aGVyX2ZpZWxkID0gOTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck90aGVyRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIG90aGVyRmllbGRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5JbnQ2NFBhcnNlVGVzdGVyKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5JbnQ2NFBhcnNlVGVzdGVyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlcigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8SW50NjRQYXJzZVRlc3Rlcj4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxJbnQ2NFBhcnNlVGVzdGVyPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgSW50NjRQYXJzZVRlc3RlciBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEludDY0UGFyc2VUZXN0ZXI+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8SW50NjRQYXJzZVRlc3Rlcj4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDY0X0VYVF9GSUVMRF9OVU1CRVIgPSAyMDAwMDAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LkludDY0UGFyc2VUZXN0ZXIgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlciwKICAgICAgICBqYXZhLmxhbmcuTG9uZz4gb3B0aW9uYWxJbnQ2NEV4dCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3Rlci5nZXREZWZhdWx0SW5zdGFuY2UoKSwKICAgICAgICAgIDAsCiAgICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICAgIG51bGwpOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfSU5UNjRfRVhUX0ZJRUxEX05VTUJFUiA9IDIwMDAwMDE7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuSW50NjRQYXJzZVRlc3RlciB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyLAogICAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gcmVwZWF0ZWRJbnQ2NEV4dCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3Rlci5nZXREZWZhdWx0SW5zdGFuY2UoKSwKICAgICAgICAgIDEsCiAgICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICAgIG51bGwpOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0lOVDY0X0VYVF9GSUVMRF9OVU1CRVIgPSAyMDAwMDAyOwogICAgLyoqCiAgICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LkludDY0UGFyc2VUZXN0ZXIgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW50NjRQYXJzZVRlc3RlciwKICAgICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4+IHBhY2tlZEludDY0RXh0ID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAgIC5uZXdNZXNzYWdlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbnQ2NFBhcnNlVGVzdGVyLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgMiwKICAgICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgICAgbnVsbCk7CiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIElubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG9PckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90bykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBXZSBtaXggZGF0YSB0byBtYWtlIHN1cmUgYXV4IGlkcyBhbmQgaW5saW5lZCBzdHJpbmcgaWR4IGRvIG5vdCBtYXRjaC4KICAgICAqIGF1eF9pZHggPT0gaW5saW5lZF9zdHJpbmdfaWR4ID09IDEKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cjEoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIFdlIG1peCBkYXRhIHRvIG1ha2Ugc3VyZSBhdXggaWRzIGFuZCBpbmxpbmVkIHN0cmluZyBpZHggZG8gbm90IG1hdGNoLgogICAgICogYXV4X2lkeCA9PSBpbmxpbmVkX3N0cmluZ19pZHggPT0gMQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjEuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMSgpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogV2UgbWl4IGRhdGEgdG8gbWFrZSBzdXJlIGF1eCBpZHMgYW5kIGlubGluZWQgc3RyaW5nIGlkeCBkbyBub3QgbWF0Y2guCiAgICAgKiBhdXhfaWR4ID09IGlubGluZWRfc3RyaW5nX2lkeCA9PSAxCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIHN0cjEuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjFCeXRlcygpOwoKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGF1eF9pZHggPT0gMgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gc3ViID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN1YiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3ViKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBhdXhfaWR4ID09IDIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIHN1YiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3ViLgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gZ2V0U3ViKCk7CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBhdXhfaWR4ID09IDIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIHN1YiA9IDI7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG9PckJ1aWxkZXIgZ2V0U3ViT3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogYXV4X2lkeCA9PSAzLCBpbmxpbmVkX3N0cmluZ19pZHggPT0gMgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzU3RyMigpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogYXV4X2lkeCA9PSAzLCBpbmxpbmVkX3N0cmluZ19pZHggPT0gMgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjIuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMigpOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogYXV4X2lkeCA9PSAzLCBpbmxpbmVkX3N0cmluZ19pZHggPT0gMgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIyLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRTdHIyQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBhdXhfaWR4ID09IDQsIGlubGluZWRfc3RyaW5nX2lkeCA9PSAzCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBzdHIzID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjMgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1N0cjMoKTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGF1eF9pZHggPT0gNCwgaW5saW5lZF9zdHJpbmdfaWR4ID09IDMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIHN0cjMgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjMuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRTdHIzKCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG99CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBJbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8pCiAgICAgIElubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG9PckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIElubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8ubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byhjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIElubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8oKSB7CiAgICAgIHN0cjFfID0gIiI7CiAgICAgIHN0cjJfID0gIiI7CiAgICAgIHN0cjNfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IElubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90b19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90by5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFIxX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBzdHIxXyA9ICIiOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogV2UgbWl4IGRhdGEgdG8gbWFrZSBzdXJlIGF1eCBpZHMgYW5kIGlubGluZWQgc3RyaW5nIGlkeCBkbyBub3QgbWF0Y2guCiAgICAgKiBhdXhfaWR4ID09IGlubGluZWRfc3RyaW5nX2lkeCA9PSAxCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdHIxIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogV2UgbWl4IGRhdGEgdG8gbWFrZSBzdXJlIGF1eCBpZHMgYW5kIGlubGluZWQgc3RyaW5nIGlkeCBkbyBub3QgbWF0Y2guCiAgICAgKiBhdXhfaWR4ID09IGlubGluZWRfc3RyaW5nX2lkeCA9PSAxCiAgICAgKiA8L3ByZT4KICAgICAqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc3RyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMSgpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBzdHIxXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBXZSBtaXggZGF0YSB0byBtYWtlIHN1cmUgYXV4IGlkcyBhbmQgaW5saW5lZCBzdHJpbmcgaWR4IGRvIG5vdCBtYXRjaC4KICAgICAqIGF1eF9pZHggPT0gaW5saW5lZF9zdHJpbmdfaWR4ID09IDEKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjFCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIxXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyMV8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVUJfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIHN1Yl87CiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBhdXhfaWR4ID09IDIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIHN1YiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzdWIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdWIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGF1eF9pZHggPT0gMgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gc3ViID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdWIuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gZ2V0U3ViKCkgewogICAgICByZXR1cm4gc3ViXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViXzsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGF1eF9pZHggPT0gMgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gc3ViID0gMjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG9PckJ1aWxkZXIgZ2V0U3ViT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gc3ViXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFIyX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBzdHIyXyA9ICIiOwogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogYXV4X2lkeCA9PSAzLCBpbmxpbmVkX3N0cmluZ19pZHggPT0gMgogICAgICogPC9wcmU+CiAgICAgKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIgPSAzOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cjIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGF1eF9pZHggPT0gMywgaW5saW5lZF9zdHJpbmdfaWR4ID09IDIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzdHIyLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdHIyKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjJfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIHN0cjJfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGF1eF9pZHggPT0gMywgaW5saW5lZF9zdHJpbmdfaWR4ID09IDIKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igc3RyMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFN0cjJCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgc3RyMl8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTVFIzX0ZJRUxEX05VTUJFUiA9IDQ7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBzdHIzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGF1eF9pZHggPT0gNCwgaW5saW5lZF9zdHJpbmdfaWR4ID09IDMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIHN0cjMgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cjMoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPHByZT4KICAgICAqIGF1eF9pZHggPT0gNCwgaW5saW5lZF9zdHJpbmdfaWR4ID09IDMKICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIHN0cjMgPSA0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIHN0cjMuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0U3RyMygpIHsKICAgICAgcmV0dXJuIHN0cjNfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxLCBzdHIxXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlTWVzc2FnZSgyLCBnZXRTdWIoKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAzLCBzdHIyXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlQnl0ZXMoNCwgc3RyM18pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDEsIHN0cjFfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoMiwgZ2V0U3ViKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMywgc3RyMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVCeXRlc1NpemUoNCwgc3RyM18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90bykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90bykgb2JqOwoKICAgICAgaWYgKGhhc1N0cjEoKSAhPSBvdGhlci5oYXNTdHIxKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjEoKSkgewogICAgICAgIGlmICghZ2V0U3RyMSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyMSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdWIoKSAhPSBvdGhlci5oYXNTdWIoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzU3ViKCkpIHsKICAgICAgICBpZiAoIWdldFN1YigpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3ViKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjIoKSAhPSBvdGhlci5oYXNTdHIyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc1N0cjIoKSkgewogICAgICAgIGlmICghZ2V0U3RyMigpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0U3RyMigpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIzKCkgIT0gb3RoZXIuaGFzU3RyMygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTdHIzKCkpIHsKICAgICAgICBpZiAoIWdldFN0cjMoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFN0cjMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNTdHIxKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFIxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHIxKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzU3ViKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVUJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN1YigpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1N0cjIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFNUUjJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFN0cjIoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChoYXNTdHIzKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBTVFIzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRTdHIzKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90b30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8pCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0lubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG9fZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90b19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8uY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90by5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90by5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwogICAgICAgIG1heWJlRm9yY2VCdWlsZGVySW5pdGlhbGl6YXRpb24oKTsKICAgICAgfQogICAgICBwcml2YXRlIHZvaWQgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpIHsKICAgICAgICBpZiAoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgICAgICAgIC5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzKSB7CiAgICAgICAgICBnZXRTdWJGaWVsZEJ1aWxkZXIoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHN0cjFfID0gIiI7CiAgICAgICAgc3ViXyA9IG51bGw7CiAgICAgICAgaWYgKHN1YkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHN1YkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHN1YkJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgc3RyMl8gPSAiIjsKICAgICAgICBzdHIzXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90b19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuc3RyMV8gPSBzdHIxXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdWJfID0gc3ViQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gc3ViXwogICAgICAgICAgICAgIDogc3ViQnVpbGRlcl8uYnVpbGQoKTsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zdHIyXyA9IHN0cjJfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0LnN0cjNfID0gc3RyM187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8pIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90bylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzU3RyMSgpKSB7CiAgICAgICAgICBzdHIxXyA9IG90aGVyLnN0cjFfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdWIoKSkgewogICAgICAgICAgbWVyZ2VTdWIob3RoZXIuZ2V0U3ViKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU3RyMigpKSB7CiAgICAgICAgICBzdHIyXyA9IG90aGVyLnN0cjJfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNTdHIzKCkpIHsKICAgICAgICAgIHNldFN0cjMob3RoZXIuZ2V0U3RyMygpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgc3RyMV8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldFN1YkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDI2OiB7CiAgICAgICAgICAgICAgICBzdHIyXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgc3RyM18gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMV8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFdlIG1peCBkYXRhIHRvIG1ha2Ugc3VyZSBhdXggaWRzIGFuZCBpbmxpbmVkIHN0cmluZyBpZHggZG8gbm90IG1hdGNoLgogICAgICAgKiBhdXhfaWR4ID09IGlubGluZWRfc3RyaW5nX2lkeCA9PSAxCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHN0cjEgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzU3RyMSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFdlIG1peCBkYXRhIHRvIG1ha2Ugc3VyZSBhdXggaWRzIGFuZCBpbmxpbmVkIHN0cmluZyBpZHggZG8gbm90IG1hdGNoLgogICAgICAgKiBhdXhfaWR4ID09IGlubGluZWRfc3RyaW5nX2lkeCA9PSAxCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBzdHIxLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RyMSgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IHN0cjFfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgc3RyMV8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogV2UgbWl4IGRhdGEgdG8gbWFrZSBzdXJlIGF1eCBpZHMgYW5kIGlubGluZWQgc3RyaW5nIGlkeCBkbyBub3QgbWF0Y2guCiAgICAgICAqIGF1eF9pZHggPT0gaW5saW5lZF9zdHJpbmdfaWR4ID09IDEKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0U3RyMUJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMV87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIHN0cjFfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogV2UgbWl4IGRhdGEgdG8gbWFrZSBzdXJlIGF1eCBpZHMgYW5kIGlubGluZWQgc3RyaW5nIGlkeCBkbyBub3QgbWF0Y2guCiAgICAgICAqIGF1eF9pZHggPT0gaW5saW5lZF9zdHJpbmdfaWR4ID09IDEKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc3RyMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFN0cjEoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogV2UgbWl4IGRhdGEgdG8gbWFrZSBzdXJlIGF1eCBpZHMgYW5kIGlubGluZWQgc3RyaW5nIGlkeCBkbyBub3QgbWF0Y2guCiAgICAgICAqIGF1eF9pZHggPT0gaW5saW5lZF9zdHJpbmdfaWR4ID09IDEKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIxID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyMSgpIHsKICAgICAgICBzdHIxXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldFN0cjEoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIFdlIG1peCBkYXRhIHRvIG1ha2Ugc3VyZSBhdXggaWRzIGFuZCBpbmxpbmVkIHN0cmluZyBpZHggZG8gbm90IG1hdGNoLgogICAgICAgKiBhdXhfaWR4ID09IGlubGluZWRfc3RyaW5nX2lkeCA9PSAxCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBzdHIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMUJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHIxXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gc3ViXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8uQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvT3JCdWlsZGVyPiBzdWJCdWlsZGVyXzsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGF1eF9pZHggPT0gMgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gc3ViID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3ViIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1N1YigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGF1eF9pZHggPT0gMgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gc3ViID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN1Yi4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gZ2V0U3ViKCkgewogICAgICAgIGlmIChzdWJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gc3ViXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvLmdldERlZmF1bHRJbnN0YW5jZSgpIDogc3ViXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHN1YkJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGF1eF9pZHggPT0gMgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gc3ViID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTdWIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIHZhbHVlKSB7CiAgICAgICAgaWYgKHN1YkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgc3ViXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdWJCdWlsZGVyXy5zZXRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBhdXhfaWR4ID09IDIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvIHN1YiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3ViKAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHN1YkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHN1Yl8gPSBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3ViQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogYXV4X2lkeCA9PSAyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byBzdWIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlU3ViKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byB2YWx1ZSkgewogICAgICAgIGlmIChzdWJCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkgJiYKICAgICAgICAgICAgc3ViXyAhPSBudWxsICYmCiAgICAgICAgICAgIHN1Yl8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvLmdldERlZmF1bHRJbnN0YW5jZSgpKSB7CiAgICAgICAgICAgIGdldFN1YkJ1aWxkZXIoKS5tZXJnZUZyb20odmFsdWUpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3ViXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdWJCdWlsZGVyXy5tZXJnZUZyb20odmFsdWUpOwogICAgICAgIH0KICAgICAgICBpZiAoc3ViXyAhPSBudWxsKSB7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGF1eF9pZHggPT0gMgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gc3ViID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN1YigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgc3ViXyA9IG51bGw7CiAgICAgICAgaWYgKHN1YkJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIHN1YkJ1aWxkZXJfLmRpc3Bvc2UoKTsKICAgICAgICAgIHN1YkJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGF1eF9pZHggPT0gMgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gc3ViID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvLkJ1aWxkZXIgZ2V0U3ViQnVpbGRlcigpIHsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIGdldFN1YkZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogYXV4X2lkeCA9PSAyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byBzdWIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG9PckJ1aWxkZXIgZ2V0U3ViT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChzdWJCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gc3ViQnVpbGRlcl8uZ2V0TWVzc2FnZU9yQnVpbGRlcigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gc3ViXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8uZ2V0RGVmYXVsdEluc3RhbmNlKCkgOiBzdWJfOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogYXV4X2lkeCA9PSAyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byBzdWIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90bywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90b09yQnVpbGRlcj4gCiAgICAgICAgICBnZXRTdWJGaWVsZEJ1aWxkZXIoKSB7CiAgICAgICAgaWYgKHN1YkJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHN1YkJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8uQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvT3JCdWlsZGVyPigKICAgICAgICAgICAgICAgICAgZ2V0U3ViKCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICBzdWJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHN1YkJ1aWxkZXJfOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgc3RyMl8gPSAiIjsKICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGF1eF9pZHggPT0gMywgaW5saW5lZF9zdHJpbmdfaWR4ID09IDIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMiBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTdHIyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogYXV4X2lkeCA9PSAzLCBpbmxpbmVkX3N0cmluZ19pZHggPT0gMgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgc3RyMi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0cjIoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBzdHIyXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIHN0cjJfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGF1eF9pZHggPT0gMywgaW5saW5lZF9zdHJpbmdfaWR4ID09IDIKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBzdHIyID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBzdHIyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0U3RyMkJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gc3RyMl87CiAgICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIFN0cmluZykgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgICAoamF2YS5sYW5nLlN0cmluZykgcmVmKTsKICAgICAgICAgIHN0cjJfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPHByZT4KICAgICAgICogYXV4X2lkeCA9PSAzLCBpbmxpbmVkX3N0cmluZ19pZHggPT0gMgogICAgICAgKiA8L3ByZT4KICAgICAgICoKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIHN0cjIgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzdHIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBhdXhfaWR4ID09IDMsIGlubGluZWRfc3RyaW5nX2lkeCA9PSAyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMiA9IDM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclN0cjIoKSB7CiAgICAgICAgc3RyMl8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRTdHIyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBhdXhfaWR4ID09IDMsIGlubGluZWRfc3RyaW5nX2lkeCA9PSAyCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgc3RyMiA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBzdHIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMkJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBzdHIyXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgc3RyM18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBhdXhfaWR4ID09IDQsIGlubGluZWRfc3RyaW5nX2lkeCA9PSAzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBzdHIzID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc3RyMyBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc1N0cjMoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBhdXhfaWR4ID09IDQsIGlubGluZWRfc3RyaW5nX2lkeCA9PSAzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBzdHIzID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHN0cjMuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0U3RyMygpIHsKICAgICAgICByZXR1cm4gc3RyM187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxwcmU+CiAgICAgICAqIGF1eF9pZHggPT0gNCwgaW5saW5lZF9zdHJpbmdfaWR4ID09IDMKICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIHN0cjMgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBzdHIzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0U3RyMyhjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIHN0cjNfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8cHJlPgogICAgICAgKiBhdXhfaWR4ID09IDQsIGlubGluZWRfc3RyaW5nX2lkeCA9PSAzCiAgICAgICAqIDwvcHJlPgogICAgICAgKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBzdHIzID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyU3RyMygpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwOCk7CiAgICAgICAgc3RyM18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRTdHIzKCk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90bykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90bykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8oKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPElubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8SW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90bz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIElubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8gcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxJbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPElubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG8+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90byBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFN0cmluZ1BhcnNlVGVzdGVyT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlN0cmluZ1BhcnNlVGVzdGVyKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy4KICAgICAgICAgIEV4dGVuZGFibGVNZXNzYWdlT3JCdWlsZGVyPFN0cmluZ1BhcnNlVGVzdGVyPiB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX2xvd2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU3RyaW5nTG93ZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsU3RyaW5nTG93ZmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmdMb3dmaWVsZC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZ0xvd2ZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZ0xvd2ZpZWxkLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFN0cmluZ0xvd2ZpZWxkQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfbWlkZmllbGQgPSAxMDAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTdHJpbmdNaWRmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxTdHJpbmdNaWRmaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZ01pZGZpZWxkLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nTWlkZmllbGQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nTWlkZmllbGQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsU3RyaW5nTWlkZmllbGRCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU3RyaW5nSGlmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxTdHJpbmdIaWZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmdIaWZpZWxkLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nSGlmaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFN0cmluZ0hpZmllbGQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsU3RyaW5nSGlmaWVsZEJ5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTG93ZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nTG93ZmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZ0xvd2ZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZ0xvd2ZpZWxkKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdMb3dmaWVsZEJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZ01pZGZpZWxkLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTWlkZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nTWlkZmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZ01pZGZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZ01pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZ01pZGZpZWxkKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ01pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdNaWRmaWVsZEJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nSGlmaWVsZC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0hpZmllbGRMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmdIaWZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdIaWZpZWxkQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nSGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdIaWZpZWxkKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nSGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nSGlmaWVsZEJ5dGVzKGludCBpbmRleCk7CiAgfQogIC8qKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlN0cmluZ1BhcnNlVGVzdGVyfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU3RyaW5nUGFyc2VUZXN0ZXIgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgICBTdHJpbmdQYXJzZVRlc3Rlcj4gaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlN0cmluZ1BhcnNlVGVzdGVyKQogICAgICBTdHJpbmdQYXJzZVRlc3Rlck9yQnVpbGRlciB7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMEw7CiAgICAvLyBVc2UgU3RyaW5nUGFyc2VUZXN0ZXIubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgIHByaXZhdGUgU3RyaW5nUGFyc2VUZXN0ZXIoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlciwgPz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgU3RyaW5nUGFyc2VUZXN0ZXIoKSB7CiAgICAgIG9wdGlvbmFsU3RyaW5nTG93ZmllbGRfID0gIiI7CiAgICAgIG9wdGlvbmFsU3RyaW5nTWlkZmllbGRfID0gIiI7CiAgICAgIG9wdGlvbmFsU3RyaW5nSGlmaWVsZF8gPSAiIjsKICAgICAgcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZ01pZGZpZWxkXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nSGlmaWVsZF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFN0cmluZ1BhcnNlVGVzdGVyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU3RyaW5nUGFyc2VUZXN0ZXJfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9TdHJpbmdQYXJzZVRlc3Rlcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3RyaW5nUGFyc2VUZXN0ZXIuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3RyaW5nUGFyc2VUZXN0ZXIuQnVpbGRlci5jbGFzcyk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NUUklOR19MT1dGSUVMRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxTdHJpbmdMb3dmaWVsZF8gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFN0cmluZ0xvd2ZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTdHJpbmdMb3dmaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX2xvd2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZ0xvd2ZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZ0xvd2ZpZWxkKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nTG93ZmllbGRfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIG9wdGlvbmFsU3RyaW5nTG93ZmllbGRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nTG93ZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFN0cmluZ0xvd2ZpZWxkQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdMb3dmaWVsZF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIG9wdGlvbmFsU3RyaW5nTG93ZmllbGRfID0gYjsKICAgICAgICByZXR1cm4gYjsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU1RSSU5HX01JREZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFN0cmluZ01pZGZpZWxkXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU3RyaW5nTWlkZmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFN0cmluZ01pZGZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfbWlkZmllbGQgPSAxMDAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsU3RyaW5nTWlkZmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nTWlkZmllbGQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdNaWRmaWVsZF87CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gCiAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgb3B0aW9uYWxTdHJpbmdNaWRmaWVsZF8gPSBzOwogICAgICAgIH0KICAgICAgICByZXR1cm4gczsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmdNaWRmaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsU3RyaW5nTWlkZmllbGRCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ01pZGZpZWxkXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdNaWRmaWVsZF8gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TVFJJTkdfSElGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDAwMDAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxTdHJpbmdIaWZpZWxkXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTdHJpbmdIaWZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTdHJpbmdIaWZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmdIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZ0hpZmllbGQoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdIaWZpZWxkXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ0hpZmllbGRfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmdIaWZpZWxkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxTdHJpbmdIaWZpZWxkQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdIaWZpZWxkXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdIaWZpZWxkXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR19MT1dGSUVMRF9GSUVMRF9OVU1CRVIgPSAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkXyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0xvd2ZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nTG93ZmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nTG93ZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nTG93ZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdMb3dmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nTG93ZmllbGRfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTG93ZmllbGRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nTG93ZmllbGRfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR19NSURGSUVMRF9GSUVMRF9OVU1CRVIgPSAxMDAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZ01pZGZpZWxkXyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZ01pZGZpZWxkLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ01pZGZpZWxkTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nTWlkZmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZ01pZGZpZWxkLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nTWlkZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nTWlkZmllbGRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZ01pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdNaWRmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nTWlkZmllbGRfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ01pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTWlkZmllbGRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nTWlkZmllbGRfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR19ISUZJRUxEX0ZJRUxEX05VTUJFUiA9IDEwMDAwMDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nSGlmaWVsZF8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZ0hpZmllbGQuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nSGlmaWVsZExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ0hpZmllbGRfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nSGlmaWVsZC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZ0hpZmllbGRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nSGlmaWVsZF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmdIaWZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdIaWZpZWxkKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdIaWZpZWxkXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ0hpZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdIaWZpZWxkQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ0hpZmllbGRfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIGlmICghZXh0ZW5zaW9uc0FyZUluaXRpYWxpemVkKCkpIHsKICAgICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgLkV4dGVuZGFibGVNZXNzYWdlPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3RyaW5nUGFyc2VUZXN0ZXI+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMSwgb3B0aW9uYWxTdHJpbmdMb3dmaWVsZF8pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDIsIHJlcGVhdGVkU3RyaW5nTG93ZmllbGRfLmdldFJhdyhpKSk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMDAxLCBvcHRpb25hbFN0cmluZ01pZGZpZWxkXyk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZ01pZGZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMTAwMiwgcmVwZWF0ZWRTdHJpbmdNaWRmaWVsZF8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEwMDAwMDEsIG9wdGlvbmFsU3RyaW5nSGlmaWVsZF8pOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmdIaWZpZWxkXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMTAwMDAwMiwgcmVwZWF0ZWRTdHJpbmdIaWZpZWxkXy5nZXRSYXcoaSkpOwogICAgICB9CiAgICAgIGV4dGVuc2lvbldyaXRlci53cml0ZVVudGlsKDUzNjg3MDkxMiwgb3V0cHV0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMSwgb3B0aW9uYWxTdHJpbmdMb3dmaWVsZF8pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFN0cmluZ0xvd2ZpZWxkTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDEwMDEsIG9wdGlvbmFsU3RyaW5nTWlkZmllbGRfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nTWlkZmllbGRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nTWlkZmllbGRfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRTdHJpbmdNaWRmaWVsZExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgxMDAwMDAxLCBvcHRpb25hbFN0cmluZ0hpZmllbGRfKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nSGlmaWVsZF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmdIaWZpZWxkXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gNCAqIGdldFJlcGVhdGVkU3RyaW5nSGlmaWVsZExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBleHRlbnNpb25zU2VyaWFsaXplZFNpemUoKTsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlcikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlciBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyKSBvYmo7CgogICAgICBpZiAoaGFzT3B0aW9uYWxTdHJpbmdMb3dmaWVsZCgpICE9IG90aGVyLmhhc09wdGlvbmFsU3RyaW5nTG93ZmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxTdHJpbmdMb3dmaWVsZCgpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbFN0cmluZ0xvd2ZpZWxkKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbFN0cmluZ0xvd2ZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsU3RyaW5nTWlkZmllbGQoKSAhPSBvdGhlci5oYXNPcHRpb25hbFN0cmluZ01pZGZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsU3RyaW5nTWlkZmllbGQoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxTdHJpbmdNaWRmaWVsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxTdHJpbmdNaWRmaWVsZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFN0cmluZ0hpZmllbGQoKSAhPSBvdGhlci5oYXNPcHRpb25hbFN0cmluZ0hpZmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxTdHJpbmdIaWZpZWxkKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsU3RyaW5nSGlmaWVsZCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxTdHJpbmdIaWZpZWxkKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZ0xvd2ZpZWxkTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nTG93ZmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmdNaWRmaWVsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZ01pZGZpZWxkTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nSGlmaWVsZExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZ0hpZmllbGRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RXh0ZW5zaW9uRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldEV4dGVuc2lvbkZpZWxkcygpKSkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsU3RyaW5nTG93ZmllbGQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1NUUklOR19MT1dGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxTdHJpbmdMb3dmaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsU3RyaW5nTWlkZmllbGQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1NUUklOR19NSURGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxTdHJpbmdNaWRmaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsU3RyaW5nSGlmaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfU1RSSU5HX0hJRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsU3RyaW5nSGlmaWVsZCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nTG93ZmllbGRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR19MT1dGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmdMb3dmaWVsZExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFN0cmluZ01pZGZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfTUlERklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nTWlkZmllbGRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmdIaWZpZWxkQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfSElGSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmdIaWZpZWxkTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9IGhhc2hGaWVsZHMoaGFzaCwgZ2V0RXh0ZW5zaW9uRmllbGRzKCkpOwogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3RyaW5nUGFyc2VUZXN0ZXIgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlciBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlN0cmluZ1BhcnNlVGVzdGVyfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlciwgQnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuU3RyaW5nUGFyc2VUZXN0ZXIpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3Rlck9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9TdHJpbmdQYXJzZVRlc3Rlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9TdHJpbmdQYXJzZVRlc3Rlcl9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3Rlci5uZXdCdWlsZGVyKCkKICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgfQoKICAgICAgcHJpdmF0ZSBCdWlsZGVyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICBzdXBlcihwYXJlbnQpOwoKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdMb3dmaWVsZF8gPSAiIjsKICAgICAgICBvcHRpb25hbFN0cmluZ01pZGZpZWxkXyA9ICIiOwogICAgICAgIG9wdGlvbmFsU3RyaW5nSGlmaWVsZF8gPSAiIjsKICAgICAgICByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ01pZGZpZWxkXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ0hpZmllbGRfID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9TdHJpbmdQYXJzZVRlc3Rlcl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3RyaW5nUGFyc2VUZXN0ZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3RyaW5nUGFyc2VUZXN0ZXIgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlciByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3RyaW5nUGFyc2VUZXN0ZXIgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3RyaW5nUGFyc2VUZXN0ZXIgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3RyaW5nUGFyc2VUZXN0ZXIodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlciByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFN0cmluZ0xvd2ZpZWxkXyA9IG9wdGlvbmFsU3RyaW5nTG93ZmllbGRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsU3RyaW5nTWlkZmllbGRfID0gb3B0aW9uYWxTdHJpbmdNaWRmaWVsZF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxTdHJpbmdIaWZpZWxkXyA9IG9wdGlvbmFsU3RyaW5nSGlmaWVsZF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDgpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF8gPSByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nTWlkZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZ01pZGZpZWxkXyA9IHJlcGVhdGVkU3RyaW5nTWlkZmllbGRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdIaWZpZWxkXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmdIaWZpZWxkXyA9IHJlcGVhdGVkU3RyaW5nSGlmaWVsZF87CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3RyaW5nUGFyc2VUZXN0ZXIsIFR5cGU+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlciwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlciwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyLCBUPiBleHRlbnNpb24pIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3RyaW5nUGFyc2VUZXN0ZXIgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3Rlci5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsU3RyaW5nTG93ZmllbGQoKSkgewogICAgICAgICAgb3B0aW9uYWxTdHJpbmdMb3dmaWVsZF8gPSBvdGhlci5vcHRpb25hbFN0cmluZ0xvd2ZpZWxkXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxTdHJpbmdNaWRmaWVsZCgpKSB7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ01pZGZpZWxkXyA9IG90aGVyLm9wdGlvbmFsU3RyaW5nTWlkZmllbGRfOwogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFN0cmluZ0hpZmllbGQoKSkgewogICAgICAgICAgb3B0aW9uYWxTdHJpbmdIaWZpZWxkXyA9IG90aGVyLm9wdGlvbmFsU3RyaW5nSGlmaWVsZF87CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZ0xvd2ZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFN0cmluZ0xvd2ZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF8gPSBvdGhlci5yZXBlYXRlZFN0cmluZ0xvd2ZpZWxkXzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTdHJpbmdNaWRmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmdNaWRmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nTWlkZmllbGRfID0gb3RoZXIucmVwZWF0ZWRTdHJpbmdNaWRmaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nTWlkZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmdNaWRmaWVsZF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU3RyaW5nTWlkZmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nSGlmaWVsZF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmdIaWZpZWxkXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmdIaWZpZWxkXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nSGlmaWVsZF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZ0hpZmllbGRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZ0hpZmllbGRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlRXh0ZW5zaW9uRmllbGRzKG90aGVyKTsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsU3RyaW5nTG93ZmllbGRfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nTG93ZmllbGRJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nTG93ZmllbGRfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTgKICAgICAgICAgICAgICBjYXNlIDgwMTA6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsU3RyaW5nTWlkZmllbGRfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODAxMAogICAgICAgICAgICAgIGNhc2UgODAxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ01pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZ01pZGZpZWxkXy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMTgKICAgICAgICAgICAgICBjYXNlIDgwMDAwMTA6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsU3RyaW5nSGlmaWVsZF8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MDAwMDEwCiAgICAgICAgICAgICAgY2FzZSA4MDAwMDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmdIaWZpZWxkXy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgwMDAwMTgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsU3RyaW5nTG93ZmllbGRfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX2xvd2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTdHJpbmdMb3dmaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFN0cmluZ0xvd2ZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZ0xvd2ZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxTdHJpbmdMb3dmaWVsZCgpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nTG93ZmllbGRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgb3B0aW9uYWxTdHJpbmdMb3dmaWVsZF8gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19sb3dmaWVsZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmdMb3dmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9wdGlvbmFsU3RyaW5nTG93ZmllbGRCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsU3RyaW5nTG93ZmllbGRfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBvcHRpb25hbFN0cmluZ0xvd2ZpZWxkXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBvcHRpb25hbFN0cmluZ0xvd2ZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTdHJpbmdMb3dmaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsU3RyaW5nTG93ZmllbGRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX2xvd2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxTdHJpbmdMb3dmaWVsZCgpIHsKICAgICAgICBvcHRpb25hbFN0cmluZ0xvd2ZpZWxkXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldE9wdGlvbmFsU3RyaW5nTG93ZmllbGQoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfbG93ZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmdMb3dmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU3RyaW5nTG93ZmllbGRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxTdHJpbmdMb3dmaWVsZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFN0cmluZ01pZGZpZWxkXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsU3RyaW5nTWlkZmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxTdHJpbmdNaWRmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfbWlkZmllbGQgPSAxMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxTdHJpbmdNaWRmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsU3RyaW5nTWlkZmllbGQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ01pZGZpZWxkXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIG9wdGlvbmFsU3RyaW5nTWlkZmllbGRfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfbWlkZmllbGQgPSAxMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nTWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRPcHRpb25hbFN0cmluZ01pZGZpZWxkQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ01pZGZpZWxkXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgb3B0aW9uYWxTdHJpbmdNaWRmaWVsZF8gPSBiOwogICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxTdHJpbmdNaWRmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU3RyaW5nTWlkZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbFN0cmluZ01pZGZpZWxkXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19taWRmaWVsZCA9IDEwMDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU3RyaW5nTWlkZmllbGQoKSB7CiAgICAgICAgb3B0aW9uYWxTdHJpbmdNaWRmaWVsZF8gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbFN0cmluZ01pZGZpZWxkKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX21pZGZpZWxkID0gMTAwMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nTWlkZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFN0cmluZ01pZGZpZWxkQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsU3RyaW5nTWlkZmllbGRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxTdHJpbmdIaWZpZWxkXyA9ICIiOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3N0cmluZ19oaWZpZWxkID0gMTAwMDAwMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxTdHJpbmdIaWZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsU3RyaW5nSGlmaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFN0cmluZ0hpZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFN0cmluZ0hpZmllbGQoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFN0cmluZ0hpZmllbGRfOwogICAgICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPQogICAgICAgICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgICAgb3B0aW9uYWxTdHJpbmdIaWZpZWxkXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsU3RyaW5nSGlmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9wdGlvbmFsU3RyaW5nSGlmaWVsZEJ5dGVzKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxTdHJpbmdIaWZpZWxkXzsKICAgICAgICBpZiAocmVmIGluc3RhbmNlb2YgU3RyaW5nKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jb3B5RnJvbVV0ZjgoCiAgICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgICAgb3B0aW9uYWxTdHJpbmdIaWZpZWxkXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsU3RyaW5nSGlmaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsU3RyaW5nSGlmaWVsZCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsU3RyaW5nSGlmaWVsZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9zdHJpbmdfaGlmaWVsZCA9IDEwMDAwMDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsU3RyaW5nSGlmaWVsZCgpIHsKICAgICAgICBvcHRpb25hbFN0cmluZ0hpZmllbGRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0T3B0aW9uYWxTdHJpbmdIaWZpZWxkKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDQpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfc3RyaW5nX2hpZmllbGQgPSAxMDAwMDAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxTdHJpbmdIaWZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxTdHJpbmdIaWZpZWxkQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsU3RyaW5nSGlmaWVsZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nTG93ZmllbGRfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU3RyaW5nTG93ZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZ0xvd2ZpZWxkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KHJlcGVhdGVkU3RyaW5nTG93ZmllbGRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nTG93ZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTG93ZmllbGRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nTG93ZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdMb3dmaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nTG93ZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdMb3dmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTG93ZmllbGRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nTG93ZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFN0cmluZ0xvd2ZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0xvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nTG93ZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0xvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbG93ZmllbGQgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nTG93ZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdMb3dmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2xvd2ZpZWxkID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmdMb3dmaWVsZCgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDgpOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19sb3dmaWVsZCA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ0xvd2ZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmdMb3dmaWVsZEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0xvd2ZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdMb3dmaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nTWlkZmllbGRfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkU3RyaW5nTWlkZmllbGRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZ01pZGZpZWxkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdNaWRmaWVsZF8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0KHJlcGVhdGVkU3RyaW5nTWlkZmllbGRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nTWlkZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTWlkZmllbGRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nTWlkZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdNaWRmaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmdNaWRmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdNaWRmaWVsZENvdW50KCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZ01pZGZpZWxkXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nTWlkZmllbGQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmdNaWRmaWVsZChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdNaWRmaWVsZF8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ01pZGZpZWxkIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nTWlkZmllbGRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdNaWRmaWVsZF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nTWlkZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFN0cmluZ01pZGZpZWxkKAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ01pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdNaWRmaWVsZF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcmVwZWF0ZWRTdHJpbmdNaWRmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nTWlkZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ01pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdNaWRmaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfbWlkZmllbGQgPSAxMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmdNaWRmaWVsZCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nTWlkZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmdNaWRmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZ01pZGZpZWxkXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX21pZGZpZWxkID0gMTAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmdNaWRmaWVsZCgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ01pZGZpZWxkXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOzsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19taWRmaWVsZCA9IDEwMDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZ01pZGZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmdNaWRmaWVsZEJ5dGVzKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ01pZGZpZWxkSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmdNaWRmaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nSGlmaWVsZF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmdIaWZpZWxkSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghcmVwZWF0ZWRTdHJpbmdIaWZpZWxkXy5pc01vZGlmaWFibGUoKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmdIaWZpZWxkXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmdIaWZpZWxkXyk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nSGlmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmdIaWZpZWxkTGlzdCgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ0hpZmllbGRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdIaWZpZWxkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nSGlmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmdIaWZpZWxkQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nSGlmaWVsZF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nSGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZ0hpZmllbGQoaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nSGlmaWVsZF8uZ2V0KGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nSGlmaWVsZCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZ0hpZmllbGRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmdIaWZpZWxkXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ19oaWZpZWxkID0gMTAwMDAwMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZ0hpZmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFN0cmluZ0hpZmllbGQoCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nSGlmaWVsZF8uc2V0KGluZGV4LCB2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZ0hpZmllbGQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZ0hpZmllbGQoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZ0hpZmllbGRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZ0hpZmllbGRfLmFkZCh2YWx1ZSk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmdIaWZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRTdHJpbmdIaWZpZWxkKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPGphdmEubGFuZy5TdHJpbmc+IHZhbHVlcykgewogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZ0hpZmllbGRfKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfaGlmaWVsZCA9IDEwMDAwMDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nSGlmaWVsZCgpIHsKICAgICAgICByZXBlYXRlZFN0cmluZ0hpZmllbGRfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAyMCk7OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nX2hpZmllbGQgPSAxMDAwMDAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmdIaWZpZWxkIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmdIaWZpZWxkQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nSGlmaWVsZElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nSGlmaWVsZF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuU3RyaW5nUGFyc2VUZXN0ZXIpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlN0cmluZ1BhcnNlVGVzdGVyKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlciBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8U3RyaW5nUGFyc2VUZXN0ZXI+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8U3RyaW5nUGFyc2VUZXN0ZXI+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBTdHJpbmdQYXJzZVRlc3RlciBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFN0cmluZ1BhcnNlVGVzdGVyPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFN0cmluZ1BhcnNlVGVzdGVyPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NUUklOR19FWFRfRklFTERfTlVNQkVSID0gMjAwMDAwMDsKICAgIC8qKgogICAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5TdHJpbmdQYXJzZVRlc3RlciB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5TdHJpbmdQYXJzZVRlc3RlciwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nPiBvcHRpb25hbFN0cmluZ0V4dCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3RyaW5nUGFyc2VUZXN0ZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAwLAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZy5jbGFzcywKICAgICAgICAgIG51bGwpOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HX0VYVF9GSUVMRF9OVU1CRVIgPSAyMDAwMDAxOwogICAgLyoqCiAgICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlN0cmluZ1BhcnNlVGVzdGVyIHsgLi4uIH08L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlN0cmluZ1BhcnNlVGVzdGVyLAogICAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+PiByZXBlYXRlZFN0cmluZ0V4dCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgICAubmV3TWVzc2FnZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uU3RyaW5nUGFyc2VUZXN0ZXIuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAxLAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZy5jbGFzcywKICAgICAgICAgIG51bGwpOwogIH0KCiAgcHVibGljIGludGVyZmFjZSBCYWRGaWVsZE5hbWVzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LkJhZEZpZWxkTmFtZXMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBPcHRpb25hbEludDMyID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsSW50MzIoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgT3B0aW9uYWxJbnQzMiA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMi4KICAgICAqLwogICAgaW50IGdldE9wdGlvbmFsSW50MzIoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvciA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmb3IgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0ZvcigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb3IgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvci4KICAgICAqLwogICAgaW50IGdldEZvcigpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5CYWRGaWVsZE5hbWVzfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQmFkRmllbGROYW1lcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5CYWRGaWVsZE5hbWVzKQogICAgICBCYWRGaWVsZE5hbWVzT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBCYWRGaWVsZE5hbWVzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIEJhZEZpZWxkTmFtZXMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBCYWRGaWVsZE5hbWVzKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IEJhZEZpZWxkTmFtZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9CYWRGaWVsZE5hbWVzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQmFkRmllbGROYW1lc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTElOVDMyX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBvcHRpb25hbEludDMyXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIE9wdGlvbmFsSW50MzIgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxJbnQzMiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsSW50MzIoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgT3B0aW9uYWxJbnQzMiA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxJbnQzMi4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRPcHRpb25hbEludDMyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxJbnQzMl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9SX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGludCBmb3JfID0gMDsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgZm9yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvciBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0ZvcigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb3IgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGZvci4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRGb3IoKSB7CiAgICAgIHJldHVybiBmb3JfOwogICAgfQoKICAgIHByaXZhdGUgYnl0ZSBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAtMTsKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgIGJ5dGUgaXNJbml0aWFsaXplZCA9IG1lbW9pemVkSXNJbml0aWFsaXplZDsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMSkgcmV0dXJuIHRydWU7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgb3V0cHV0LndyaXRlSW50MzIoMSwgb3B0aW9uYWxJbnQzMl8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDIsIGZvcl8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIG9wdGlvbmFsSW50MzJfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIsIGZvcl8pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcykgb2JqOwoKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIoKSAhPSBvdGhlci5oYXNPcHRpb25hbEludDMyKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIoKSkgewogICAgICAgIGlmIChnZXRPcHRpb25hbEludDMyKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0T3B0aW9uYWxJbnQzMigpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc0ZvcigpICE9IG90aGVyLmhhc0ZvcigpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNGb3IoKSkgewogICAgICAgIGlmIChnZXRGb3IoKQogICAgICAgICAgICAhPSBvdGhlci5nZXRGb3IoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsSW50MzIoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMSU5UMzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsSW50MzIoKTsKICAgICAgfQogICAgICBpZiAoaGFzRm9yKCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBGT1JfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEZvcigpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhZEZpZWxkTmFtZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhZEZpZWxkTmFtZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhZEZpZWxkTmFtZXMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcyBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhZEZpZWxkTmFtZXMgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhZEZpZWxkTmFtZXMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcyBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcyBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5CYWRGaWVsZE5hbWVzfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuQmFkRmllbGROYW1lcykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhZEZpZWxkTmFtZXNPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQmFkRmllbGROYW1lc19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9CYWRGaWVsZE5hbWVzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBvcHRpb25hbEludDMyXyA9IDA7CiAgICAgICAgZm9yXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0JhZEZpZWxkTmFtZXNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcy5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcyBidWlsZFBhcnRpYWwoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhZEZpZWxkTmFtZXModGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsSW50MzJfID0gb3B0aW9uYWxJbnQzMl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQuZm9yXyA9IGZvcl87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhZEZpZWxkTmFtZXMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhZEZpZWxkTmFtZXMgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYWRGaWVsZE5hbWVzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAob3RoZXIuaGFzT3B0aW9uYWxJbnQzMigpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEludDMyKG90aGVyLmdldE9wdGlvbmFsSW50MzIoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNGb3IoKSkgewogICAgICAgICAgc2V0Rm9yKG90aGVyLmdldEZvcigpKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEludDMyXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDgKICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICBmb3JfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTYKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgb3B0aW9uYWxJbnQzMl8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgT3B0aW9uYWxJbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsSW50MzIgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEludDMyKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgT3B0aW9uYWxJbnQzMiA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEludDMyLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldE9wdGlvbmFsSW50MzIoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsSW50MzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBPcHRpb25hbEludDMyID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxJbnQzMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsSW50MzIoaW50IHZhbHVlKSB7CgogICAgICAgIG9wdGlvbmFsSW50MzJfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBPcHRpb25hbEludDMyID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxJbnQzMigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb3B0aW9uYWxJbnQzMl8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGludCBmb3JfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvciA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGZvciBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc0ZvcigpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvciA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBmb3IuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0Rm9yKCkgewogICAgICAgIHJldHVybiBmb3JfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBmb3IgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBmb3IgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGb3IoaW50IHZhbHVlKSB7CgogICAgICAgIGZvcl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGZvciA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZvcigpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgZm9yXyA9IDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQmFkRmllbGROYW1lcykKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuQmFkRmllbGROYW1lcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcyBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhZEZpZWxkTmFtZXMoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJhZEZpZWxkTmFtZXM+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8QmFkRmllbGROYW1lcz4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJhZEZpZWxkTmFtZXMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxCYWRGaWVsZE5hbWVzPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEJhZEZpZWxkTmFtZXM+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFkRmllbGROYW1lcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3VucmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfdW5yZWRhY3RlZF9uZXN0ZWRfc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF91bnJlZGFjdGVkX25lc3RlZF9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmcuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZ0J5dGVzKCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfcmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDIgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfcmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDIgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmcuCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfcmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDIgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nQnl0ZXMoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb259CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbikKICAgICAgVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25PckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24oKSB7CiAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZ18gPSAiIjsKICAgICAgb3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZ18gPSAiIjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VTlJFREFDVEVEX05FU1RFRF9TVFJJTkdfRklFTERfTlVNQkVSID0gMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSB2b2xhdGlsZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZ18gPSAiIjsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3VucmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3VucmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3VucmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgZm9yIG9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZ0J5dGVzKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZ187CiAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGIgPSAKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgIChqYXZhLmxhbmcuU3RyaW5nKSByZWYpOwogICAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZ18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9SRURBQ1RFRF9ORVNURURfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfcmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDIgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZyBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmcoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3JlZGFjdGVkX25lc3RlZF9zdHJpbmcgPSAyIFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nKCkgewogICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmdfOwogICAgICBpZiAocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IAogICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgaWYgKGJzLmlzVmFsaWRVdGY4KCkpIHsKICAgICAgICAgIG9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3JlZGFjdGVkX25lc3RlZF9zdHJpbmcgPSAyIFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZ18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMSwgb3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyLCBvcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nXyk7CiAgICAgIH0KICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuY29tcHV0ZVN0cmluZ1NpemUoMSwgb3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5jb21wdXRlU3RyaW5nU2l6ZSgyLCBvcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nXyk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbikpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uKSBvYmo7CgogICAgICBpZiAoaGFzT3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZygpKSB7CiAgICAgICAgaWYgKCFnZXRPcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmcoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZygpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNPcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmcoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmcoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldFVua25vd25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKSkgcmV0dXJuIGZhbHNlOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICBpZiAobWVtb2l6ZWRIYXNoQ29kZSAhPSAwKSB7CiAgICAgICAgcmV0dXJuIG1lbW9pemVkSGFzaENvZGU7CiAgICAgIH0KICAgICAgaW50IGhhc2ggPSA0MTsKICAgICAgaGFzaCA9ICgxOSAqIGhhc2gpICsgZ2V0RGVzY3JpcHRvcigpLmhhc2hDb2RlKCk7CiAgICAgIGlmIChoYXNPcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmcoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1VOUkVEQUNURURfTkVTVEVEX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfUkVEQUNURURfTkVTVEVEX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbn0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25PckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25fZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25fZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24ubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZ18gPSAiIjsKICAgICAgICBvcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nXyA9ICIiOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbl9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24odGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmdfID0gb3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5vcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nXyA9IG9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmdfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbikgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbilvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmcoKSkgewogICAgICAgICAgb3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nXyA9IG90aGVyLm9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZ187CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmcoKSkgewogICAgICAgICAgb3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZ18gPSBvdGhlci5vcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmdfID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmdfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfdW5yZWRhY3RlZF9uZXN0ZWRfc3RyaW5nID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF91bnJlZGFjdGVkX25lc3RlZF9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZ18gPSBzOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLlN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3VucmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0T3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3VucmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF91bnJlZGFjdGVkX25lc3RlZF9zdHJpbmcgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmcoKSB7CiAgICAgICAgb3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nXyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldE9wdGlvbmFsVW5yZWRhY3RlZE5lc3RlZFN0cmluZygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3VucmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFVucmVkYWN0ZWROZXN0ZWRTdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmdfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfcmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDIgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIHB1YmxpYyBib29sZWFuIGhhc09wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfcmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDIgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmcoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nXzsKICAgICAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBqYXZhLmxhbmcuU3RyaW5nKSkgewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0KICAgICAgICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHMgPSBicy50b1N0cmluZ1V0ZjgoKTsKICAgICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICAgIG9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9yZWRhY3RlZF9uZXN0ZWRfc3RyaW5nID0gMiBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBvcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9yZWRhY3RlZF9uZXN0ZWRfc3RyaW5nID0gMiBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9yZWRhY3RlZF9uZXN0ZWRfc3RyaW5nID0gMiBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmcoKSB7CiAgICAgICAgb3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZ18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbFJlZGFjdGVkTmVzdGVkU3RyaW5nKCk7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDIpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfcmVkYWN0ZWRfbmVzdGVkX3N0cmluZyA9IDIgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxSZWRhY3RlZE5lc3RlZFN0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24pCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgUmVkYWN0ZWRGaWVsZHNPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuUmVkYWN0ZWRGaWVsZHMpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfcmVkYWN0ZWRfc3RyaW5nID0gMSBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFJlZGFjdGVkU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFJlZGFjdGVkU3RyaW5nKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9yZWRhY3RlZF9zdHJpbmcgPSAxIFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFJlZGFjdGVkU3RyaW5nLgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsUmVkYWN0ZWRTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3JlZGFjdGVkX3N0cmluZyA9IDEgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIGZvciBvcHRpb25hbFJlZGFjdGVkU3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFJlZGFjdGVkU3RyaW5nQnl0ZXMoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF91bnJlZGFjdGVkX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVucmVkYWN0ZWRTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsVW5yZWRhY3RlZFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfdW5yZWRhY3RlZF9zdHJpbmcgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVW5yZWRhY3RlZFN0cmluZy4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFVucmVkYWN0ZWRTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3VucmVkYWN0ZWRfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nLgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRPcHRpb25hbFVucmVkYWN0ZWRTdHJpbmdCeXRlcygpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3JlZGFjdGVkX3N0cmluZyA9IDMgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkUmVkYWN0ZWRTdHJpbmcuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRSZWRhY3RlZFN0cmluZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3JlZGFjdGVkX3N0cmluZyA9IDMgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkUmVkYWN0ZWRTdHJpbmcuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFJlZGFjdGVkU3RyaW5nQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3JlZGFjdGVkX3N0cmluZyA9IDMgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRSZWRhY3RlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRSZWRhY3RlZFN0cmluZyhpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfcmVkYWN0ZWRfc3RyaW5nID0gMyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkUmVkYWN0ZWRTdHJpbmcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFJlZGFjdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF91bnJlZGFjdGVkX3N0cmluZyA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3VucmVkYWN0ZWRfc3RyaW5nID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmcuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfdW5yZWRhY3RlZF9zdHJpbmcgPSA0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmcoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3VucmVkYWN0ZWRfc3RyaW5nID0gNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBvcHRpb25hbF9yZWRhY3RlZF9tZXNzYWdlID0gNSBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFJlZGFjdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2UoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIG9wdGlvbmFsX3JlZGFjdGVkX21lc3NhZ2UgPSA1IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFJlZGFjdGVkTWVzc2FnZS4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBnZXRPcHRpb25hbFJlZGFjdGVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxfcmVkYWN0ZWRfbWVzc2FnZSA9IDUgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbk9yQnVpbGRlciBnZXRPcHRpb25hbFJlZGFjdGVkTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIG9wdGlvbmFsX3VucmVkYWN0ZWRfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBvcHRpb25hbF91bnJlZGFjdGVkX21lc3NhZ2UgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gZ2V0T3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxfdW5yZWRhY3RlZF9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25PckJ1aWxkZXIgZ2V0T3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZU9yQnVpbGRlcigpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3JlZGFjdGVkX21lc3NhZ2UgPSA3IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24+IAogICAgICAgIGdldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfcmVkYWN0ZWRfbWVzc2FnZSA9IDcgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBnZXRSZXBlYXRlZFJlZGFjdGVkTWVzc2FnZShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfcmVkYWN0ZWRfbWVzc2FnZSA9IDcgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3JlZGFjdGVkX21lc3NhZ2UgPSA3IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZFJlZGFjdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3JlZGFjdGVkX21lc3NhZ2UgPSA3IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25PckJ1aWxkZXIgZ2V0UmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbj4gCiAgICAgICAgZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3VucmVkYWN0ZWRfbWVzc2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIGdldFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2UoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3VucmVkYWN0ZWRfbWVzc2FnZSA9IDg7PC9jb2RlPgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25PckJ1aWxkZXI+IAogICAgICAgIGdldFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbk9yQnVpbGRlciBnZXRSZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9yZWRhY3RlZF9zdHJpbmcgPSA5IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBSZWRhY3RlZFN0cmluZ0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3JlZGFjdGVkX3N0cmluZyA9IDkgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgYm9vbGVhbiBjb250YWluc01hcFJlZGFjdGVkU3RyaW5nKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwUmVkYWN0ZWRTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICBnZXRNYXBSZWRhY3RlZFN0cmluZygpOwogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9yZWRhY3RlZF9zdHJpbmcgPSA5IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldE1hcFJlZGFjdGVkU3RyaW5nTWFwKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3JlZGFjdGVkX3N0cmluZyA9IDkgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRNYXBSZWRhY3RlZFN0cmluZ09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3JlZGFjdGVkX3N0cmluZyA9IDkgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRNYXBSZWRhY3RlZFN0cmluZ09yVGhyb3coCiAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpOwoKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfdW5yZWRhY3RlZF9zdHJpbmcgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGludCBnZXRNYXBVbnJlZGFjdGVkU3RyaW5nQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfdW5yZWRhY3RlZF9zdHJpbmcgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGJvb2xlYW4gY29udGFpbnNNYXBVbnJlZGFjdGVkU3RyaW5nKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICAgIC8qKgogICAgICogVXNlIHtAbGluayAjZ2V0TWFwVW5yZWRhY3RlZFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldE1hcFVucmVkYWN0ZWRTdHJpbmcoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfdW5yZWRhY3RlZF9zdHJpbmcgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGdldE1hcFVucmVkYWN0ZWRTdHJpbmdNYXAoKTsKICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfdW5yZWRhY3RlZF9zdHJpbmcgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0TWFwVW5yZWRhY3RlZFN0cmluZ09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSk7CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3VucmVkYWN0ZWRfc3RyaW5nID0gMTA7PC9jb2RlPgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldE1hcFVucmVkYWN0ZWRTdHJpbmdPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuUmVkYWN0ZWRGaWVsZHN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBSZWRhY3RlZEZpZWxkcyBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5SZWRhY3RlZEZpZWxkcykKICAgICAgUmVkYWN0ZWRGaWVsZHNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFJlZGFjdGVkRmllbGRzLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFJlZGFjdGVkRmllbGRzKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgUmVkYWN0ZWRGaWVsZHMoKSB7CiAgICAgIG9wdGlvbmFsUmVkYWN0ZWRTdHJpbmdfID0gIiI7CiAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZFN0cmluZ18gPSAiIjsKICAgICAgcmVwZWF0ZWRSZWRhY3RlZFN0cmluZ18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBSZWRhY3RlZEZpZWxkcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlZGFjdGVkRmllbGRzX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQFN1cHByZXNzV2FybmluZ3MoeyJyYXd0eXBlcyJ9KQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgaW50IG51bWJlcikgewogICAgICBzd2l0Y2ggKG51bWJlcikgewogICAgICAgIGNhc2UgOToKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFJlZGFjdGVkU3RyaW5nKCk7CiAgICAgICAgY2FzZSAxMDoKICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFVucmVkYWN0ZWRTdHJpbmcoKTsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oCiAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgIH0KICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlZGFjdGVkRmllbGRzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZWRhY3RlZEZpZWxkcy5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZWRhY3RlZEZpZWxkcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfUkVEQUNURURfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgdm9sYXRpbGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFJlZGFjdGVkU3RyaW5nXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfcmVkYWN0ZWRfc3RyaW5nID0gMSBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFJlZGFjdGVkU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxSZWRhY3RlZFN0cmluZygpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfcmVkYWN0ZWRfc3RyaW5nID0gMSBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxSZWRhY3RlZFN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T3B0aW9uYWxSZWRhY3RlZFN0cmluZygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFJlZGFjdGVkU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBvcHRpb25hbFJlZGFjdGVkU3RyaW5nXyA9IHM7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9yZWRhY3RlZF9zdHJpbmcgPSAxIFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxSZWRhY3RlZFN0cmluZy4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldE9wdGlvbmFsUmVkYWN0ZWRTdHJpbmdCeXRlcygpIHsKICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFJlZGFjdGVkU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0aW9uYWxSZWRhY3RlZFN0cmluZ18gPSBiOwogICAgICAgIHJldHVybiBiOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nKSByZWY7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VTlJFREFDVEVEX1NUUklOR19GSUVMRF9OVU1CRVIgPSAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIHZvbGF0aWxlIGphdmEubGFuZy5PYmplY3Qgb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nXyA9ICIiOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfdW5yZWRhY3RlZF9zdHJpbmcgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF91bnJlZGFjdGVkX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFVucmVkYWN0ZWRTdHJpbmcoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSAKICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIGphdmEubGFuZy5TdHJpbmcgcyA9IGJzLnRvU3RyaW5nVXRmOCgpOwogICAgICAgIGlmIChicy5pc1ZhbGlkVXRmOCgpKSB7CiAgICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWRTdHJpbmdfID0gczsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHM7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3VucmVkYWN0ZWRfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0T3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nQnl0ZXMoKSB7CiAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nXzsKICAgICAgaWYgKHJlZiBpbnN0YW5jZW9mIGphdmEubGFuZy5TdHJpbmcpIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYiA9IAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY29weUZyb21VdGY4KAogICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nXyA9IGI7CiAgICAgICAgcmV0dXJuIGI7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1JFREFDVEVEX1NUUklOR19GSUVMRF9OVU1CRVIgPSAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFJlZGFjdGVkU3RyaW5nXyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfcmVkYWN0ZWRfc3RyaW5nID0gMyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRSZWRhY3RlZFN0cmluZy4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwZWF0ZWRSZWRhY3RlZFN0cmluZ0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFJlZGFjdGVkU3RyaW5nXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3JlZGFjdGVkX3N0cmluZyA9IDMgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkUmVkYWN0ZWRTdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRSZWRhY3RlZFN0cmluZ0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRSZWRhY3RlZFN0cmluZ18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfcmVkYWN0ZWRfc3RyaW5nID0gMyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFJlZGFjdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRSZWRhY3RlZFN0cmluZyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9yZWRhY3RlZF9zdHJpbmcgPSAzIFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRSZWRhY3RlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFJlZGFjdGVkU3RyaW5nQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFJlZGFjdGVkU3RyaW5nXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9VTlJFREFDVEVEX1NUUklOR19GSUVMRF9OVU1CRVIgPSA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF91bnJlZGFjdGVkX3N0cmluZyA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3VucmVkYWN0ZWRfc3RyaW5nID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmcuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3VucmVkYWN0ZWRfc3RyaW5nID0gNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ18uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3VucmVkYWN0ZWRfc3RyaW5nID0gNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ0J5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9SRURBQ1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDU7CiAgICBwcml2YXRlIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxfcmVkYWN0ZWRfbWVzc2FnZSA9IDUgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFJlZGFjdGVkTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxfcmVkYWN0ZWRfbWVzc2FnZSA9IDUgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBnZXRPcHRpb25hbFJlZGFjdGVkTWVzc2FnZSgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIG9wdGlvbmFsX3JlZGFjdGVkX21lc3NhZ2UgPSA1IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uT3JCdWlsZGVyIGdldE9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICByZXR1cm4gb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VOUkVEQUNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVIgPSA2OwogICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VfOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxfdW5yZWRhY3RlZF9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBvcHRpb25hbF91bnJlZGFjdGVkX21lc3NhZ2UgPSA2OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2UuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIGdldE9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2UoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxfdW5yZWRhY3RlZF9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uT3JCdWlsZGVyIGdldE9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VPckJ1aWxkZXIoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VfOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1JFREFDVEVEX01FU1NBR0VfRklFTERfTlVNQkVSID0gNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uPiByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF9yZWRhY3RlZF9tZXNzYWdlID0gNyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbj4gZ2V0UmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfcmVkYWN0ZWRfbWVzc2FnZSA9IDcgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZFJlZGFjdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF9yZWRhY3RlZF9tZXNzYWdlID0gNyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfcmVkYWN0ZWRfbWVzc2FnZSA9IDcgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gZ2V0UmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3JlZGFjdGVkX21lc3NhZ2UgPSA3IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uT3JCdWlsZGVyIGdldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgIGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VfLmdldChpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfVU5SRURBQ1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUiA9IDg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbj4gcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZV87CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24+IGdldFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5MaXN0PD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uT3JCdWlsZGVyPiAKICAgICAgICBnZXRSZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfdW5yZWRhY3RlZF9tZXNzYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfdW5yZWRhY3RlZF9tZXNzYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIGdldFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2UoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfdW5yZWRhY3RlZF9tZXNzYWdlID0gODs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uT3JCdWlsZGVyIGdldFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VPckJ1aWxkZXIoCiAgICAgICAgaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1BUF9SRURBQ1RFRF9TVFJJTkdfRklFTERfTlVNQkVSID0gOTsKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNsYXNzIE1hcFJlZGFjdGVkU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyIHsKICAgICAgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0RW50cnkgPQogICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnkKICAgICAgICAgICAgICAuPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+bmV3RGVmYXVsdEluc3RhbmNlKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SZWRhY3RlZEZpZWxkc19NYXBSZWRhY3RlZFN0cmluZ0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXBSZWRhY3RlZFN0cmluZ187CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgIGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKSB7CiAgICAgIGlmIChtYXBSZWRhY3RlZFN0cmluZ18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcFJlZGFjdGVkU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcFJlZGFjdGVkU3RyaW5nXzsKICAgIH0KICAgIHB1YmxpYyBpbnQgZ2V0TWFwUmVkYWN0ZWRTdHJpbmdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3JlZGFjdGVkX3N0cmluZyA9IDkgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBSZWRhY3RlZFN0cmluZygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgfQogICAgLyoqCiAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBSZWRhY3RlZFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldE1hcFJlZGFjdGVkU3RyaW5nKCkgewogICAgICByZXR1cm4gZ2V0TWFwUmVkYWN0ZWRTdHJpbmdNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfcmVkYWN0ZWRfc3RyaW5nID0gOSBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNYXBSZWRhY3RlZFN0cmluZ01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKS5nZXRNYXAoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfcmVkYWN0ZWRfc3RyaW5nID0gOSBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRNYXBSZWRhY3RlZFN0cmluZ09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBSZWRhY3RlZFN0cmluZygpLmdldE1hcCgpOwogICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3JlZGFjdGVkX3N0cmluZyA9IDkgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TWFwUmVkYWN0ZWRTdHJpbmdPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFJlZGFjdGVkU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgIGlmICghbWFwLmNvbnRhaW5zS2V5KGtleSkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICB9CiAgICAgIHJldHVybiBtYXAuZ2V0KGtleSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUFQX1VOUkVEQUNURURfU1RSSU5HX0ZJRUxEX05VTUJFUiA9IDEwOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2xhc3MgTWFwVW5yZWRhY3RlZFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlciB7CiAgICAgIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5PAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdEVudHJ5ID0KICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEVudHJ5CiAgICAgICAgICAgICAgLjxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPm5ld0RlZmF1bHRJbnN0YW5jZSgKICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmVkYWN0ZWRGaWVsZHNfTWFwVW5yZWRhY3RlZFN0cmluZ0VudHJ5X2Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLldpcmVGb3JtYXQuRmllbGRUeXBlLlNUUklORywKICAgICAgICAgICAgICAgICAgIiIsCiAgICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuV2lyZUZvcm1hdC5GaWVsZFR5cGUuU1RSSU5HLAogICAgICAgICAgICAgICAgICAiIik7CiAgICB9CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXBVbnJlZGFjdGVkU3RyaW5nXzsKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgaW50ZXJuYWxHZXRNYXBVbnJlZGFjdGVkU3RyaW5nKCkgewogICAgICBpZiAobWFwVW5yZWRhY3RlZFN0cmluZ18gPT0gbnVsbCkgewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgIE1hcFVucmVkYWN0ZWRTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5KTsKICAgICAgfQogICAgICByZXR1cm4gbWFwVW5yZWRhY3RlZFN0cmluZ187CiAgICB9CiAgICBwdWJsaWMgaW50IGdldE1hcFVucmVkYWN0ZWRTdHJpbmdDb3VudCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwVW5yZWRhY3RlZFN0cmluZygpLmdldE1hcCgpLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfdW5yZWRhY3RlZF9zdHJpbmcgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGNvbnRhaW5zTWFwVW5yZWRhY3RlZFN0cmluZygKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwVW5yZWRhY3RlZFN0cmluZygpLmdldE1hcCgpLmNvbnRhaW5zS2V5KGtleSk7CiAgICB9CiAgICAvKioKICAgICAqIFVzZSB7QGxpbmsgI2dldE1hcFVucmVkYWN0ZWRTdHJpbmdNYXAoKX0gaW5zdGVhZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICBwdWJsaWMgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBnZXRNYXBVbnJlZGFjdGVkU3RyaW5nKCkgewogICAgICByZXR1cm4gZ2V0TWFwVW5yZWRhY3RlZFN0cmluZ01hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF91bnJlZGFjdGVkX3N0cmluZyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0TWFwVW5yZWRhY3RlZFN0cmluZ01hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwVW5yZWRhY3RlZFN0cmluZygpLmdldE1hcCgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF91bnJlZGFjdGVkX3N0cmluZyA9IDEwOzwvY29kZT4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIC8qIG51bGxhYmxlICovCmphdmEubGFuZy5TdHJpbmcgZ2V0TWFwVW5yZWRhY3RlZFN0cmluZ09yRGVmYXVsdCgKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXAgPQogICAgICAgICAgaW50ZXJuYWxHZXRNYXBVbnJlZGFjdGVkU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgIHJldHVybiBtYXAuY29udGFpbnNLZXkoa2V5KSA/IG1hcC5nZXQoa2V5KSA6IGRlZmF1bHRWYWx1ZTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfdW5yZWRhY3RlZF9zdHJpbmcgPSAxMDs8L2NvZGU+CiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE1hcFVucmVkYWN0ZWRTdHJpbmdPclRocm93KAogICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFVucmVkYWN0ZWRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMSwgb3B0aW9uYWxSZWRhY3RlZFN0cmluZ18pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMiwgb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nXyk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFJlZGFjdGVkU3RyaW5nXy5zaXplKCk7IGkrKykgewogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLndyaXRlU3RyaW5nKG91dHB1dCwgMywgcmVwZWF0ZWRSZWRhY3RlZFN0cmluZ18uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDQsIHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ18uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVNZXNzYWdlKDUsIGdldE9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNiwgZ2V0T3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZSgpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoNywgcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VfLmdldChpKSk7CiAgICAgIH0KICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXy5zaXplKCk7IGkrKykgewogICAgICAgIG91dHB1dC53cml0ZU1lc3NhZ2UoOCwgcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKSwKICAgICAgICAgIE1hcFJlZGFjdGVkU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSwKICAgICAgICAgIDkpOwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5zZXJpYWxpemVTdHJpbmdNYXBUbygKICAgICAgICAgIG91dHB1dCwKICAgICAgICAgIGludGVybmFsR2V0TWFwVW5yZWRhY3RlZFN0cmluZygpLAogICAgICAgICAgTWFwVW5yZWRhY3RlZFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnksCiAgICAgICAgICAxMCk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDEsIG9wdGlvbmFsUmVkYWN0ZWRTdHJpbmdfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLmNvbXB1dGVTdHJpbmdTaXplKDIsIG9wdGlvbmFsVW5yZWRhY3RlZFN0cmluZ18pOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRSZWRhY3RlZFN0cmluZ18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRSZWRhY3RlZFN0cmluZ18uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFJlZGFjdGVkU3RyaW5nTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ0xpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDUsIGdldE9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA4KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVNZXNzYWdlU2l6ZSg2LCBnZXRPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlKCkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDcsIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXy5nZXQoaSkpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOCwgcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZV8uZ2V0KGkpKTsKICAgICAgfQogICAgICBmb3IgKGphdmEudXRpbC5NYXAuRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZW50cnkKICAgICAgICAgICA6IGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIG1hcFJlZGFjdGVkU3RyaW5nX18gPSBNYXBSZWRhY3RlZFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkubmV3QnVpbGRlckZvclR5cGUoKQogICAgICAgICAgICAuc2V0S2V5KGVudHJ5LmdldEtleSgpKQogICAgICAgICAgICAuc2V0VmFsdWUoZW50cnkuZ2V0VmFsdWUoKSkKICAgICAgICAgICAgLmJ1aWxkKCk7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAgIC5jb21wdXRlTWVzc2FnZVNpemUoOSwgbWFwUmVkYWN0ZWRTdHJpbmdfXyk7CiAgICAgIH0KICAgICAgZm9yIChqYXZhLnV0aWwuTWFwLkVudHJ5PGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGVudHJ5CiAgICAgICAgICAgOiBpbnRlcm5hbEdldE1hcFVucmVkYWN0ZWRTdHJpbmcoKS5nZXRNYXAoKS5lbnRyeVNldCgpKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBFbnRyeTxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIG1hcFVucmVkYWN0ZWRTdHJpbmdfXyA9IE1hcFVucmVkYWN0ZWRTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5Lm5ld0J1aWxkZXJGb3JUeXBlKCkKICAgICAgICAgICAgLnNldEtleShlbnRyeS5nZXRLZXkoKSkKICAgICAgICAgICAgLnNldFZhbHVlKGVudHJ5LmdldFZhbHVlKCkpCiAgICAgICAgICAgIC5idWlsZCgpOwogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZU1lc3NhZ2VTaXplKDEwLCBtYXBVbnJlZGFjdGVkU3RyaW5nX18pOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMpKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmVxdWFscyhvYmopOwogICAgICB9CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZWRhY3RlZEZpZWxkcykgb2JqOwoKICAgICAgaWYgKGhhc09wdGlvbmFsUmVkYWN0ZWRTdHJpbmcoKSAhPSBvdGhlci5oYXNPcHRpb25hbFJlZGFjdGVkU3RyaW5nKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsUmVkYWN0ZWRTdHJpbmcoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxSZWRhY3RlZFN0cmluZygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxSZWRhY3RlZFN0cmluZygpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbFVucmVkYWN0ZWRTdHJpbmcoKSAhPSBvdGhlci5oYXNPcHRpb25hbFVucmVkYWN0ZWRTdHJpbmcoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsVW5yZWRhY3RlZFN0cmluZygpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRSZXBlYXRlZFJlZGFjdGVkU3RyaW5nTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlKCkgIT0gb3RoZXIuaGFzT3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2UoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2UoKQogICAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldE9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2UoKSAhPSBvdGhlci5oYXNPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2UoKSkgewogICAgICAgIGlmICghZ2V0T3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZSgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZSgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKS5lcXVhbHMoCiAgICAgICAgICBvdGhlci5pbnRlcm5hbEdldE1hcFJlZGFjdGVkU3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBVbnJlZGFjdGVkU3RyaW5nKCkuZXF1YWxzKAogICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBVbnJlZGFjdGVkU3RyaW5nKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc09wdGlvbmFsUmVkYWN0ZWRTdHJpbmcoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1JFREFDVEVEX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0T3B0aW9uYWxSZWRhY3RlZFN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc09wdGlvbmFsVW5yZWRhY3RlZFN0cmluZygpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVU5SRURBQ1RFRF9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsVW5yZWRhY3RlZFN0cmluZygpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1JFREFDVEVEX1NUUklOR19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRSZWRhY3RlZFN0cmluZ0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VOUkVEQUNURURfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2UoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX1JFREFDVEVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgT1BUSU9OQUxfVU5SRURBQ1RFRF9NRVNTQUdFX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1JFREFDVEVEX01FU1NBR0VfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1VOUkVEQUNURURfTUVTU0FHRV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBSZWRhY3RlZFN0cmluZygpLmdldE1hcCgpLmlzRW1wdHkoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE1BUF9SRURBQ1RFRF9TVFJJTkdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmICghaW50ZXJuYWxHZXRNYXBVbnJlZGFjdGVkU3RyaW5nKCkuZ2V0TWFwKCkuaXNFbXB0eSgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgTUFQX1VOUkVEQUNURURfU1RSSU5HX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBpbnRlcm5hbEdldE1hcFVucmVkYWN0ZWRTdHJpbmcoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlZGFjdGVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlZGFjdGVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlZGFjdGVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZWRhY3RlZEZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlZGFjdGVkRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuUmVkYWN0ZWRGaWVsZHN9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5SZWRhY3RlZEZpZWxkcykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlZGFjdGVkRmllbGRzT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlZGFjdGVkRmllbGRzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNYXBGaWVsZFJlZmxlY3Rpb24oCiAgICAgICAgICBpbnQgbnVtYmVyKSB7CiAgICAgICAgc3dpdGNoIChudW1iZXIpIHsKICAgICAgICAgIGNhc2UgOToKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKTsKICAgICAgICAgIGNhc2UgMTA6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE1hcFVucmVkYWN0ZWRTdHJpbmcoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsicmF3dHlwZXMifSkKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGRSZWZsZWN0aW9uQWNjZXNzb3IgaW50ZXJuYWxHZXRNdXRhYmxlTWFwRmllbGRSZWZsZWN0aW9uKAogICAgICAgICAgaW50IG51bWJlcikgewogICAgICAgIHN3aXRjaCAobnVtYmVyKSB7CiAgICAgICAgICBjYXNlIDk6CiAgICAgICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBSZWRhY3RlZFN0cmluZygpOwogICAgICAgICAgY2FzZSAxMDoKICAgICAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TXV0YWJsZU1hcFVucmVkYWN0ZWRTdHJpbmcoKTsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKAogICAgICAgICAgICAgICAgIkludmFsaWQgbWFwIGZpZWxkIG51bWJlcjogIiArIG51bWJlcik7CiAgICAgICAgfQogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlZGFjdGVkRmllbGRzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMuQnVpbGRlci5jbGFzcyk7CiAgICAgIH0KCiAgICAgIC8vIENvbnN0cnVjdCB1c2luZyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlZGFjdGVkRmllbGRzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CiAgICAgICAgbWF5YmVGb3JjZUJ1aWxkZXJJbml0aWFsaXphdGlvbigpOwogICAgICB9CiAgICAgIHByaXZhdGUgdm9pZCBtYXliZUZvcmNlQnVpbGRlckluaXRpYWxpemF0aW9uKCkgewogICAgICAgIGlmIChjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAgICAgLmFsd2F5c1VzZUZpZWxkQnVpbGRlcnMpIHsKICAgICAgICAgIGdldE9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCk7CiAgICAgICAgICBnZXRSZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgICAgZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpOwogICAgICAgIH0KICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyKCkgewogICAgICAgIHN1cGVyLmNsZWFyKCk7CiAgICAgICAgYml0RmllbGQwXyA9IDA7CiAgICAgICAgb3B0aW9uYWxSZWRhY3RlZFN0cmluZ18gPSAiIjsKICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWRTdHJpbmdfID0gIiI7CiAgICAgICAgcmVwZWF0ZWRSZWRhY3RlZFN0cmluZ18gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICBvcHRpb25hbFJlZGFjdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIGlmIChvcHRpb25hbFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICBpZiAob3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfICE9IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBudWxsOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmNsZWFyKCk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICBpZiAocmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uY2xlYXIoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFJlZGFjdGVkU3RyaW5nKCkuY2xlYXIoKTsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVbnJlZGFjdGVkU3RyaW5nKCkuY2xlYXIoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmVkYWN0ZWRGaWVsZHNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZWRhY3RlZEZpZWxkcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlZGFjdGVkRmllbGRzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlZGFjdGVkRmllbGRzIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlZGFjdGVkRmllbGRzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlZGFjdGVkRmllbGRzIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlZGFjdGVkRmllbGRzKHRoaXMpOwogICAgICAgIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHJlc3VsdCk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbFJlcGVhdGVkRmllbGRzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMgcmVzdWx0KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwNDApICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXyk7CiAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICAgIH0KICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8gPSByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV87CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8gPSByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICAgIGlmIChyZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZV8pOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZV8gPSByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfID0gcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlZGFjdGVkRmllbGRzIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICAgIGludCB0b19iaXRGaWVsZDBfID0gMDsKICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsUmVkYWN0ZWRTdHJpbmdfID0gb3B0aW9uYWxSZWRhY3RlZFN0cmluZ187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nXyA9IG9wdGlvbmFsVW5yZWRhY3RlZFN0cmluZ187CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkU3RyaW5nXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRSZWRhY3RlZFN0cmluZ18gPSByZXBlYXRlZFJlZGFjdGVkU3RyaW5nXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ18gPSByZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlXyA9IG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VfCiAgICAgICAgICAgICAgOiBvcHRpb25hbFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmJ1aWxkKCk7CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZV8gPSBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbAogICAgICAgICAgICAgID8gb3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZV8KICAgICAgICAgICAgICA6IG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5idWlsZCgpOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMTAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFJlZGFjdGVkU3RyaW5nXyA9IGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKTsKICAgICAgICAgIHJlc3VsdC5tYXBSZWRhY3RlZFN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMjAwKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm1hcFVucmVkYWN0ZWRTdHJpbmdfID0gaW50ZXJuYWxHZXRNYXBVbnJlZGFjdGVkU3RyaW5nKCk7CiAgICAgICAgICByZXN1bHQubWFwVW5yZWRhY3RlZFN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZWRhY3RlZEZpZWxkcykgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZWRhY3RlZEZpZWxkcylvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlZGFjdGVkRmllbGRzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFJlZGFjdGVkU3RyaW5nKCkpIHsKICAgICAgICAgIG9wdGlvbmFsUmVkYWN0ZWRTdHJpbmdfID0gb3RoZXIub3B0aW9uYWxSZWRhY3RlZFN0cmluZ187CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsVW5yZWRhY3RlZFN0cmluZygpKSB7CiAgICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWRTdHJpbmdfID0gb3RoZXIub3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nXzsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkU3RyaW5nXyA9IG90aGVyLnJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFJlZGFjdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdfLmFkZEFsbChvdGhlci5yZXBlYXRlZFJlZGFjdGVkU3RyaW5nXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ18gPSBvdGhlci5yZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2Uob3RoZXIuZ2V0T3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2UoKSk7CiAgICAgICAgfQogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlKCkpIHsKICAgICAgICAgIG1lcmdlT3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZShvdGhlci5nZXRPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlKCkpOwogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV87CiAgICAgICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwNDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VfLmFkZEFsbChvdGhlci5yZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VfID0gb3RoZXIucmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTsKICAgICAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgOiBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXMob3RoZXIucmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIGlmIChyZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXyA9IG90aGVyLnJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfOwogICAgICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgaWYgKHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG51bGw7CiAgICAgICAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZV8gPSBvdGhlci5yZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXzsKICAgICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA4MCk7CiAgICAgICAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID0gCiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5hbHdheXNVc2VGaWVsZEJ1aWxkZXJzID8KICAgICAgICAgICAgICAgICAgIGdldFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKSA6IG51bGw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZEFsbE1lc3NhZ2VzKG90aGVyLnJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBSZWRhY3RlZFN0cmluZygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBSZWRhY3RlZFN0cmluZygpKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVW5yZWRhY3RlZFN0cmluZygpLm1lcmdlRnJvbSgKICAgICAgICAgICAgb3RoZXIuaW50ZXJuYWxHZXRNYXBVbnJlZGFjdGVkU3RyaW5nKCkpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbFJlZGFjdGVkU3RyaW5nXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgY2FzZSAxODogewogICAgICAgICAgICAgICAgb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nXyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFJlZGFjdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkU3RyaW5nXy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI2CiAgICAgICAgICAgICAgY2FzZSAzNDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ18uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAzNAogICAgICAgICAgICAgIGNhc2UgNDI6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA0MgogICAgICAgICAgICAgIGNhc2UgNTA6IHsKICAgICAgICAgICAgICAgIGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKCksCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDUwCiAgICAgICAgICAgICAgY2FzZSA1ODogewogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBtID0KICAgICAgICAgICAgICAgICAgICBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5QQVJTRVIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICAgICAgICAgIGlmIChyZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VfLmFkZChtKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1OAogICAgICAgICAgICAgIGNhc2UgNjY6IHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gbSA9CiAgICAgICAgICAgICAgICAgICAgaW5wdXQucmVhZE1lc3NhZ2UoCiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uUEFSU0VSLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpZiAocmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXy5hZGQobSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA2NgogICAgICAgICAgICAgIGNhc2UgNzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIG1hcFJlZGFjdGVkU3RyaW5nX18gPSBpbnB1dC5yZWFkTWVzc2FnZSgKICAgICAgICAgICAgICAgICAgICBNYXBSZWRhY3RlZFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkuZ2V0UGFyc2VyRm9yVHlwZSgpLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBSZWRhY3RlZFN0cmluZygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwUmVkYWN0ZWRTdHJpbmdfXy5nZXRLZXkoKSwgbWFwUmVkYWN0ZWRTdHJpbmdfXy5nZXRWYWx1ZSgpKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NAogICAgICAgICAgICAgIGNhc2UgODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRW50cnk8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgICAgICAgIG1hcFVucmVkYWN0ZWRTdHJpbmdfXyA9IGlucHV0LnJlYWRNZXNzYWdlKAogICAgICAgICAgICAgICAgICAgIE1hcFVucmVkYWN0ZWRTdHJpbmdEZWZhdWx0RW50cnlIb2xkZXIuZGVmYXVsdEVudHJ5LmdldFBhcnNlckZvclR5cGUoKSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVW5yZWRhY3RlZFN0cmluZygpLmdldE11dGFibGVNYXAoKS5wdXQoCiAgICAgICAgICAgICAgICAgICAgbWFwVW5yZWRhY3RlZFN0cmluZ19fLmdldEtleSgpLCBtYXBVbnJlZGFjdGVkU3RyaW5nX18uZ2V0VmFsdWUoKSk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgODIKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuT2JqZWN0IG9wdGlvbmFsUmVkYWN0ZWRTdHJpbmdfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfcmVkYWN0ZWRfc3RyaW5nID0gMSBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsUmVkYWN0ZWRTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxSZWRhY3RlZFN0cmluZygpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9yZWRhY3RlZF9zdHJpbmcgPSAxIFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsUmVkYWN0ZWRTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcHRpb25hbFJlZGFjdGVkU3RyaW5nKCkgewogICAgICAgIGphdmEubGFuZy5PYmplY3QgcmVmID0gb3B0aW9uYWxSZWRhY3RlZFN0cmluZ187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBvcHRpb25hbFJlZGFjdGVkU3RyaW5nXyA9IHM7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChqYXZhLmxhbmcuU3RyaW5nKSByZWY7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfcmVkYWN0ZWRfc3RyaW5nID0gMSBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxSZWRhY3RlZFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldE9wdGlvbmFsUmVkYWN0ZWRTdHJpbmdCeXRlcygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsUmVkYWN0ZWRTdHJpbmdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBvcHRpb25hbFJlZGFjdGVkU3RyaW5nXyA9IGI7CiAgICAgICAgICByZXR1cm4gYjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIChjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF9yZWRhY3RlZF9zdHJpbmcgPSAxIFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxSZWRhY3RlZFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsUmVkYWN0ZWRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbFJlZGFjdGVkU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3JlZGFjdGVkX3N0cmluZyA9IDEgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFJlZGFjdGVkU3RyaW5nKCkgewogICAgICAgIG9wdGlvbmFsUmVkYWN0ZWRTdHJpbmdfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0T3B0aW9uYWxSZWRhY3RlZFN0cmluZygpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3JlZGFjdGVkX3N0cmluZyA9IDEgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxSZWRhY3RlZFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsUmVkYWN0ZWRTdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxSZWRhY3RlZFN0cmluZ18gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBvcHRpb25hbFVucmVkYWN0ZWRTdHJpbmdfID0gIiI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBzdHJpbmcgb3B0aW9uYWxfdW5yZWRhY3RlZF9zdHJpbmcgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbFVucmVkYWN0ZWRTdHJpbmcgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3VucmVkYWN0ZWRfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIG9wdGlvbmFsVW5yZWRhY3RlZFN0cmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wdGlvbmFsVW5yZWRhY3RlZFN0cmluZygpIHsKICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHJlZiA9IG9wdGlvbmFsVW5yZWRhY3RlZFN0cmluZ187CiAgICAgICAgaWYgKCEocmVmIGluc3RhbmNlb2YgamF2YS5sYW5nLlN0cmluZykpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9CiAgICAgICAgICAgICAgKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBzID0gYnMudG9TdHJpbmdVdGY4KCk7CiAgICAgICAgICBpZiAoYnMuaXNWYWxpZFV0ZjgoKSkgewogICAgICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWRTdHJpbmdfID0gczsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGphdmEubGFuZy5TdHJpbmcpIHJlZjsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF91bnJlZGFjdGVkX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBmb3Igb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgICAgZ2V0T3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nQnl0ZXMoKSB7CiAgICAgICAgamF2YS5sYW5nLk9iamVjdCByZWYgPSBvcHRpb25hbFVucmVkYWN0ZWRTdHJpbmdfOwogICAgICAgIGlmIChyZWYgaW5zdGFuY2VvZiBTdHJpbmcpIHsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBiID0gCiAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNvcHlGcm9tVXRmOCgKICAgICAgICAgICAgICAgICAgKGphdmEubGFuZy5TdHJpbmcpIHJlZik7CiAgICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWRTdHJpbmdfID0gYjsKICAgICAgICAgIHJldHVybiBiOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gKGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZykgcmVmOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3VucmVkYWN0ZWRfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgc3RyaW5nIG9wdGlvbmFsX3VucmVkYWN0ZWRfc3RyaW5nID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nKCkgewogICAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZFN0cmluZ18gPSBnZXREZWZhdWx0SW5zdGFuY2UoKS5nZXRPcHRpb25hbFVucmVkYWN0ZWRTdHJpbmcoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIHN0cmluZyBvcHRpb25hbF91bnJlZGFjdGVkX3N0cmluZyA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIGZvciBvcHRpb25hbFVucmVkYWN0ZWRTdHJpbmcgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRPcHRpb25hbFVucmVkYWN0ZWRTdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxVbnJlZGFjdGVkU3RyaW5nXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRSZWRhY3RlZFN0cmluZ18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRSZWRhY3RlZFN0cmluZ0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkU3RyaW5nXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRSZWRhY3RlZFN0cmluZ18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9yZWRhY3RlZF9zdHJpbmcgPSAzIFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkUmVkYWN0ZWRTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdMaXN0KCkgewogICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRSZWRhY3RlZFN0cmluZ187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9yZWRhY3RlZF9zdHJpbmcgPSAzIFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkUmVkYWN0ZWRTdHJpbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRSZWRhY3RlZFN0cmluZ18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfcmVkYWN0ZWRfc3RyaW5nID0gMyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRSZWRhY3RlZFN0cmluZyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFJlZGFjdGVkU3RyaW5nKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFJlZGFjdGVkU3RyaW5nXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfcmVkYWN0ZWRfc3RyaW5nID0gMyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFJlZGFjdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRSZWRhY3RlZFN0cmluZ18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9yZWRhY3RlZF9zdHJpbmcgPSAzIFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFJlZGFjdGVkU3RyaW5nIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRSZWRhY3RlZFN0cmluZygKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRSZWRhY3RlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3JlZGFjdGVkX3N0cmluZyA9IDMgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFJlZGFjdGVkU3RyaW5nIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRSZWRhY3RlZFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFJlZGFjdGVkU3RyaW5nXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3JlZGFjdGVkX3N0cmluZyA9IDMgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRSZWRhY3RlZFN0cmluZyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkUmVkYWN0ZWRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRSZWRhY3RlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFJlZGFjdGVkU3RyaW5nXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfcmVkYWN0ZWRfc3RyaW5nID0gMyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkUmVkYWN0ZWRTdHJpbmcoKSB7CiAgICAgICAgcmVwZWF0ZWRSZWRhY3RlZFN0cmluZ18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9yZWRhY3RlZF9zdHJpbmcgPSAzIFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkUmVkYWN0ZWRTdHJpbmcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFJlZGFjdGVkU3RyaW5nQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkUmVkYWN0ZWRTdHJpbmdJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFJlZGFjdGVkU3RyaW5nXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfdW5yZWRhY3RlZF9zdHJpbmcgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdMaXN0KCkgewogICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfdW5yZWRhY3RlZF9zdHJpbmcgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF91bnJlZGFjdGVkX3N0cmluZyA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfdW5yZWRhY3RlZF9zdHJpbmcgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ0J5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfdW5yZWRhY3RlZF9zdHJpbmcgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZygKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF91bnJlZGFjdGVkX3N0cmluZyA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ18uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF91bnJlZGFjdGVkX3N0cmluZyA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ18pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3VucmVkYWN0ZWRfc3RyaW5nID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nKCkgewogICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZ18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF91bnJlZGFjdGVkX3N0cmluZyA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFVucmVkYWN0ZWRTdHJpbmdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkU3RyaW5nXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uT3JCdWlsZGVyPiBvcHRpb25hbFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIG9wdGlvbmFsX3JlZGFjdGVkX21lc3NhZ2UgPSA1IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2UgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMTApICE9IDApOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxfcmVkYWN0ZWRfbWVzc2FnZSA9IDUgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBnZXRPcHRpb25hbFJlZGFjdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VfID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlKCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxfcmVkYWN0ZWRfbWVzc2FnZSA9IDUgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBvcHRpb25hbF9yZWRhY3RlZF9tZXNzYWdlID0gNSBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2UoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIG9wdGlvbmFsX3JlZGFjdGVkX21lc3NhZ2UgPSA1IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gdmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAxMCkgIT0gMCkgJiYKICAgICAgICAgICAgb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VfICE9IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHsKICAgICAgICAgICAgZ2V0T3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyKCkubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGlmIChvcHRpb25hbFJlZGFjdGVkTWVzc2FnZV8gIT0gbnVsbCkgewogICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxfcmVkYWN0ZWRfbWVzc2FnZSA9IDUgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2UoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMTApOwogICAgICAgIG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5kaXNwb3NlKCk7CiAgICAgICAgICBvcHRpb25hbFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBvcHRpb25hbF9yZWRhY3RlZF9tZXNzYWdlID0gNSBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uQnVpbGRlciBnZXRPcHRpb25hbFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbFJlZGFjdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIG9wdGlvbmFsX3JlZGFjdGVkX21lc3NhZ2UgPSA1IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbk9yQnVpbGRlciBnZXRPcHRpb25hbFJlZGFjdGVkTWVzc2FnZU9yQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFJlZGFjdGVkTWVzc2FnZV8gPT0gbnVsbCA/CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlXzsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBvcHRpb25hbF9yZWRhY3RlZF9tZXNzYWdlID0gNSBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uT3JCdWlsZGVyPiAKICAgICAgICAgIGdldE9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5TaW5nbGVGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25PckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICBnZXRPcHRpb25hbFJlZGFjdGVkTWVzc2FnZSgpLAogICAgICAgICAgICAgICAgICBnZXRQYXJlbnRGb3JDaGlsZHJlbigpLAogICAgICAgICAgICAgICAgICBpc0NsZWFuKCkpOwogICAgICAgICAgb3B0aW9uYWxSZWRhY3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uT3JCdWlsZGVyPiBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxfdW5yZWRhY3RlZF9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDIwKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIG9wdGlvbmFsX3VucmVkYWN0ZWRfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlLgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gZ2V0T3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAob3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlXyA9PSBudWxsID8gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSA6IG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VfOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBvcHRpb25hbF91bnJlZGFjdGVkX21lc3NhZ2UgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldE9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIG9wdGlvbmFsX3VucmVkYWN0ZWRfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZSgKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAob3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VfID0gYnVpbGRlckZvclZhbHVlLmJ1aWxkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxfdW5yZWRhY3RlZF9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZU9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiB2YWx1ZSkgewogICAgICAgIGlmIChvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApICYmCiAgICAgICAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VfICE9IG51bGwgJiYKICAgICAgICAgICAgb3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZV8gIT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSkgewogICAgICAgICAgICBnZXRPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcigpLm1lcmdlRnJvbSh2YWx1ZSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlXyA9IHZhbHVlOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8ubWVyZ2VGcm9tKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgaWYgKG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VfICE9IG51bGwpIHsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIG9wdGlvbmFsX3VucmVkYWN0ZWRfbWVzc2FnZSA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTsKICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgaWYgKG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uZGlzcG9zZSgpOwogICAgICAgICAgb3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiBvcHRpb25hbF91bnJlZGFjdGVkX21lc3NhZ2UgPSA2OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLkJ1aWxkZXIgZ2V0T3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBnZXRPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlcigpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxfdW5yZWRhY3RlZF9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbk9yQnVpbGRlciBnZXRPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlT3JCdWlsZGVyKCkgewogICAgICAgIGlmIChvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gIT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBvcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlXyA9PSBudWxsID8KICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLmdldERlZmF1bHRJbnN0YW5jZSgpIDogb3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZV87CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gb3B0aW9uYWxfdW5yZWRhY3RlZF9tZXNzYWdlID0gNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuU2luZ2xlRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25PckJ1aWxkZXI+IAogICAgICAgICAgZ2V0T3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpIHsKICAgICAgICBpZiAob3B0aW9uYWxVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLlNpbmdsZUZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24sIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbk9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIGdldE9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2UoKSwKICAgICAgICAgICAgICAgICAgZ2V0UGFyZW50Rm9yQ2hpbGRyZW4oKSwKICAgICAgICAgICAgICAgICAgaXNDbGVhbigpKTsKICAgICAgICAgIG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VfID0gbnVsbDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uPiByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8gPQogICAgICAgIGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgcHJpdmF0ZSB2b2lkIGVuc3VyZVJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24+KHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXyk7CiAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgIH0KICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLlJlcGVhdGVkRmllbGRCdWlsZGVyVjM8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25PckJ1aWxkZXI+IHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl87CgogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3JlZGFjdGVkX21lc3NhZ2UgPSA3IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbj4gZ2V0UmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VMaXN0KCkgewogICAgICAgIGlmIChyZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlTGlzdCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3JlZGFjdGVkX21lc3NhZ2UgPSA3IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQ291bnQoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXy5zaXplKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmdldENvdW50KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfcmVkYWN0ZWRfbWVzc2FnZSA9IDcgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIGdldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlKGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8uZ2V0KGluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZShpbmRleCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfcmVkYWN0ZWRfbWVzc2FnZSA9IDcgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3JlZGFjdGVkX21lc3NhZ2UgPSA3IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZFJlZGFjdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5zZXRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfcmVkYWN0ZWRfbWVzc2FnZSA9IDcgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICAgIH0KICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8uYWRkKHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UodmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3JlZGFjdGVkX21lc3NhZ2UgPSA3IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFJlZGFjdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXy5hZGQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF9yZWRhY3RlZF9tZXNzYWdlID0gNyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2UoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkTWVzc2FnZShidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfcmVkYWN0ZWRfbWVzc2FnZSA9IDcgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlKAogICAgICAgICAgaW50IGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXy5hZGQoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF9yZWRhY3RlZF9tZXNzYWdlID0gNyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkQWxsUmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2UoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24+IHZhbHVlcykgewogICAgICAgIGlmIChyZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0TWVzc2FnZUxpdGUuQnVpbGRlci5hZGRBbGwoCiAgICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8pOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF9yZWRhY3RlZF9tZXNzYWdlID0gNyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJSZXBlYXRlZFJlZGFjdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8gPSBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDA0MCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3JlZGFjdGVkX21lc3NhZ2UgPSA3IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVSZXBlYXRlZFJlZGFjdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5yZW1vdmUoaW5kZXgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3JlZGFjdGVkX21lc3NhZ2UgPSA3IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5CdWlsZGVyIGdldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmdldEJ1aWxkZXIoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfcmVkYWN0ZWRfbWVzc2FnZSA9IDcgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uT3JCdWlsZGVyIGdldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlT3JCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgaWYgKHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOyAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXIoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3JlZGFjdGVkX21lc3NhZ2UgPSA3IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8PyBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25PckJ1aWxkZXI+IAogICAgICAgICAgIGdldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyTGlzdCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZUxpc3QocmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VfKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF9yZWRhY3RlZF9tZXNzYWdlID0gNyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uQnVpbGRlciBhZGRSZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXIoKSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF9yZWRhY3RlZF9tZXNzYWdlID0gNyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uQnVpbGRlciBhZGRSZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5hZGRCdWlsZGVyKAogICAgICAgICAgICBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF9yZWRhY3RlZF9tZXNzYWdlID0gNyBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyTGlzdCgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyTGlzdCgpOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5CdWlsZGVyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uT3JCdWlsZGVyPiAKICAgICAgICAgIGdldFJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXBlYXRlZFJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5SZXBlYXRlZEZpZWxkQnVpbGRlclYzPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24sIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbk9yQnVpbGRlcj4oCiAgICAgICAgICAgICAgICAgIHJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXBlYXRlZFJlZGFjdGVkTWVzc2FnZV8gPSBudWxsOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVwZWF0ZWRSZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXzsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uPiByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXyA9CiAgICAgICAgamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoISgoYml0RmllbGQwXyAmIDB4MDAwMDAwODApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXyA9IG5ldyBqYXZhLnV0aWwuQXJyYXlMaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24+KHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgfQogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24sIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbk9yQnVpbGRlcj4gcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uPiBnZXRSZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlTGlzdCgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uZ2V0TWVzc2FnZUxpc3QoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUNvdW50KCkgewogICAgICAgIGlmIChyZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfLnNpemUoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRDb3VudCgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3VucmVkYWN0ZWRfbWVzc2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXy5nZXQoaW5kZXgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2UoaW5kZXgpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3VucmVkYWN0ZWRfbWVzc2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uc2V0TWVzc2FnZShpbmRleCwgdmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3VucmVkYWN0ZWRfbWVzc2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZSgKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5CdWlsZGVyIGJ1aWxkZXJGb3JWYWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZV8uc2V0KGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLnNldE1lc3NhZ2UoaW5kZXgsIGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2UocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiB2YWx1ZSkgewogICAgICAgIGlmIChyZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXy5hZGQodmFsdWUpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gdmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgZW5zdXJlUmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUlzTXV0YWJsZSgpOwogICAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZV8uYWRkKGluZGV4LCB2YWx1ZSk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmFkZE1lc3NhZ2UoaW5kZXgsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2UoCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLkJ1aWxkZXIgYnVpbGRlckZvclZhbHVlKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyA9PSBudWxsKSB7CiAgICAgICAgICBlbnN1cmVSZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlSXNNdXRhYmxlKCk7CiAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXy5hZGQoYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGJ1aWxkZXJGb3JWYWx1ZS5idWlsZCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2UoCiAgICAgICAgICBpbnQgaW5kZXgsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uQnVpbGRlciBidWlsZGVyRm9yVmFsdWUpIHsKICAgICAgICBpZiAocmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfLmFkZChpbmRleCwgYnVpbGRlckZvclZhbHVlLmJ1aWxkKCkpOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5hZGRNZXNzYWdlKGluZGV4LCBidWlsZGVyRm9yVmFsdWUuYnVpbGQoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfdW5yZWRhY3RlZF9tZXNzYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uPiB2YWx1ZXMpIHsKICAgICAgICBpZiAocmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8uYWRkQWxsTWVzc2FnZXModmFsdWVzKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZSgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwODApOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5jbGVhcigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3VucmVkYWN0ZWRfbWVzc2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlUmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZShpbnQgaW5kZXgpIHsKICAgICAgICBpZiAocmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID09IG51bGwpIHsKICAgICAgICAgIGVuc3VyZVJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VJc011dGFibGUoKTsKICAgICAgICAgIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfLnJlbW92ZShpbmRleCk7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLnJlbW92ZShpbmRleCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfdW5yZWRhY3RlZF9tZXNzYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5CdWlsZGVyIGdldFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyKAogICAgICAgICAgaW50IGluZGV4KSB7CiAgICAgICAgcmV0dXJuIGdldFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VGaWVsZEJ1aWxkZXIoKS5nZXRCdWlsZGVyKGluZGV4KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3VucmVkYWN0ZWRfbWVzc2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25PckJ1aWxkZXIgZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZU9yQnVpbGRlcigKICAgICAgICAgIGludCBpbmRleCkgewogICAgICAgIGlmIChyZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VfLmdldChpbmRleCk7ICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXy5nZXRNZXNzYWdlT3JCdWlsZGVyKGluZGV4KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDw/IGV4dGVuZHMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbk9yQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZU9yQnVpbGRlckxpc3QoKSB7CiAgICAgICAgaWYgKHJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyXyAhPSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfLmdldE1lc3NhZ2VPckJ1aWxkZXJMaXN0KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlTGlzdChyZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXyk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24gcmVwZWF0ZWRfdW5yZWRhY3RlZF9tZXNzYWdlID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5CdWlsZGVyIGFkZFJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2VCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuYWRkQnVpbGRlcigKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbiByZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2UgPSA4OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLkJ1aWxkZXIgYWRkUmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXIoCiAgICAgICAgICBpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUZpZWxkQnVpbGRlcigpLmFkZEJ1aWxkZXIoCiAgICAgICAgICAgIGluZGV4LCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uIHJlcGVhdGVkX3VucmVkYWN0ZWRfbWVzc2FnZSA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uQnVpbGRlcj4gCiAgICAgICAgICAgZ2V0UmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJMaXN0KCkgewogICAgICAgIHJldHVybiBnZXRSZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkuZ2V0QnVpbGRlckxpc3QoKTsKICAgICAgfQogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24sIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb24uQnVpbGRlciwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbk9yQnVpbGRlcj4gCiAgICAgICAgICBnZXRSZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlRmllbGRCdWlsZGVyKCkgewogICAgICAgIGlmIChyZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl8gPT0gbnVsbCkgewogICAgICAgICAgcmVwZWF0ZWRVbnJlZGFjdGVkTWVzc2FnZUJ1aWxkZXJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuUmVwZWF0ZWRGaWVsZEJ1aWxkZXJWMzwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRNZXNzYWdlUmVkYWN0aW9uLkJ1aWxkZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25PckJ1aWxkZXI+KAogICAgICAgICAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXywKICAgICAgICAgICAgICAgICAgKChiaXRGaWVsZDBfICYgMHgwMDAwMDA4MCkgIT0gMCksCiAgICAgICAgICAgICAgICAgIGdldFBhcmVudEZvckNoaWxkcmVuKCksCiAgICAgICAgICAgICAgICAgIGlzQ2xlYW4oKSk7CiAgICAgICAgICByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlXyA9IG51bGw7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXBlYXRlZFVucmVkYWN0ZWRNZXNzYWdlQnVpbGRlcl87CiAgICAgIH0KCiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcFJlZGFjdGVkU3RyaW5nXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFJlZGFjdGVkU3RyaW5nKCkgewogICAgICAgIGlmIChtYXBSZWRhY3RlZFN0cmluZ18gPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQuZW1wdHlNYXBGaWVsZCgKICAgICAgICAgICAgICBNYXBSZWRhY3RlZFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwUmVkYWN0ZWRTdHJpbmdfOwogICAgICB9CiAgICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5NYXBGaWVsZDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwUmVkYWN0ZWRTdHJpbmcoKSB7CiAgICAgICAgaWYgKG1hcFJlZGFjdGVkU3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBSZWRhY3RlZFN0cmluZ18gPSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLm5ld01hcEZpZWxkKAogICAgICAgICAgICAgIE1hcFJlZGFjdGVkU3RyaW5nRGVmYXVsdEVudHJ5SG9sZGVyLmRlZmF1bHRFbnRyeSk7CiAgICAgICAgfQogICAgICAgIGlmICghbWFwUmVkYWN0ZWRTdHJpbmdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBSZWRhY3RlZFN0cmluZ18gPSBtYXBSZWRhY3RlZFN0cmluZ18uY29weSgpOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIG1hcFJlZGFjdGVkU3RyaW5nXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcFJlZGFjdGVkU3RyaW5nQ291bnQoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKS5nZXRNYXAoKS5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3JlZGFjdGVkX3N0cmluZyA9IDkgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBSZWRhY3RlZFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKS5nZXRNYXAoKS5jb250YWluc0tleShrZXkpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2Uge0BsaW5rICNnZXRNYXBSZWRhY3RlZFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0TWFwUmVkYWN0ZWRTdHJpbmcoKSB7CiAgICAgICAgcmV0dXJuIGdldE1hcFJlZGFjdGVkU3RyaW5nTWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3JlZGFjdGVkX3N0cmluZyA9IDkgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0TWFwUmVkYWN0ZWRTdHJpbmdNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfcmVkYWN0ZWRfc3RyaW5nID0gOSBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRNYXBSZWRhY3RlZFN0cmluZ09yRGVmYXVsdCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5LAogICAgICAgICAgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBkZWZhdWx0VmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgICByZXR1cm4gbWFwLmNvbnRhaW5zS2V5KGtleSkgPyBtYXAuZ2V0KGtleSkgOiBkZWZhdWx0VmFsdWU7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3JlZGFjdGVkX3N0cmluZyA9IDkgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TWFwUmVkYWN0ZWRTdHJpbmdPclRocm93KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IG1hcCA9CiAgICAgICAgICAgIGludGVybmFsR2V0TWFwUmVkYWN0ZWRTdHJpbmcoKS5nZXRNYXAoKTsKICAgICAgICBpZiAoIW1hcC5jb250YWluc0tleShrZXkpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwLmdldChrZXkpOwogICAgICB9CiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyTWFwUmVkYWN0ZWRTdHJpbmcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAxMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFJlZGFjdGVkU3RyaW5nKCkuZ2V0TXV0YWJsZU1hcCgpCiAgICAgICAgICAgIC5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF9yZWRhY3RlZF9zdHJpbmcgPSA5IFtkZWJ1Z19yZWRhY3QgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciByZW1vdmVNYXBSZWRhY3RlZFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwUmVkYWN0ZWRTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnJlbW92ZShrZXkpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVc2UgYWx0ZXJuYXRlIG11dGF0aW9uIGFjY2Vzc29ycyBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBqYXZhLnV0aWwuTWFwPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBnZXRNdXRhYmxlTWFwUmVkYWN0ZWRTdHJpbmcoKSB7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiBpbnRlcm5hbEdldE11dGFibGVNYXBSZWRhY3RlZFN0cmluZygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfcmVkYWN0ZWRfc3RyaW5nID0gOSBbZGVidWdfcmVkYWN0ID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0TWFwUmVkYWN0ZWRTdHJpbmcoCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSwKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCB2YWx1ZSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwUmVkYWN0ZWRTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3JlZGFjdGVkX3N0cmluZyA9IDkgW2RlYnVnX3JlZGFjdCA9IHRydWVdOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHB1dEFsbE1hcFJlZGFjdGVkU3RyaW5nKAogICAgICAgICAgamF2YS51dGlsLk1hcDxqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiB2YWx1ZXMpIHsKICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBSZWRhY3RlZFN0cmluZygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQ8CiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLCBqYXZhLmxhbmcuU3RyaW5nPiBtYXBVbnJlZGFjdGVkU3RyaW5nXzsKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE1hcFVucmVkYWN0ZWRTdHJpbmcoKSB7CiAgICAgICAgaWYgKG1hcFVucmVkYWN0ZWRTdHJpbmdfID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkLmVtcHR5TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwVW5yZWRhY3RlZFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbWFwVW5yZWRhY3RlZFN0cmluZ187CiAgICAgIH0KICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLk1hcEZpZWxkPGphdmEubGFuZy5TdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgICBpbnRlcm5hbEdldE11dGFibGVNYXBVbnJlZGFjdGVkU3RyaW5nKCkgewogICAgICAgIGlmIChtYXBVbnJlZGFjdGVkU3RyaW5nXyA9PSBudWxsKSB7CiAgICAgICAgICBtYXBVbnJlZGFjdGVkU3RyaW5nXyA9IGNvbS5nb29nbGUucHJvdG9idWYuTWFwRmllbGQubmV3TWFwRmllbGQoCiAgICAgICAgICAgICAgTWFwVW5yZWRhY3RlZFN0cmluZ0RlZmF1bHRFbnRyeUhvbGRlci5kZWZhdWx0RW50cnkpOwogICAgICAgIH0KICAgICAgICBpZiAoIW1hcFVucmVkYWN0ZWRTdHJpbmdfLmlzTXV0YWJsZSgpKSB7CiAgICAgICAgICBtYXBVbnJlZGFjdGVkU3RyaW5nXyA9IG1hcFVucmVkYWN0ZWRTdHJpbmdfLmNvcHkoKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiBtYXBVbnJlZGFjdGVkU3RyaW5nXzsKICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE1hcFVucmVkYWN0ZWRTdHJpbmdDb3VudCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVbnJlZGFjdGVkU3RyaW5nKCkuZ2V0TWFwKCkuc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF91bnJlZGFjdGVkX3N0cmluZyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gY29udGFpbnNNYXBVbnJlZGFjdGVkU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICBpZiAoa2V5ID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAga2V5Iik7IH0KICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVbnJlZGFjdGVkU3RyaW5nKCkuZ2V0TWFwKCkuY29udGFpbnNLZXkoa2V5KTsKICAgICAgfQogICAgICAvKioKICAgICAgICogVXNlIHtAbGluayAjZ2V0TWFwVW5yZWRhY3RlZFN0cmluZ01hcCgpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0TWFwVW5yZWRhY3RlZFN0cmluZygpIHsKICAgICAgICByZXR1cm4gZ2V0TWFwVW5yZWRhY3RlZFN0cmluZ01hcCgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF91bnJlZGFjdGVkX3N0cmluZyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gZ2V0TWFwVW5yZWRhY3RlZFN0cmluZ01hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNYXBVbnJlZGFjdGVkU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3VucmVkYWN0ZWRfc3RyaW5nID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgLyogbnVsbGFibGUgKi8KamF2YS5sYW5nLlN0cmluZyBnZXRNYXBVbnJlZGFjdGVkU3RyaW5nT3JEZWZhdWx0KAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICAvKiBudWxsYWJsZSAqLwpqYXZhLmxhbmcuU3RyaW5nIGRlZmF1bHRWYWx1ZSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBVbnJlZGFjdGVkU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgcmV0dXJuIG1hcC5jb250YWluc0tleShrZXkpID8gbWFwLmdldChrZXkpIDogZGVmYXVsdFZhbHVlOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5tYXAmbHQ7c3RyaW5nLCBzdHJpbmcmZ3Q7IG1hcF91bnJlZGFjdGVkX3N0cmluZyA9IDEwOzwvY29kZT4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TWFwVW5yZWRhY3RlZFN0cmluZ09yVGhyb3coCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIGlmIChrZXkgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm1hcCBrZXkiKTsgfQogICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbWFwID0KICAgICAgICAgICAgaW50ZXJuYWxHZXRNYXBVbnJlZGFjdGVkU3RyaW5nKCkuZ2V0TWFwKCk7CiAgICAgICAgaWYgKCFtYXAuY29udGFpbnNLZXkoa2V5KSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1hcC5nZXQoa2V5KTsKICAgICAgfQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck1hcFVucmVkYWN0ZWRTdHJpbmcoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAyMDApOwogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFVucmVkYWN0ZWRTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLmNsZWFyKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3VucmVkYWN0ZWRfc3RyaW5nID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcmVtb3ZlTWFwVW5yZWRhY3RlZFN0cmluZygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVW5yZWRhY3RlZFN0cmluZygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucmVtb3ZlKGtleSk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVzZSBhbHRlcm5hdGUgbXV0YXRpb24gYWNjZXNzb3JzIGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4KICAgICAgICAgIGdldE11dGFibGVNYXBVbnJlZGFjdGVkU3RyaW5nKCkgewogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICByZXR1cm4gaW50ZXJuYWxHZXRNdXRhYmxlTWFwVW5yZWRhY3RlZFN0cmluZygpLmdldE11dGFibGVNYXAoKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+bWFwJmx0O3N0cmluZywgc3RyaW5nJmd0OyBtYXBfdW5yZWRhY3RlZF9zdHJpbmcgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBwdXRNYXBVbnJlZGFjdGVkU3RyaW5nKAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZyBrZXksCiAgICAgICAgICBqYXZhLmxhbmcuU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigibWFwIGtleSIpOyB9CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJtYXAgdmFsdWUiKTsgfQogICAgICAgIGludGVybmFsR2V0TXV0YWJsZU1hcFVucmVkYWN0ZWRTdHJpbmcoKS5nZXRNdXRhYmxlTWFwKCkKICAgICAgICAgICAgLnB1dChrZXksIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm1hcCZsdDtzdHJpbmcsIHN0cmluZyZndDsgbWFwX3VucmVkYWN0ZWRfc3RyaW5nID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgcHV0QWxsTWFwVW5yZWRhY3RlZFN0cmluZygKICAgICAgICAgIGphdmEudXRpbC5NYXA8amF2YS5sYW5nLlN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgaW50ZXJuYWxHZXRNdXRhYmxlTWFwVW5yZWRhY3RlZFN0cmluZygpLmdldE11dGFibGVNYXAoKQogICAgICAgICAgICAucHV0QWxsKHZhbHVlcyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlJlZGFjdGVkRmllbGRzKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5SZWRhY3RlZEZpZWxkcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVkYWN0ZWRGaWVsZHMgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZWRhY3RlZEZpZWxkcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZWRhY3RlZEZpZWxkcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFJlZGFjdGVkRmllbGRzPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFJlZGFjdGVkRmllbGRzPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgUmVkYWN0ZWRGaWVsZHMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZWRhY3RlZEZpZWxkcz4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxSZWRhY3RlZEZpZWxkcz4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5SZWRhY3RlZEZpZWxkcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RDb3JkT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDb3JkKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPckJ1aWxkZXIgewoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXNfY29yZCA9IDEgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEJ5dGVzQ29yZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzT3B0aW9uYWxCeXRlc0NvcmQoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXNfY29yZCA9IDEgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlc0NvcmQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzQ29yZCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXNfY29yZF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9ICJoZWxsbyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEJ5dGVzQ29yZERlZmF1bHQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc09wdGlvbmFsQnl0ZXNDb3JkRGVmYXVsdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHRpb25hbF9ieXRlc19jb3JkX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gImhlbGxvIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJ5dGVzQ29yZERlZmF1bHQuCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBnZXRPcHRpb25hbEJ5dGVzQ29yZERlZmF1bHQoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdENvcmR9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0Q29yZCBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q29yZCkKICAgICAgVGVzdENvcmRPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RDb3JkLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RDb3JkKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgVGVzdENvcmQoKSB7CiAgICAgIG9wdGlvbmFsQnl0ZXNDb3JkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgb3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuYnl0ZXNEZWZhdWx0VmFsdWUoImhlbGxvIik7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVGVzdENvcmQoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q29yZF9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDb3JkX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZC5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQllURVNfQ09SRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgb3B0aW9uYWxCeXRlc0NvcmRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLkVNUFRZOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHRpb25hbF9ieXRlc19jb3JkID0gMSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIG9wdGlvbmFsQnl0ZXNDb3JkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxCeXRlc0NvcmQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXNfY29yZCA9IDEgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlc0NvcmQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T3B0aW9uYWxCeXRlc0NvcmQoKSB7CiAgICAgIHJldHVybiBvcHRpb25hbEJ5dGVzQ29yZF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQllURVNfQ09SRF9ERUZBVUxUX0ZJRUxEX05VTUJFUiA9IDI7CiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBvcHRpb25hbEJ5dGVzQ29yZERlZmF1bHRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5ieXRlc0RlZmF1bHRWYWx1ZSgiaGVsbG8iKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXNfY29yZF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9ICJoZWxsbyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBvcHRpb25hbEJ5dGVzQ29yZERlZmF1bHQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEJ5dGVzQ29yZERlZmF1bHQoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXNfY29yZF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9ICJoZWxsbyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGdldE9wdGlvbmFsQnl0ZXNDb3JkRGVmYXVsdCgpIHsKICAgICAgcmV0dXJuIG9wdGlvbmFsQnl0ZXNDb3JkRGVmYXVsdF87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVCeXRlcygxLCBvcHRpb25hbEJ5dGVzQ29yZF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUJ5dGVzKDIsIG9wdGlvbmFsQnl0ZXNDb3JkRGVmYXVsdF8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlQnl0ZXNTaXplKDEsIG9wdGlvbmFsQnl0ZXNDb3JkXyk7CiAgICAgIH0KICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApKSB7CiAgICAgICAgc2l6ZSArPSBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtCiAgICAgICAgICAuY29tcHV0ZUJ5dGVzU2l6ZSgyLCBvcHRpb25hbEJ5dGVzQ29yZERlZmF1bHRfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb3JkKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb3JkIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvcmQpIG9iajsKCiAgICAgIGlmIChoYXNPcHRpb25hbEJ5dGVzQ29yZCgpICE9IG90aGVyLmhhc09wdGlvbmFsQnl0ZXNDb3JkKCkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKGhhc09wdGlvbmFsQnl0ZXNDb3JkKCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsQnl0ZXNDb3JkKCkKICAgICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRPcHRpb25hbEJ5dGVzQ29yZCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNPcHRpb25hbEJ5dGVzQ29yZERlZmF1bHQoKSAhPSBvdGhlci5oYXNPcHRpb25hbEJ5dGVzQ29yZERlZmF1bHQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzT3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0KCkpIHsKICAgICAgICBpZiAoIWdldE9wdGlvbmFsQnl0ZXNDb3JkRGVmYXVsdCgpCiAgICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0T3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzT3B0aW9uYWxCeXRlc0NvcmQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIE9QVElPTkFMX0JZVEVTX0NPUkRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsQnl0ZXNDb3JkKCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoaGFzT3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0KCkpIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBPUFRJT05BTF9CWVRFU19DT1JEX0RFRkFVTFRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldE9wdGlvbmFsQnl0ZXNDb3JkRGVmYXVsdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvcmQgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZCBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvcmQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZCBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvcmQgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZCBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb3JkIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZCBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZCBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZCBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvcmQgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZCBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0Q29yZH0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDb3JkKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvcmRPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENvcmRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENvcmRfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZC5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZC5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvcmQubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIG9wdGlvbmFsQnl0ZXNDb3JkXyA9IGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5FTVBUWTsKICAgICAgICBvcHRpb25hbEJ5dGVzQ29yZERlZmF1bHRfID0gY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5ieXRlc0RlZmF1bHRWYWx1ZSgiaGVsbG8iKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENvcmRfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb3JkLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb3JkIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvcmQgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb3JkIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb3JkIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb3JkKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvcmQgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQub3B0aW9uYWxCeXRlc0NvcmRfID0gb3B0aW9uYWxCeXRlc0NvcmRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVzdWx0Lm9wdGlvbmFsQnl0ZXNDb3JkRGVmYXVsdF8gPSBvcHRpb25hbEJ5dGVzQ29yZERlZmF1bHRfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZCkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZClvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RDb3JkIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvcmQuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNPcHRpb25hbEJ5dGVzQ29yZCgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEJ5dGVzQ29yZChvdGhlci5nZXRPcHRpb25hbEJ5dGVzQ29yZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc09wdGlvbmFsQnl0ZXNDb3JkRGVmYXVsdCgpKSB7CiAgICAgICAgICBzZXRPcHRpb25hbEJ5dGVzQ29yZERlZmF1bHQob3RoZXIuZ2V0T3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0KCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOwogICAgICAgICAgd2hpbGUgKCFkb25lKSB7CiAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgIHN3aXRjaCAodGFnKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICBvcHRpb25hbEJ5dGVzQ29yZF8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMAogICAgICAgICAgICAgIGNhc2UgMTg6IHsKICAgICAgICAgICAgICAgIG9wdGlvbmFsQnl0ZXNDb3JkRGVmYXVsdF8gPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxOAogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBvcHRpb25hbEJ5dGVzQ29yZF8gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuRU1QVFk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHRpb25hbF9ieXRlc19jb3JkID0gMSBbY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxCeXRlc0NvcmQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNPcHRpb25hbEJ5dGVzQ29yZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzX2NvcmQgPSAxIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgb3B0aW9uYWxCeXRlc0NvcmQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T3B0aW9uYWxCeXRlc0NvcmQoKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbmFsQnl0ZXNDb3JkXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXNfY29yZCA9IDEgW2N0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG9wdGlvbmFsQnl0ZXNDb3JkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxCeXRlc0NvcmQoY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsgdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCk7IH0KICAgICAgICBvcHRpb25hbEJ5dGVzQ29yZF8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGJ5dGVzIG9wdGlvbmFsX2J5dGVzX2NvcmQgPSAxIFtjdHlwZSA9IENPUkRdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPcHRpb25hbEJ5dGVzQ29yZCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb3B0aW9uYWxCeXRlc0NvcmRfID0gZ2V0RGVmYXVsdEluc3RhbmNlKCkuZ2V0T3B0aW9uYWxCeXRlc0NvcmQoKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgb3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0XyA9IGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuYnl0ZXNEZWZhdWx0VmFsdWUoImhlbGxvIik7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHRpb25hbF9ieXRlc19jb3JkX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gImhlbGxvIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgb3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0IGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzT3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0KCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXNfY29yZF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9ICJoZWxsbyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBvcHRpb25hbEJ5dGVzQ29yZERlZmF1bHQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZ2V0T3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0KCkgewogICAgICAgIHJldHVybiBvcHRpb25hbEJ5dGVzQ29yZERlZmF1bHRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBieXRlcyBvcHRpb25hbF9ieXRlc19jb3JkX2RlZmF1bHQgPSAyIFtkZWZhdWx0ID0gImhlbGxvIiwgY3R5cGUgPSBDT1JEXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgb3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0T3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0KGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgb3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0XyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgYnl0ZXMgb3B0aW9uYWxfYnl0ZXNfY29yZF9kZWZhdWx0ID0gMiBbZGVmYXVsdCA9ICJoZWxsbyIsIGN0eXBlID0gQ09SRF07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9wdGlvbmFsQnl0ZXNDb3JkRGVmYXVsdCgpIHsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMik7CiAgICAgICAgb3B0aW9uYWxCeXRlc0NvcmREZWZhdWx0XyA9IGdldERlZmF1bHRJbnN0YW5jZSgpLmdldE9wdGlvbmFsQnl0ZXNDb3JkRGVmYXVsdCgpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDb3JkKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0Q29yZCkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdENvcmQgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZCgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZCBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RDb3JkPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RDb3JkPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdENvcmQgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0Q29yZD4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0Q29yZD4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0Q29yZCBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLk5lc3RlZEVudW0gdmFscyA9IDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHZhbHMuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLk5lc3RlZEVudW0+IGdldFZhbHNMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UuTmVzdGVkRW51bSB2YWxzID0gMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdmFscy4KICAgICAqLwogICAgaW50IGdldFZhbHNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLk5lc3RlZEVudW0gdmFscyA9IDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgdmFscyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLk5lc3RlZEVudW0gZ2V0VmFscyhpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2V9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlKQogICAgICBUZXN0UGFja2VkRW51bVNtYWxsUmFuZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UoKSB7CiAgICAgIHZhbHNfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYWNrZWRFbnVtU21hbGxSYW5nZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYWNrZWRFbnVtU21hbGxSYW5nZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5OZXN0ZWRFbnVtfQogICAgICovCiAgICBwdWJsaWMgZW51bSBOZXN0ZWRFbnVtCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgICAvKioKICAgICAgICogPGNvZGU+VU5TUEVDSUZJRUQgPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIFVOU1BFQ0lGSUVEKDApLAogICAgICAvKioKICAgICAgICogPGNvZGU+Rk9PID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBGT08oMSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CQVIgPSAyOzwvY29kZT4KICAgICAgICovCiAgICAgIEJBUigyKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBWiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQkFaKDMpLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+VU5TUEVDSUZJRUQgPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOU1BFQ0lGSUVEX1ZBTFVFID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkZPTyA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRk9PX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBUiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFSX1ZBTFVFID0gMjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkJBWiA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQkFaX1ZBTFVFID0gMzsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIFVOU1BFQ0lGSUVEOwogICAgICAgICAgY2FzZSAxOiByZXR1cm4gRk9POwogICAgICAgICAgY2FzZSAyOiByZXR1cm4gQkFSOwogICAgICAgICAgY2FzZSAzOiByZXR1cm4gQkFaOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIE5lc3RlZEVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxOZXN0ZWRFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgTmVzdGVkRW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gTmVzdGVkRW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLmdldERlc2NyaXB0b3IoKS5nZXRFbnVtVHlwZXMoKS5nZXQoMCk7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIE5lc3RlZEVudW1bXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICAgIHB1YmxpYyBzdGF0aWMgTmVzdGVkRW51bSB2YWx1ZU9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgICBwcml2YXRlIE5lc3RlZEVudW0oaW50IHZhbHVlKSB7CiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgICB9CgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoZW51bV9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UuTmVzdGVkRW51bSkKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBWQUxTX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHZhbHNfOwogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlci5Db252ZXJ0ZXI8CiAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLk5lc3RlZEVudW0+IHZhbHNfY29udmVydGVyXyA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkxpc3RBZGFwdGVyLkNvbnZlcnRlcjwKICAgICAgICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5OZXN0ZWRFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UuTmVzdGVkRW51bSBjb252ZXJ0KGphdmEubGFuZy5JbnRlZ2VyIGZyb20pIHsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLk5lc3RlZEVudW0gcmVzdWx0ID0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UuTmVzdGVkRW51bS5mb3JOdW1iZXIoZnJvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0ID09IG51bGwgPyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5OZXN0ZWRFbnVtLlVOU1BFQ0lGSUVEIDogcmVzdWx0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5OZXN0ZWRFbnVtIHZhbHMgPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB2YWxzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UuTmVzdGVkRW51bT4gZ2V0VmFsc0xpc3QoKSB7CiAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5OZXN0ZWRFbnVtPih2YWxzXywgdmFsc19jb252ZXJ0ZXJfKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5OZXN0ZWRFbnVtIHZhbHMgPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiB2YWxzLgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFZhbHNDb3VudCgpIHsKICAgICAgcmV0dXJuIHZhbHNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5OZXN0ZWRFbnVtIHZhbHMgPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHZhbHMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UuTmVzdGVkRW51bSBnZXRWYWxzKGludCBpbmRleCkgewogICAgICByZXR1cm4gdmFsc19jb252ZXJ0ZXJfLmNvbnZlcnQodmFsc18uZ2V0KGluZGV4KSk7CiAgICB9CiAgICBwcml2YXRlIGludCB2YWxzTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZTsKCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIGlmIChnZXRWYWxzTGlzdCgpLnNpemUoKSA+IDApIHsKICAgICAgICBvdXRwdXQud3JpdGVVSW50MzJOb1RhZygxMCk7CiAgICAgICAgb3V0cHV0LndyaXRlVUludDMyTm9UYWcodmFsc01lbW9pemVkU2VyaWFsaXplZFNpemUpOwogICAgICB9CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdmFsc18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBvdXRwdXQud3JpdGVFbnVtTm9UYWcodmFsc18uZ2V0KGkpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxzXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgICAuY29tcHV0ZUVudW1TaXplTm9UYWcodmFsc18uZ2V0KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBpZiAoIWdldFZhbHNMaXN0KCkuaXNFbXB0eSgpKSB7ICBzaXplICs9IDE7CiAgICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgICAgLmNvbXB1dGVVSW50MzJTaXplTm9UYWcoZGF0YVNpemUpOwogICAgICAgIH12YWxzTWVtb2l6ZWRTZXJpYWxpemVkU2l6ZSA9IGRhdGFTaXplOwogICAgICB9CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZSkgb2JqOwoKICAgICAgaWYgKCF2YWxzXy5lcXVhbHMob3RoZXIudmFsc18pKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGdldFZhbHNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFZBTFNfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIHZhbHNfLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UgcGFyc2VGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZSBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UgcHJvdG90eXBlKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgfQogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICByZXR1cm4gdGhpcyA9PSBERUZBVUxUX0lOU1RBTkNFCiAgICAgICAgICA/IG5ldyBCdWlsZGVyKCkgOiBuZXcgQnVpbGRlcigpLm1lcmdlRnJvbSh0aGlzKTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgQnVpbGRlcihwYXJlbnQpOwogICAgICByZXR1cm4gYnVpbGRlcjsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYWNrZWRFbnVtU21hbGxSYW5nZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIGJpdEZpZWxkMF8gPSAwOwogICAgICAgIHZhbHNfID0gamF2YS51dGlsLkNvbGxlY3Rpb25zLmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UodGhpcyk7CiAgICAgICAgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocmVzdWx0KTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsUmVwZWF0ZWRGaWVsZHMocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UgcmVzdWx0KSB7CiAgICAgICAgaWYgKCgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICB2YWxzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy51bm1vZGlmaWFibGVMaXN0KHZhbHNfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTsKICAgICAgICB9CiAgICAgICAgcmVzdWx0LnZhbHNfID0gdmFsc187CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlIHJlc3VsdCkgewogICAgICAgIGludCBmcm9tX2JpdEZpZWxkMF8gPSBiaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoIW90aGVyLnZhbHNfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHZhbHNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICB2YWxzXyA9IG90aGVyLnZhbHNfOwogICAgICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVWYWxzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHZhbHNfLmFkZEFsbChvdGhlci52YWxzXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgY2FzZSA4OiB7CiAgICAgICAgICAgICAgICBpbnQgdG1wUmF3ID0gaW5wdXQucmVhZEVudW0oKTsKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLk5lc3RlZEVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLk5lc3RlZEVudW0uZm9yTnVtYmVyKHRtcFJhdyk7CiAgICAgICAgICAgICAgICBpZiAodG1wVmFsdWUgPT0gbnVsbCkgewogICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgZW5zdXJlVmFsc0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgICB2YWxzXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxMDogewogICAgICAgICAgICAgICAgaW50IGxlbmd0aCA9IGlucHV0LnJlYWRSYXdWYXJpbnQzMigpOwogICAgICAgICAgICAgICAgaW50IG9sZExpbWl0ID0gaW5wdXQucHVzaExpbWl0KGxlbmd0aCk7CiAgICAgICAgICAgICAgICB3aGlsZShpbnB1dC5nZXRCeXRlc1VudGlsTGltaXQoKSA+IDApIHsKICAgICAgICAgICAgICAgICAgaW50IHRtcFJhdyA9IGlucHV0LnJlYWRFbnVtKCk7CiAgICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLk5lc3RlZEVudW0gdG1wVmFsdWUgPQogICAgICAgICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UuTmVzdGVkRW51bS5mb3JOdW1iZXIodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgaWYgKHRtcFZhbHVlID09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICBtZXJnZVVua25vd25WYXJpbnRGaWVsZCgxLCB0bXBSYXcpOwogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGVuc3VyZVZhbHNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgICAgICB2YWxzXy5hZGQodG1wUmF3KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaW5wdXQucG9wTGltaXQob2xkTGltaXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEwCiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+IHZhbHNfID0KICAgICAgICBqYXZhLnV0aWwuQ29sbGVjdGlvbnMuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVWYWxzSXNNdXRhYmxlKCkgewogICAgICAgIGlmICghKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHZhbHNfID0gbmV3IGphdmEudXRpbC5BcnJheUxpc3Q8amF2YS5sYW5nLkludGVnZXI+KHZhbHNfKTsKICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UuTmVzdGVkRW51bSB2YWxzID0gMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSB2YWxzLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLk5lc3RlZEVudW0+IGdldFZhbHNMaXN0KCkgewogICAgICAgIHJldHVybiBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5MaXN0QWRhcHRlcjwKICAgICAgICAgICAgamF2YS5sYW5nLkludGVnZXIsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLk5lc3RlZEVudW0+KHZhbHNfLCB2YWxzX2NvbnZlcnRlcl8pOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLk5lc3RlZEVudW0gdmFscyA9IDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgdmFscy4KICAgICAgICovCiAgICAgIHB1YmxpYyBpbnQgZ2V0VmFsc0NvdW50KCkgewogICAgICAgIHJldHVybiB2YWxzXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UuTmVzdGVkRW51bSB2YWxzID0gMSBbcGFja2VkID0gdHJ1ZV07PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgdmFscyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UuTmVzdGVkRW51bSBnZXRWYWxzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiB2YWxzX2NvbnZlcnRlcl8uY29udmVydCh2YWxzXy5nZXQoaW5kZXgpKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5OZXN0ZWRFbnVtIHZhbHMgPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWxzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0VmFscygKICAgICAgICAgIGludCBpbmRleCwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UuTmVzdGVkRW51bSB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsKICAgICAgICB9CiAgICAgICAgZW5zdXJlVmFsc0lzTXV0YWJsZSgpOwogICAgICAgIHZhbHNfLnNldChpbmRleCwgdmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlLk5lc3RlZEVudW0gdmFscyA9IDEgW3BhY2tlZCA9IHRydWVdOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWxzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkVmFscyhwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5OZXN0ZWRFbnVtIHZhbHVlKSB7CiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICBlbnN1cmVWYWxzSXNNdXRhYmxlKCk7CiAgICAgICAgdmFsc18uYWRkKHZhbHVlLmdldE51bWJlcigpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5OZXN0ZWRFbnVtIHZhbHMgPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZXMgVGhlIHZhbHMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxWYWxzKAogICAgICAgICAgamF2YS5sYW5nLkl0ZXJhYmxlPD8gZXh0ZW5kcyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5OZXN0ZWRFbnVtPiB2YWx1ZXMpIHsKICAgICAgICBlbnN1cmVWYWxzSXNNdXRhYmxlKCk7CiAgICAgICAgZm9yIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5OZXN0ZWRFbnVtIHZhbHVlIDogdmFsdWVzKSB7CiAgICAgICAgICB2YWxzXy5hZGQodmFsdWUuZ2V0TnVtYmVyKCkpOwogICAgICAgIH0KICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZS5OZXN0ZWRFbnVtIHZhbHMgPSAxIFtwYWNrZWQgPSB0cnVlXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyVmFscygpIHsKICAgICAgICB2YWxzXyA9IGphdmEudXRpbC5Db2xsZWN0aW9ucy5lbXB0eUxpc3QoKTsKICAgICAgICBiaXRGaWVsZDBfID0gKGJpdEZpZWxkMF8gJiB+MHgwMDAwMDAwMSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UpCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZSBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UgZ2V0RGVmYXVsdEluc3RhbmNlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0UGFja2VkRW51bVNtYWxsUmFuZ2U+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8VGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlIHBhcnNlUGFydGlhbEZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3QnVpbGRlcigpOwogICAgICAgIHRyeSB7CiAgICAgICAgICBidWlsZGVyLm1lcmdlRnJvbShpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5VbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLmFzSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKCkuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oZSkKICAgICAgICAgICAgICAuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBidWlsZGVyLmJ1aWxkUGFydGlhbCgpOwogICAgICB9CiAgICB9OwoKICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RQYWNrZWRFbnVtU21hbGxSYW5nZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBFbnVtc0ZvckJlbmNobWFya09yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5FbnVtc0ZvckJlbmNobWFyaykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuRW51bXNGb3JCZW5jaG1hcmt9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBFbnVtc0ZvckJlbmNobWFyayBleHRlbmRzCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzIGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5FbnVtc0ZvckJlbmNobWFyaykKICAgICAgRW51bXNGb3JCZW5jaG1hcmtPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEVudW1zRm9yQmVuY2htYXJrLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIEVudW1zRm9yQmVuY2htYXJrKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICBzdXBlcihidWlsZGVyKTsKICAgIH0KICAgIHByaXZhdGUgRW51bXNGb3JCZW5jaG1hcmsoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgRW51bXNGb3JCZW5jaG1hcmsoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FbnVtc0ZvckJlbmNobWFya19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0VudW1zRm9yQmVuY2htYXJrX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyay5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyay5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkVudW1zRm9yQmVuY2htYXJrLkZsYXR9CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIEZsYXQKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BMCA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQTAoMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQTEoMSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQTIoMiksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQTMoMyksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BNCA9IDQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQTQoNCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BNSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQTUoNSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BNiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQTYoNiksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BNyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQTcoNyksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BOCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQTgoOCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BOSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQTkoOSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBBMTAoMTApLAogICAgICAvKioKICAgICAgICogPGNvZGU+QTExID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQTExKDExKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkExMiA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIEExMigxMiksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqLwogICAgICBBMTMoMTMpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QTE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgQTE0KDE0KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkExNSA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIEExNSgxNSksCiAgICAgIDsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BMCA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQTBfVkFMVUUgPSAwOwogICAgICAvKioKICAgICAgICogPGNvZGU+QTEgPSAxOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEExX1ZBTFVFID0gMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkEyID0gMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBMl9WQUxVRSA9IDI7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQTNfVkFMVUUgPSAzOwogICAgICAvKioKICAgICAgICogPGNvZGU+QTQgPSA0OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEE0X1ZBTFVFID0gNDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkE1ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBNV9WQUxVRSA9IDU7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BNiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQTZfVkFMVUUgPSA2OwogICAgICAvKioKICAgICAgICogPGNvZGU+QTcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEE3X1ZBTFVFID0gNzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkE4ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBOF9WQUxVRSA9IDg7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BOSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQTlfVkFMVUUgPSA5OwogICAgICAvKioKICAgICAgICogPGNvZGU+QTEwID0gMTA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQTEwX1ZBTFVFID0gMTA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBMTFfVkFMVUUgPSAxMTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkExMiA9IDEyOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEExMl9WQUxVRSA9IDEyOwogICAgICAvKioKICAgICAgICogPGNvZGU+QTEzID0gMTM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQTEzX1ZBTFVFID0gMTM7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5BMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBMTRfVkFMVUUgPSAxNDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkExNSA9IDE1OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEExNV9WQUxVRSA9IDE1OwoKCiAgICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgRmxhdCB2YWx1ZU9mKGludCB2YWx1ZSkgewogICAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgRmxhdCBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAwOiByZXR1cm4gQTA7CiAgICAgICAgICBjYXNlIDE6IHJldHVybiBBMTsKICAgICAgICAgIGNhc2UgMjogcmV0dXJuIEEyOwogICAgICAgICAgY2FzZSAzOiByZXR1cm4gQTM7CiAgICAgICAgICBjYXNlIDQ6IHJldHVybiBBNDsKICAgICAgICAgIGNhc2UgNTogcmV0dXJuIEE1OwogICAgICAgICAgY2FzZSA2OiByZXR1cm4gQTY7CiAgICAgICAgICBjYXNlIDc6IHJldHVybiBBNzsKICAgICAgICAgIGNhc2UgODogcmV0dXJuIEE4OwogICAgICAgICAgY2FzZSA5OiByZXR1cm4gQTk7CiAgICAgICAgICBjYXNlIDEwOiByZXR1cm4gQTEwOwogICAgICAgICAgY2FzZSAxMTogcmV0dXJuIEExMTsKICAgICAgICAgIGNhc2UgMTI6IHJldHVybiBBMTI7CiAgICAgICAgICBjYXNlIDEzOiByZXR1cm4gQTEzOwogICAgICAgICAgY2FzZSAxNDogcmV0dXJuIEExNDsKICAgICAgICAgIGNhc2UgMTU6IHJldHVybiBBMTU7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxGbGF0PgogICAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgICAgfQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgICAgRmxhdD4gaW50ZXJuYWxWYWx1ZU1hcCA9CiAgICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPEZsYXQ+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBGbGF0IGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiBGbGF0LmZvck51bWJlcihudW1iZXIpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IKICAgICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpLmdldFZhbHVlcygpLmdldChvcmRpbmFsKCkpOwogICAgICB9CiAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyay5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBGbGF0W10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIEZsYXQgdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBGbGF0KGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuRW51bXNGb3JCZW5jaG1hcmsuRmxhdCkKICAgIH0KCiAgICAvKioKICAgICAqIDxwcmU+CiAgICAgKiBIYXMgYSBmZXcgaG9sZXMsIGJpdG1hcCBjYW4gYmUgdXNlZC4KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkVudW1zRm9yQmVuY2htYXJrLkFsbW9zdEZsYXR9CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIEFsbW9zdEZsYXQKICAgICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CMCA9IDA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQjAoMCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CMSA9IDE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQjEoMSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQjIoMiksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CMyA9IDM7PC9jb2RlPgogICAgICAgKi8KICAgICAgQjMoMyksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CNSA9IDU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQjUoNSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CNiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQjYoNiksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CNyA9IDc7PC9jb2RlPgogICAgICAgKi8KICAgICAgQjcoNyksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5COCA9IDg7PC9jb2RlPgogICAgICAgKi8KICAgICAgQjgoOCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5COSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQjkoOSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBCMTEoMTEpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QjEyID0gMTI7PC9jb2RlPgogICAgICAgKi8KICAgICAgQjEyKDEyKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkIxMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIEIxMygxMyksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqLwogICAgICBCMTQoMTQpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QjE1ID0gMTU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQjE1KDE1KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkIxNyA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIEIxNygxNyksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBCMTkoMTkpLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+QjAgPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEIwX1ZBTFVFID0gMDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkIxID0gMTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCMV9WQUxVRSA9IDE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CMiA9IDI7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQjJfVkFMVUUgPSAyOwogICAgICAvKioKICAgICAgICogPGNvZGU+QjMgPSAzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEIzX1ZBTFVFID0gMzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkI1ID0gNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCNV9WQUxVRSA9IDU7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CNiA9IDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQjZfVkFMVUUgPSA2OwogICAgICAvKioKICAgICAgICogPGNvZGU+QjcgPSA3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEI3X1ZBTFVFID0gNzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkI4ID0gODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCOF9WQUxVRSA9IDg7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5COSA9IDk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQjlfVkFMVUUgPSA5OwogICAgICAvKioKICAgICAgICogPGNvZGU+QjExID0gMTE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQjExX1ZBTFVFID0gMTE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCMTJfVkFMVUUgPSAxMjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkIxMyA9IDEzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEIxM19WQUxVRSA9IDEzOwogICAgICAvKioKICAgICAgICogPGNvZGU+QjE0ID0gMTQ7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQjE0X1ZBTFVFID0gMTQ7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5CMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCMTVfVkFMVUUgPSAxNTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkIxNyA9IDE3OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEIxN19WQUxVRSA9IDE3OwogICAgICAvKioKICAgICAgICogPGNvZGU+QjE5ID0gMTk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQjE5X1ZBTFVFID0gMTk7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBBbG1vc3RGbGF0IHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBBbG1vc3RGbGF0IGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICBjYXNlIDA6IHJldHVybiBCMDsKICAgICAgICAgIGNhc2UgMTogcmV0dXJuIEIxOwogICAgICAgICAgY2FzZSAyOiByZXR1cm4gQjI7CiAgICAgICAgICBjYXNlIDM6IHJldHVybiBCMzsKICAgICAgICAgIGNhc2UgNTogcmV0dXJuIEI1OwogICAgICAgICAgY2FzZSA2OiByZXR1cm4gQjY7CiAgICAgICAgICBjYXNlIDc6IHJldHVybiBCNzsKICAgICAgICAgIGNhc2UgODogcmV0dXJuIEI4OwogICAgICAgICAgY2FzZSA5OiByZXR1cm4gQjk7CiAgICAgICAgICBjYXNlIDExOiByZXR1cm4gQjExOwogICAgICAgICAgY2FzZSAxMjogcmV0dXJuIEIxMjsKICAgICAgICAgIGNhc2UgMTM6IHJldHVybiBCMTM7CiAgICAgICAgICBjYXNlIDE0OiByZXR1cm4gQjE0OwogICAgICAgICAgY2FzZSAxNTogcmV0dXJuIEIxNTsKICAgICAgICAgIGNhc2UgMTc6IHJldHVybiBCMTc7CiAgICAgICAgICBjYXNlIDE5OiByZXR1cm4gQjE5OwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8QWxtb3N0RmxhdD4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIEFsbW9zdEZsYXQ+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxBbG1vc3RGbGF0PigpIHsKICAgICAgICAgICAgICBwdWJsaWMgQWxtb3N0RmxhdCBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gQWxtb3N0RmxhdC5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmsuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgxKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQWxtb3N0RmxhdFtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgICAgcHVibGljIHN0YXRpYyBBbG1vc3RGbGF0IHZhbHVlT2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFZBTFVFU1tkZXNjLmdldEluZGV4KCldOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICAgIHByaXZhdGUgQWxtb3N0RmxhdChpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkVudW1zRm9yQmVuY2htYXJrLkFsbW9zdEZsYXQpCiAgICB9CgogICAgLyoqCiAgICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5FbnVtc0ZvckJlbmNobWFyay5TcGFyc2V9CiAgICAgKi8KICAgIHB1YmxpYyBlbnVtIFNwYXJzZQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbE1lc3NhZ2VFbnVtIHsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkM1MzYgPSA1MzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQzUzNig1MzYpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QzgzODcgPSA4Mzg3OzwvY29kZT4KICAgICAgICovCiAgICAgIEM4Mzg3KDgzODcpLAogICAgICAvKioKICAgICAgICogPGNvZGU+Qzk2NzMgPSA5NjczOzwvY29kZT4KICAgICAgICovCiAgICAgIEM5NjczKDk2NzMpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QzEwMjg1ID0gMTAyODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgQzEwMjg1KDEwMjg1KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkMxMzMxOCA9IDEzMzE4OzwvY29kZT4KICAgICAgICovCiAgICAgIEMxMzMxOCgxMzMxOCksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5DMTU5NjMgPSAxNTk2Mzs8L2NvZGU+CiAgICAgICAqLwogICAgICBDMTU5NjMoMTU5NjMpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QzE2NDM5ID0gMTY0Mzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgQzE2NDM5KDE2NDM5KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkMxODE5NyA9IDE4MTk3OzwvY29kZT4KICAgICAgICovCiAgICAgIEMxODE5NygxODE5NyksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5DMTk0MzAgPSAxOTQzMDs8L2NvZGU+CiAgICAgICAqLwogICAgICBDMTk0MzAoMTk0MzApLAogICAgICAvKioKICAgICAgICogPGNvZGU+QzIwMzYxID0gMjAzNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgQzIwMzYxKDIwMzYxKSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkMyMDcwNiA9IDIwNzA2OzwvY29kZT4KICAgICAgICovCiAgICAgIEMyMDcwNigyMDcwNiksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5DMjEwNTAgPSAyMTA1MDs8L2NvZGU+CiAgICAgICAqLwogICAgICBDMjEwNTAoMjEwNTApLAogICAgICAvKioKICAgICAgICogPGNvZGU+QzIxOTA2ID0gMjE5MDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgQzIxOTA2KDIxOTA2KSwKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkMyNzI2NSA9IDI3MjY1OzwvY29kZT4KICAgICAgICovCiAgICAgIEMyNzI2NSgyNzI2NSksCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5DMzAxMDkgPSAzMDEwOTs8L2NvZGU+CiAgICAgICAqLwogICAgICBDMzAxMDkoMzAxMDkpLAogICAgICAvKioKICAgICAgICogPGNvZGU+QzMxNjcwID0gMzE2NzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgQzMxNjcwKDMxNjcwKSwKICAgICAgOwoKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkM1MzYgPSA1MzY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQzUzNl9WQUxVRSA9IDUzNjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkM4Mzg3ID0gODM4Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDODM4N19WQUxVRSA9IDgzODc7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5DOTY3MyA9IDk2NzM7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQzk2NzNfVkFMVUUgPSA5NjczOwogICAgICAvKioKICAgICAgICogPGNvZGU+QzEwMjg1ID0gMTAyODU7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQzEwMjg1X1ZBTFVFID0gMTAyODU7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5DMTMzMTggPSAxMzMxODs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDMTMzMThfVkFMVUUgPSAxMzMxODsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkMxNTk2MyA9IDE1OTYzOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEMxNTk2M19WQUxVRSA9IDE1OTYzOwogICAgICAvKioKICAgICAgICogPGNvZGU+QzE2NDM5ID0gMTY0Mzk7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQzE2NDM5X1ZBTFVFID0gMTY0Mzk7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5DMTgxOTcgPSAxODE5Nzs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDMTgxOTdfVkFMVUUgPSAxODE5NzsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkMxOTQzMCA9IDE5NDMwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEMxOTQzMF9WQUxVRSA9IDE5NDMwOwogICAgICAvKioKICAgICAgICogPGNvZGU+QzIwMzYxID0gMjAzNjE7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQzIwMzYxX1ZBTFVFID0gMjAzNjE7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5DMjA3MDYgPSAyMDcwNjs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDMjA3MDZfVkFMVUUgPSAyMDcwNjsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkMyMTA1MCA9IDIxMDUwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEMyMTA1MF9WQUxVRSA9IDIxMDUwOwogICAgICAvKioKICAgICAgICogPGNvZGU+QzIxOTA2ID0gMjE5MDY7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQzIxOTA2X1ZBTFVFID0gMjE5MDY7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5DMjcyNjUgPSAyNzI2NTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDMjcyNjVfVkFMVUUgPSAyNzI2NTsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPkMzMDEwOSA9IDMwMTA5OzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEMzMDEwOV9WQUxVRSA9IDMwMTA5OwogICAgICAvKioKICAgICAgICogPGNvZGU+QzMxNjcwID0gMzE2NzA7PC9jb2RlPgogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQzMxNjcwX1ZBTFVFID0gMzE2NzA7CgoKICAgICAgcHVibGljIGZpbmFsIGludCBnZXROdW1iZXIoKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayAjZm9yTnVtYmVyKGludCl9IGluc3RlYWQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgICAgcHVibGljIHN0YXRpYyBTcGFyc2UgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIFNwYXJzZSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSA1MzY6IHJldHVybiBDNTM2OwogICAgICAgICAgY2FzZSA4Mzg3OiByZXR1cm4gQzgzODc7CiAgICAgICAgICBjYXNlIDk2NzM6IHJldHVybiBDOTY3MzsKICAgICAgICAgIGNhc2UgMTAyODU6IHJldHVybiBDMTAyODU7CiAgICAgICAgICBjYXNlIDEzMzE4OiByZXR1cm4gQzEzMzE4OwogICAgICAgICAgY2FzZSAxNTk2MzogcmV0dXJuIEMxNTk2MzsKICAgICAgICAgIGNhc2UgMTY0Mzk6IHJldHVybiBDMTY0Mzk7CiAgICAgICAgICBjYXNlIDE4MTk3OiByZXR1cm4gQzE4MTk3OwogICAgICAgICAgY2FzZSAxOTQzMDogcmV0dXJuIEMxOTQzMDsKICAgICAgICAgIGNhc2UgMjAzNjE6IHJldHVybiBDMjAzNjE7CiAgICAgICAgICBjYXNlIDIwNzA2OiByZXR1cm4gQzIwNzA2OwogICAgICAgICAgY2FzZSAyMTA1MDogcmV0dXJuIEMyMTA1MDsKICAgICAgICAgIGNhc2UgMjE5MDY6IHJldHVybiBDMjE5MDY7CiAgICAgICAgICBjYXNlIDI3MjY1OiByZXR1cm4gQzI3MjY1OwogICAgICAgICAgY2FzZSAzMDEwOTogcmV0dXJuIEMzMDEwOTsKICAgICAgICAgIGNhc2UgMzE2NzA6IHJldHVybiBDMzE2NzA7CiAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxTcGFyc2U+CiAgICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICAgIHJldHVybiBpbnRlcm5hbFZhbHVlTWFwOwogICAgICB9CiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgICBTcGFyc2U+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxTcGFyc2U+KCkgewogICAgICAgICAgICAgIHB1YmxpYyBTcGFyc2UgZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIFNwYXJzZS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmsuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgyKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3BhcnNlW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIFNwYXJzZSB2YWx1ZU9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yIGRlc2MpIHsKICAgICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgIkVudW1WYWx1ZURlc2NyaXB0b3IgaXMgbm90IGZvciB0aGlzIHR5cGUuIik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgICBwcml2YXRlIFNwYXJzZShpbnQgdmFsdWUpIHsKICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkVudW1zRm9yQmVuY2htYXJrLlNwYXJzZSkKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1zRm9yQmVuY2htYXJrKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1zRm9yQmVuY2htYXJrIG90aGVyID0gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmspIG9iajsKCiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaGFzaCA9ICgyOSAqIGhhc2gpICsgZ2V0VW5rbm93bkZpZWxkcygpLmhhc2hDb2RlKCk7CiAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICByZXR1cm4gaGFzaDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmsgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyayBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyayBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmsgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyayBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmsgcGFyc2VGcm9tKAogICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyayBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1zRm9yQmVuY2htYXJrIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyayBwYXJzZURlbGltaXRlZEZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyayBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyayBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmsgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBuZXdCdWlsZGVyRm9yVHlwZSgpIHsgcmV0dXJuIG5ld0J1aWxkZXIoKTsgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBCdWlsZGVyIG5ld0J1aWxkZXIocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyayBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5FbnVtc0ZvckJlbmNobWFya30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkVudW1zRm9yQmVuY2htYXJrKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmtPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRW51bXNGb3JCZW5jaG1hcmtfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRW51bXNGb3JCZW5jaG1hcmtfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyay5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyay5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmsubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FbnVtc0ZvckJlbmNobWFya19kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1zRm9yQmVuY2htYXJrIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmsuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmsgYnVpbGQoKSB7CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyayByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmsgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmsgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmsodGhpcyk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1zRm9yQmVuY2htYXJrKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1zRm9yQmVuY2htYXJrKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRW51bXNGb3JCZW5jaG1hcmsgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyay5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuRW51bXNGb3JCZW5jaG1hcmspCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkVudW1zRm9yQmVuY2htYXJrKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5FbnVtc0ZvckJlbmNobWFyayBERUZBVUxUX0lOU1RBTkNFOwogICAgc3RhdGljIHsKICAgICAgREVGQVVMVF9JTlNUQU5DRSA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1zRm9yQmVuY2htYXJrKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1zRm9yQmVuY2htYXJrIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RW51bXNGb3JCZW5jaG1hcms+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8RW51bXNGb3JCZW5jaG1hcms+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBFbnVtc0ZvckJlbmNobWFyayBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEVudW1zRm9yQmVuY2htYXJrPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEVudW1zRm9yQmVuY2htYXJrPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkVudW1zRm9yQmVuY2htYXJrIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGludGVyZmFjZV9leHRlbmRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcykKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcxLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzEuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEgPSAxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzEoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xID0gMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIgPSAyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzIoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yID0gMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmczLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nM0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzMuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMgPSAzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmczIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzMoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zID0gMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmczIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmczQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc0LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nNExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ180ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzQgPSA0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmc0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzQoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ180ID0gNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmc0Qnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc1LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nNUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ181ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzUuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzVDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzUgPSA1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmc1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzUoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ181ID0gNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmc1Qnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc2LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nNkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ182ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzYuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzYgPSA2OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmc2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzYoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ182ID0gNjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmc2Qnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc3LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nN0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ183ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzcuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzcgPSA3OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmc3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzcoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ183ID0gNzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmc3Qnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfOCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc4LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nOExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ184ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzhDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzggPSA4OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmc4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzgoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ184ID0gODs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmc4Qnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc5LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nOUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzkuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmc5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzkoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmc5Qnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzEwLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTBMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzEwLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcxMENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMTAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMTAoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMCA9IDEwOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzEwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxMEJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzExID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcxMS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzExTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzExID0gMTE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcxMS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU3RyaW5nMTFDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzExID0gMTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzExIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzExKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTEgPSAxMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcxMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTFCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTIuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxMkxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTIuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzEyQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMiA9IDEyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcxMihpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEyID0gMTI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzEyQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzEzLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTNMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzEzLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcxM0NvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMTMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMTMoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMyA9IDEzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzEzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxM0J5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE0ID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcxNC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzE0TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE0ID0gMTQ7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcxNC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU3RyaW5nMTRDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE0ID0gMTQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzE0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzE0KGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTQgPSAxNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcxNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTRCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTUuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxNUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTUuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzE1Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcxNShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzE1Qnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzE2LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTZMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzE2LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcxNkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMTYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMTYoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNiA9IDE2OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzE2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxNkJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE3ID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcxNy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzE3TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE3ID0gMTc7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcxNy4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU3RyaW5nMTdDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE3ID0gMTc7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzE3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzE3KGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTcgPSAxNzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcxNyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTdCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xOCA9IDE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTguCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxOExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xOCA9IDE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTguCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzE4Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xOCA9IDE4OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcxOChpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE4ID0gMTg7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzE4Qnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTkgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzE5LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTkgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzE5LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcxOUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTkgPSAxOTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMTkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMTkoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xOSA9IDE5OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzE5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxOUJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIwID0gMjA7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcyMC4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzIwTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIwID0gMjA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcyMC4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU3RyaW5nMjBDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIwID0gMjA7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzIwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzIwKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjAgPSAyMDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcyMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjBCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMSA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjEuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyMUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMSA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjEuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzIxQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMSA9IDIxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcyMShpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIxID0gMjE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzIxQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjIgPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzIyLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjJMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjIgPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzIyLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcyMkNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjIgPSAyMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMjIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMjIoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMiA9IDIyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzIyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyMkJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIzID0gMjM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcyMy4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzIzTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIzID0gMjM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcyMy4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU3RyaW5nMjNDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIzID0gMjM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzIzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzIzKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjMgPSAyMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcyMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjNCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNCA9IDI0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjQuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyNExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNCA9IDI0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjQuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzI0Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNCA9IDI0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcyNChpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI0ID0gMjQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzI0Qnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjUgPSAyNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzI1LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjVMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjUgPSAyNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzI1LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcyNUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjUgPSAyNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMjUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMjUoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNSA9IDI1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzI1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyNUJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI2ID0gMjY7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcyNi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzI2TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI2ID0gMjY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcyNi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU3RyaW5nMjZDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI2ID0gMjY7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzI2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzI2KGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjYgPSAyNjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcyNiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjZCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNyA9IDI3OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjcuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyN0xpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNyA9IDI3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjcuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzI3Q291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNyA9IDI3OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyNyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcyNyhpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI3ID0gMjc7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzI3Qnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjggPSAyODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzI4LgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjhMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjggPSAyODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzI4LgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcyOENvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjggPSAyODs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMjggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMjgoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yOCA9IDI4OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzI4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyOEJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI5ID0gMjk7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcyOS4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzI5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI5ID0gMjk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcyOS4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU3RyaW5nMjlDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI5ID0gMjk7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzI5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzI5KGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjkgPSAyOTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcyOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjlCeXRlcyhpbnQgaW5kZXgpOwoKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMCA9IDMwOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMzAuCiAgICAgKi8KICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmczMExpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMCA9IDMwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMzAuCiAgICAgKi8KICAgIGludCBnZXRSZXBlYXRlZFN0cmluZzMwQ291bnQoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMCA9IDMwOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmczMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmczMChpbnQgaW5kZXgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMwID0gMzA7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMzAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzMwQnl0ZXMoaW50IGluZGV4KTsKCiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzEgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzMxLgogICAgICovCiAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPgogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMzFMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzEgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzMxLgogICAgICovCiAgICBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmczMUNvdW50KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzEgPSAzMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMzEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMzEoaW50IGluZGV4KTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMSA9IDMxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzMxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmczMUJ5dGVzKGludCBpbmRleCk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmczMi4KICAgICAqLwogICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4KICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzMyTGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmczMi4KICAgICAqLwogICAgaW50IGdldFJlcGVhdGVkU3RyaW5nMzJDb3VudCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzMyKGludCBpbmRleCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmczMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMzJCeXRlcyhpbnQgaW5kZXgpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHN9CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBUZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHMgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzKQogICAgICBUZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHNPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcy5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHMoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjw/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHMoKSB7CiAgICAgIHJlcGVhdGVkU3RyaW5nMV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZzJfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmczXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nNF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZzVfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmc2XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nN18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZzhfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmc5XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nMTBfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmcxMV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZzEyXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nMTNfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmcxNF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZzE1XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nMTZfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmcxN18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZzE4XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nMTlfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmcyMF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZzIxXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nMjJfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmcyM18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZzI0XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nMjVfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmcyNl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZzI3XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nMjhfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmcyOV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICByZXBlYXRlZFN0cmluZzMwXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHJlcGVhdGVkU3RyaW5nMzFfID0KICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgcmVwZWF0ZWRTdHJpbmczMl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IFRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcygpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkc19kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkc19maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcy5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfMV9GSUVMRF9OVU1CRVIgPSAxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzFfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcxLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzFMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzEuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcxQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzFfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xID0gMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xID0gMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMUJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfMl9GSUVMRF9OVU1CRVIgPSAyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzJfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMiA9IDI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcyLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yID0gMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMl8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yID0gMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMkJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfM19GSUVMRF9OVU1CRVIgPSAzOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzNfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMyA9IDM7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmczLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzNMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zID0gMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzMuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmczQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zID0gMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nM18uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zID0gMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmczIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nM0J5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfNF9GSUVMRF9OVU1CRVIgPSA0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzRfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNCA9IDQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc0LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ180ID0gNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmc0Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ180ID0gNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nNChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nNF8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ180ID0gNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nNEJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc0Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfNV9GSUVMRF9OVU1CRVIgPSA1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzVfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNSA9IDU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc1LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzVMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc1XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ181ID0gNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmc1Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzVfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ181ID0gNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nNShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nNV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ181ID0gNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nNUJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc1Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfNl9GSUVMRF9OVU1CRVIgPSA2OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzZfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNiA9IDY7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc2LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzZMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc2XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ182ID0gNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzYuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmc2Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzZfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ182ID0gNjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nNiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nNihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nNl8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ182ID0gNjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nNkJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc2Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfN19GSUVMRF9OVU1CRVIgPSA3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzdfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNyA9IDc7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc3LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzdMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc3XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ183ID0gNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzcuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmc3Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzdfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ183ID0gNzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nNyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nNyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nN18uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ183ID0gNzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nN0J5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc3Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfOF9GSUVMRF9OVU1CRVIgPSA4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzhfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfOCA9IDg7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzhMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc4XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ184ID0gODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmc4Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzhfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ184ID0gODs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nOChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nOF8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ184ID0gODs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nOEJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc4Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfOV9GSUVMRF9OVU1CRVIgPSA5OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzlfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc5LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzlMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc5XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzkuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmc5Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzlfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nOShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nOV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nOUJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc5Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfMTBfRklFTERfTlVNQkVSID0gMTA7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nMTBfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzEwLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzEwTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMTBfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEwID0gMTA7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcxMC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzEwQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzEwXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTAgPSAxMDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMTAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzEwKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxMF8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMCA9IDEwOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzEwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTBCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMTBfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR18xMV9GSUVMRF9OVU1CRVIgPSAxMTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxMV8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMSA9IDExOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTEuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTFMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxMV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTEgPSAxMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzExLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMTFDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMTFfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMSA9IDExOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMTEoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzExXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzExID0gMTE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxMUJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxMV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HXzEyX0ZJRUxEX05VTUJFUiA9IDEyOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzEyXyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEyID0gMTI7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcxMi4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxMkxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzEyXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMiA9IDEyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTIuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcxMkNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxMl8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEyID0gMTI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzEyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcxMihpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMTJfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTIgPSAxMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcxMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzEyQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzEyXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfMTNfRklFTERfTlVNQkVSID0gMTM7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nMTNfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzEzLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzEzTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMTNfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEzID0gMTM7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcxMy4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzEzQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzEzXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTMgPSAxMzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMTMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzEzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxM18uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMyA9IDEzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzEzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTNCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMTNfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR18xNF9GSUVMRF9OVU1CRVIgPSAxNDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxNF8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNCA9IDE0OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTQuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTRMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxNF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTQgPSAxNDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzE0LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMTRDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMTRfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNCA9IDE0OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMTQoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE0Xy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE0ID0gMTQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTQgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxNEJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxNF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HXzE1X0ZJRUxEX05VTUJFUiA9IDE1OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzE1XyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcxNS4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxNUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE1XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTUuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcxNUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxNV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzE1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcxNShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMTVfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcxNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzE1Qnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE1Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfMTZfRklFTERfTlVNQkVSID0gMTY7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nMTZfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzE2LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzE2TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMTZfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE2ID0gMTY7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcxNi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzE2Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE2Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTYgPSAxNjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMTYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzE2KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxNl8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNiA9IDE2OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzE2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTZCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMTZfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR18xN19GSUVMRF9OVU1CRVIgPSAxNzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxN18gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNyA9IDE3OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTcuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTdMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxN187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTcgPSAxNzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzE3LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMTdDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMTdfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNyA9IDE3OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxNyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMTcoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE3Xy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE3ID0gMTc7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTcgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxN0J5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxN18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HXzE4X0ZJRUxEX05VTUJFUiA9IDE4OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzE4XyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE4ID0gMTg7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcxOC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcxOExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE4XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xOCA9IDE4OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTguCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcxOENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxOF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE4ID0gMTg7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzE4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcxOChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMThfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTggPSAxODs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcxOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzE4Qnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE4Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfMTlfRklFTERfTlVNQkVSID0gMTk7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nMTlfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTkgPSAxOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzE5LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzE5TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMTlfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE5ID0gMTk7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcxOS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzE5Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE5Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTkgPSAxOTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMTkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzE5KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxOV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xOSA9IDE5OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzE5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTlCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMTlfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR18yMF9GSUVMRF9OVU1CRVIgPSAyMDsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyMF8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMCA9IDIwOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjAuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjBMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyMF87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjAgPSAyMDs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzIwLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjBDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMjBfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMCA9IDIwOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMjAoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzIwXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIwID0gMjA7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjAgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyMEJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyMF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HXzIxX0ZJRUxEX05VTUJFUiA9IDIxOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzIxXyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIxID0gMjE7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcyMS4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyMUxpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzIxXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMSA9IDIxOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjEuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcyMUNvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyMV8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIxID0gMjE7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzIxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcyMShpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMjFfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjEgPSAyMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcyMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzIxQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzIxXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfMjJfRklFTERfTlVNQkVSID0gMjI7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nMjJfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjIgPSAyMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzIyLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzIyTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMjJfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIyID0gMjI7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcyMi4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzIyQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzIyXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjIgPSAyMjs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMjIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzIyKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyMl8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMiA9IDIyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzIyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjJCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMjJfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR18yM19GSUVMRF9OVU1CRVIgPSAyMzsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyM18gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMyA9IDIzOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjMuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjNMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyM187CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjMgPSAyMzs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzIzLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjNDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMjNfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMyA9IDIzOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMjMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzIzXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIzID0gMjM7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjMgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyM0J5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyM18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HXzI0X0ZJRUxEX05VTUJFUiA9IDI0OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzI0XyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI0ID0gMjQ7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcyNC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyNExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI0XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNCA9IDI0OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjQuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcyNENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyNF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI0ID0gMjQ7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzI0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcyNChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMjRfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjQgPSAyNDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcyNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzI0Qnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI0Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfMjVfRklFTERfTlVNQkVSID0gMjU7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nMjVfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjUgPSAyNTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzI1LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzI1TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMjVfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI1ID0gMjU7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcyNS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzI1Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI1Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjUgPSAyNTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMjUgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzI1KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyNV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNSA9IDI1OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzI1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjVCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMjVfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR18yNl9GSUVMRF9OVU1CRVIgPSAyNjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyNl8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNiA9IDI2OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjYuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjZMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyNl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjYgPSAyNjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzI2LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjZDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMjZfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNiA9IDI2OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyNiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMjYoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI2Xy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI2ID0gMjY7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjYgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyNkJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyNl8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HXzI3X0ZJRUxEX05VTUJFUiA9IDI3OwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzI3XyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI3ID0gMjc7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcyNy4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyN0xpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI3XzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNyA9IDI3OzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjcuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmcyN0NvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyN18uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI3ID0gMjc7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzI3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmcyNyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMjdfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjcgPSAyNzs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcyNyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzI3Qnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI3Xy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfMjhfRklFTERfTlVNQkVSID0gMjg7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nMjhfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjggPSAyODs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzI4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzI4TGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMjhfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI4ID0gMjg7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcyOC4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzI4Q291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI4Xy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjggPSAyODs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMjggYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzI4KGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyOF8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yOCA9IDI4OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzI4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjhCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMjhfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR18yOV9GSUVMRF9OVU1CRVIgPSAyOTsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyOV8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yOSA9IDI5OzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjkuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjlMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyOV87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjkgPSAyOTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzI5LgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjlDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMjlfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yOSA9IDI5OzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMjkoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI5Xy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI5ID0gMjk7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjkgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmcyOUJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyOV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU1RSSU5HXzMwX0ZJRUxEX05VTUJFUiA9IDMwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdCByZXBlYXRlZFN0cmluZzMwXyA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMwID0gMzA7PC9jb2RlPgogICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmczMC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmczMExpc3QoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzMwXzsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMCA9IDMwOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMzAuCiAgICAgKi8KICAgIHB1YmxpYyBpbnQgZ2V0UmVwZWF0ZWRTdHJpbmczMENvdW50KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczMF8uc2l6ZSgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMwID0gMzA7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSByZXBlYXRlZFN0cmluZzMwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVwZWF0ZWRTdHJpbmczMChpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMzBfLmdldChpbmRleCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzAgPSAzMDs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmczMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzMwQnl0ZXMoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzMwXy5nZXRCeXRlU3RyaW5nKGluZGV4KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfMzFfRklFTERfTlVNQkVSID0gMzE7CiAgICBAU3VwcHJlc3NXYXJuaW5ncygic2VyaWFsIikKICAgIHByaXZhdGUgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0IHJlcGVhdGVkU3RyaW5nMzFfID0KICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzEgPSAzMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgbGlzdCBjb250YWluaW5nIHRoZSByZXBlYXRlZFN0cmluZzMxLgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzMxTGlzdCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMzFfOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMxID0gMzE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmczMS4KICAgICAqLwogICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzMxQ291bnQoKSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzMxXy5zaXplKCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzEgPSAzMTs8L2NvZGU+CiAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIHJlcGVhdGVkU3RyaW5nMzEgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzMxKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczMV8uZ2V0KGluZGV4KTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMSA9IDMxOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIHZhbHVlIHRvIHJldHVybi4KICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzMxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAqLwogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZwogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMzFCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMzFfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR18zMl9GSUVMRF9OVU1CRVIgPSAzMjsKICAgIEBTdXBwcmVzc1dhcm5pbmdzKCJzZXJpYWwiKQogICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmczMl8gPQogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMzIuCiAgICAgKi8KICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sU3RyaW5nTGlzdAogICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMzJMaXN0KCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczMl87CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBjb3VudCBvZiByZXBlYXRlZFN0cmluZzMyLgogICAgICovCiAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMzJDb3VudCgpIHsKICAgICAgcmV0dXJuIHJlcGVhdGVkU3RyaW5nMzJfLnNpemUoKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmczMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgKi8KICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMzIoaW50IGluZGV4KSB7CiAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzMyXy5nZXQoaW5kZXgpOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICogQHJldHVybiBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMzIgYXQgdGhlIGdpdmVuIGluZGV4LgogICAgICovCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nCiAgICAgICAgZ2V0UmVwZWF0ZWRTdHJpbmczMkJ5dGVzKGludCBpbmRleCkgewogICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczMl8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDEsIHJlcGVhdGVkU3RyaW5nMV8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDIsIHJlcGVhdGVkU3RyaW5nMl8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nM18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDMsIHJlcGVhdGVkU3RyaW5nM18uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nNF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDQsIHJlcGVhdGVkU3RyaW5nNF8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nNV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDUsIHJlcGVhdGVkU3RyaW5nNV8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nNl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDYsIHJlcGVhdGVkU3RyaW5nNl8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nN18uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDcsIHJlcGVhdGVkU3RyaW5nN18uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nOF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDgsIHJlcGVhdGVkU3RyaW5nOF8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nOV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy53cml0ZVN0cmluZyhvdXRwdXQsIDksIHJlcGVhdGVkU3RyaW5nOV8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMTBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMCwgcmVwZWF0ZWRTdHJpbmcxMF8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMTFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMSwgcmVwZWF0ZWRTdHJpbmcxMV8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMTJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMiwgcmVwZWF0ZWRTdHJpbmcxMl8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMTNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxMywgcmVwZWF0ZWRTdHJpbmcxM18uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMTRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxNCwgcmVwZWF0ZWRTdHJpbmcxNF8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMTVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxNSwgcmVwZWF0ZWRTdHJpbmcxNV8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMTZfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxNiwgcmVwZWF0ZWRTdHJpbmcxNl8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMTdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxNywgcmVwZWF0ZWRTdHJpbmcxN18uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMThfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxOCwgcmVwZWF0ZWRTdHJpbmcxOF8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMTlfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAxOSwgcmVwZWF0ZWRTdHJpbmcxOV8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMjBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyMCwgcmVwZWF0ZWRTdHJpbmcyMF8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMjFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyMSwgcmVwZWF0ZWRTdHJpbmcyMV8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMjJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyMiwgcmVwZWF0ZWRTdHJpbmcyMl8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMjNfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyMywgcmVwZWF0ZWRTdHJpbmcyM18uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyNCwgcmVwZWF0ZWRTdHJpbmcyNF8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMjVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyNSwgcmVwZWF0ZWRTdHJpbmcyNV8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMjZfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyNiwgcmVwZWF0ZWRTdHJpbmcyNl8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMjdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyNywgcmVwZWF0ZWRTdHJpbmcyN18uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMjhfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyOCwgcmVwZWF0ZWRTdHJpbmcyOF8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMjlfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAyOSwgcmVwZWF0ZWRTdHJpbmcyOV8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMzBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAzMCwgcmVwZWF0ZWRTdHJpbmczMF8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMzFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAzMSwgcmVwZWF0ZWRTdHJpbmczMV8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMzJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMud3JpdGVTdHJpbmcob3V0cHV0LCAzMiwgcmVwZWF0ZWRTdHJpbmczMl8uZ2V0UmF3KGkpKTsKICAgICAgfQogICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgIGludCBzaXplID0gbWVtb2l6ZWRTaXplOwogICAgICBpZiAoc2l6ZSAhPSAtMSkgcmV0dXJuIHNpemU7CgogICAgICBzaXplID0gMDsKICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZzFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nMV8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFN0cmluZzFMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmcyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZzJfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRTdHJpbmcyTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nM18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmczXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU3RyaW5nM0xpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZzRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nNF8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFN0cmluZzRMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmc1Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZzVfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRTdHJpbmc1TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nNl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmc2Xy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU3RyaW5nNkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZzdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nN18uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFN0cmluZzdMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmc4Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZzhfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRTdHJpbmc4TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nOV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmc5Xy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU3RyaW5nOUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZzEwXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZzEwXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU3RyaW5nMTBMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmcxMV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmcxMV8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFN0cmluZzExTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMTJfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nMTJfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRTdHJpbmcxMkxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZzEzXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZzEzXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMSAqIGdldFJlcGVhdGVkU3RyaW5nMTNMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmcxNF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmcxNF8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDEgKiBnZXRSZXBlYXRlZFN0cmluZzE0TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMTVfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nMTVfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAxICogZ2V0UmVwZWF0ZWRTdHJpbmcxNUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZzE2Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZzE2Xy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkU3RyaW5nMTZMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmcxN18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmcxN18uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZFN0cmluZzE3TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMThfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nMThfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRTdHJpbmcxOExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZzE5Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZzE5Xy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkU3RyaW5nMTlMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmcyMF8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmcyMF8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZFN0cmluZzIwTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMjFfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nMjFfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRTdHJpbmcyMUxpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZzIyXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZzIyXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkU3RyaW5nMjJMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmcyM18uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmcyM18uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZFN0cmluZzIzTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMjRfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nMjRfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRTdHJpbmcyNExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZzI1Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZzI1Xy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkU3RyaW5nMjVMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmcyNl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmcyNl8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZFN0cmluZzI2TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMjdfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nMjdfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRTdHJpbmcyN0xpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZzI4Xy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZzI4Xy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkU3RyaW5nMjhMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmcyOV8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmcyOV8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZFN0cmluZzI5TGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICB7CiAgICAgICAgaW50IGRhdGFTaXplID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHJlcGVhdGVkU3RyaW5nMzBfLnNpemUoKTsgaSsrKSB7CiAgICAgICAgICBkYXRhU2l6ZSArPSBjb21wdXRlU3RyaW5nU2l6ZU5vVGFnKHJlcGVhdGVkU3RyaW5nMzBfLmdldFJhdyhpKSk7CiAgICAgICAgfQogICAgICAgIHNpemUgKz0gZGF0YVNpemU7CiAgICAgICAgc2l6ZSArPSAyICogZ2V0UmVwZWF0ZWRTdHJpbmczMExpc3QoKS5zaXplKCk7CiAgICAgIH0KICAgICAgewogICAgICAgIGludCBkYXRhU2l6ZSA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCByZXBlYXRlZFN0cmluZzMxXy5zaXplKCk7IGkrKykgewogICAgICAgICAgZGF0YVNpemUgKz0gY29tcHV0ZVN0cmluZ1NpemVOb1RhZyhyZXBlYXRlZFN0cmluZzMxXy5nZXRSYXcoaSkpOwogICAgICAgIH0KICAgICAgICBzaXplICs9IGRhdGFTaXplOwogICAgICAgIHNpemUgKz0gMiAqIGdldFJlcGVhdGVkU3RyaW5nMzFMaXN0KCkuc2l6ZSgpOwogICAgICB9CiAgICAgIHsKICAgICAgICBpbnQgZGF0YVNpemUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcmVwZWF0ZWRTdHJpbmczMl8uc2l6ZSgpOyBpKyspIHsKICAgICAgICAgIGRhdGFTaXplICs9IGNvbXB1dGVTdHJpbmdTaXplTm9UYWcocmVwZWF0ZWRTdHJpbmczMl8uZ2V0UmF3KGkpKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSArPSBkYXRhU2l6ZTsKICAgICAgICBzaXplICs9IDIgKiBnZXRSZXBlYXRlZFN0cmluZzMyTGlzdCgpLnNpemUoKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcykpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHMgb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHMpIG9iajsKCiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmcxTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nMUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTdHJpbmcyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nM0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZzNMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmc0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nNExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZzVMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTdHJpbmc1TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nNkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZzZMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmc3TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nN0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZzhMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTdHJpbmc4TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nOUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZzlMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmcxMExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZzEwTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nMTFMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTdHJpbmcxMUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZzEyTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nMTJMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmcxM0xpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZzEzTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nMTRMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTdHJpbmcxNExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZzE1TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nMTVMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmcxNkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZzE2TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nMTdMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTdHJpbmcxN0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZzE4TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nMThMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmcxOUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZzE5TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nMjBMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTdHJpbmcyMExpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZzIxTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nMjFMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmcyMkxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZzIyTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nMjNMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTdHJpbmcyM0xpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZzI0TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nMjRMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmcyNUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZzI1TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nMjZMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTdHJpbmcyNkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZzI3TGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nMjdMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmcyOExpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZzI4TGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nMjlMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTdHJpbmcyOUxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRSZXBlYXRlZFN0cmluZzMwTGlzdCgpCiAgICAgICAgICAuZXF1YWxzKG90aGVyLmdldFJlcGVhdGVkU3RyaW5nMzBMaXN0KCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0UmVwZWF0ZWRTdHJpbmczMUxpc3QoKQogICAgICAgICAgLmVxdWFscyhvdGhlci5nZXRSZXBlYXRlZFN0cmluZzMxTGlzdCgpKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWdldFJlcGVhdGVkU3RyaW5nMzJMaXN0KCkKICAgICAgICAgIC5lcXVhbHMob3RoZXIuZ2V0UmVwZWF0ZWRTdHJpbmczMkxpc3QoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmcxQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmcxTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HXzJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFN0cmluZzNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR18zX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZzNMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmc0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfNF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmc0TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nNUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HXzVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nNUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFN0cmluZzZDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR182X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZzZMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmc3Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmc3TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nOENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HXzhfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nOExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFN0cmluZzlDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR185X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZzlMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmcxMENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HXzEwX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZzEwTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nMTFDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR18xMV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmcxMUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFN0cmluZzEyQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfMTJfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nMTJMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmcxM0NvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HXzEzX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZzEzTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nMTRDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR18xNF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmcxNExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFN0cmluZzE1Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfMTVfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nMTVMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmcxNkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HXzE2X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZzE2TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nMTdDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR18xN19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmcxN0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFN0cmluZzE4Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfMThfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nMThMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmcxOUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HXzE5X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZzE5TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nMjBDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR18yMF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmcyMExpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFN0cmluZzIxQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfMjFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nMjFMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmcyMkNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HXzIyX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZzIyTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nMjNDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR18yM19GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmcyM0xpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFN0cmluZzI0Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfMjRfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nMjRMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmcyNUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HXzI1X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZzI1TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nMjZDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR18yNl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmcyNkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFN0cmluZzI3Q291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfMjdfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nMjdMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmcyOENvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HXzI4X0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZzI4TGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nMjlDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR18yOV9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmcyOUxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGlmIChnZXRSZXBlYXRlZFN0cmluZzMwQ291bnQoKSA+IDApIHsKICAgICAgICBoYXNoID0gKDM3ICogaGFzaCkgKyBSRVBFQVRFRF9TVFJJTkdfMzBfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJlcGVhdGVkU3RyaW5nMzBMaXN0KCkuaGFzaENvZGUoKTsKICAgICAgfQogICAgICBpZiAoZ2V0UmVwZWF0ZWRTdHJpbmczMUNvdW50KCkgPiAwKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUkVQRUFURURfU1RSSU5HXzMxX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRSZXBlYXRlZFN0cmluZzMxTGlzdCgpLmhhc2hDb2RlKCk7CiAgICAgIH0KICAgICAgaWYgKGdldFJlcGVhdGVkU3RyaW5nMzJDb3VudCgpID4gMCkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFJFUEVBVEVEX1NUUklOR18zMl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0UmVwZWF0ZWRTdHJpbmczMkxpc3QoKS5oYXNoQ29kZSgpOwogICAgICB9CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHMgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcyBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHMgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcyBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkc30KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcykKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkc09yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHNfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcy5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICByZXBlYXRlZFN0cmluZzFfID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMl8gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmczXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzRfID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nNV8gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc2XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzdfID0KICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nOF8gPQogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc5XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzEwXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzExXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzEyXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzEzXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE0XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE1XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE2XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE3XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE4XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE5XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzIwXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzIxXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzIyXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzIzXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI0XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI1XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI2XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI3XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI4XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI5XyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzMwXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzMxXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzMyXyA9CiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdC5lbXB0eUxpc3QoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcyBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcyByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcyByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHModGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHMgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nMV8gPSByZXBlYXRlZFN0cmluZzFfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmcyXyA9IHJlcGVhdGVkU3RyaW5nMl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDQpICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZzNfID0gcmVwZWF0ZWRTdHJpbmczXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwOCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nNF8gPSByZXBlYXRlZFN0cmluZzRfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDEwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmc1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmc1XyA9IHJlcGVhdGVkU3RyaW5nNV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMjApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZzZfID0gcmVwZWF0ZWRTdHJpbmc2XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDA0MCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nN18gPSByZXBlYXRlZFN0cmluZzdfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwMDgwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmc4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmc4XyA9IHJlcGVhdGVkU3RyaW5nOF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAxMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZzlfID0gcmVwZWF0ZWRTdHJpbmc5XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDIwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMTBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZzEwXyA9IHJlcGVhdGVkU3RyaW5nMTBfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAwNDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nMTFfID0gcmVwZWF0ZWRTdHJpbmcxMV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDA4MDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzEyXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmcxMl8gPSByZXBlYXRlZFN0cmluZzEyXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMTAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMTNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZzEzXyA9IHJlcGVhdGVkU3RyaW5nMTNfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDAyMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nMTRfID0gcmVwZWF0ZWRTdHJpbmcxNF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDQwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzE1Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmcxNV8gPSByZXBlYXRlZFN0cmluZzE1XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwODAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMTZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZzE2XyA9IHJlcGVhdGVkU3RyaW5nMTZfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDEwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nMTdfID0gcmVwZWF0ZWRTdHJpbmcxN187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMjAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzE4Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmcxOF8gPSByZXBlYXRlZFN0cmluZzE4XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDA0MDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZzE5XyA9IHJlcGVhdGVkU3RyaW5nMTlfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwMDgwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyMF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nMjBfID0gcmVwZWF0ZWRTdHJpbmcyMF87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAxMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzIxXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmcyMV8gPSByZXBlYXRlZFN0cmluZzIxXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDIwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZzIyXyA9IHJlcGVhdGVkU3RyaW5nMjJfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAwNDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nMjNfID0gcmVwZWF0ZWRTdHJpbmcyM187CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDA4MDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzI0Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmcyNF8gPSByZXBlYXRlZFN0cmluZzI0XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMTAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZzI1XyA9IHJlcGVhdGVkU3RyaW5nMjVfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDAyMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nMjZfID0gcmVwZWF0ZWRTdHJpbmcyNl87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDQwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzI3Xy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmcyN18gPSByZXBlYXRlZFN0cmluZzI3XzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwODAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMjhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZzI4XyA9IHJlcGVhdGVkU3RyaW5nMjhfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDEwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nMjlfID0gcmVwZWF0ZWRTdHJpbmcyOV87CiAgICAgICAgfQogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MjAwMDAwMDApICE9IDApKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzMwXy5tYWtlSW1tdXRhYmxlKCk7CiAgICAgICAgICByZXN1bHQucmVwZWF0ZWRTdHJpbmczMF8gPSByZXBlYXRlZFN0cmluZzMwXzsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHg0MDAwMDAwMCkgIT0gMCkpIHsKICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICAgIHJlc3VsdC5yZXBlYXRlZFN0cmluZzMxXyA9IHJlcGVhdGVkU3RyaW5nMzFfOwogICAgICAgIH0KICAgICAgICBpZiAoKChmcm9tX2JpdEZpZWxkMF8gJiAweDgwMDAwMDAwKSAhPSAwKSkgewogICAgICAgICAgcmVwZWF0ZWRTdHJpbmczMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgICAgcmVzdWx0LnJlcGVhdGVkU3RyaW5nMzJfID0gcmVwZWF0ZWRTdHJpbmczMl87CiAgICAgICAgfQogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzIG90aGVyKSB7CiAgICAgICAgaWYgKG90aGVyID09IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzLmdldERlZmF1bHRJbnN0YW5jZSgpKSByZXR1cm4gdGhpczsKICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmcxXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nMV87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzFfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzFfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmcyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nMl87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzJfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nM18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmczXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmczXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nM187CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nM0lzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzNfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzNfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nNF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmc0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmc0XyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nNF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nNElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzRfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nNV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmc1Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmc1XyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nNV87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nNUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzVfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzVfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nNl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmc2Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmc2XyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nNl87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nNklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzZfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzZfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nN18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmc3Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmc3XyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nN187CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nN0lzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzdfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzdfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nOF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmc4Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmc4XyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nOF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nOElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzhfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzhfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nOV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmc5Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmc5XyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nOV87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nOUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzlfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzlfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nMTBfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU3RyaW5nMTBfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFN0cmluZzEwXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nMTBfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzEwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMTBfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzEwXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZzExXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFN0cmluZzExXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxMV8gPSBvdGhlci5yZXBlYXRlZFN0cmluZzExXzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxMUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzExXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmcxMV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTdHJpbmcxMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmcxMl8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMTJfID0gb3RoZXIucmVwZWF0ZWRTdHJpbmcxMl87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTJJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxMl8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU3RyaW5nMTJfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nMTNfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU3RyaW5nMTNfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFN0cmluZzEzXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nMTNfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzEzSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMTNfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzEzXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZzE0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFN0cmluZzE0Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxNF8gPSBvdGhlci5yZXBlYXRlZFN0cmluZzE0XzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxNElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzE0Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmcxNF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTdHJpbmcxNV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmcxNV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMTVfID0gb3RoZXIucmVwZWF0ZWRTdHJpbmcxNV87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTVJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxNV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU3RyaW5nMTVfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nMTZfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU3RyaW5nMTZfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFN0cmluZzE2XyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nMTZfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzE2SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMTZfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzE2Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZzE3Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFN0cmluZzE3Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxN18gPSBvdGhlci5yZXBlYXRlZFN0cmluZzE3XzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxN0lzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzE3Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmcxN18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTdHJpbmcxOF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmcxOF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMThfID0gb3RoZXIucmVwZWF0ZWRTdHJpbmcxOF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMThJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxOF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU3RyaW5nMThfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nMTlfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU3RyaW5nMTlfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFN0cmluZzE5XyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nMTlfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzE5SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMTlfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzE5Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZzIwXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFN0cmluZzIwXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyMF8gPSBvdGhlci5yZXBlYXRlZFN0cmluZzIwXzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyMElzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzIwXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmcyMF8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTdHJpbmcyMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmcyMV8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMjFfID0gb3RoZXIucmVwZWF0ZWRTdHJpbmcyMV87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjFJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyMV8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU3RyaW5nMjFfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nMjJfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU3RyaW5nMjJfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFN0cmluZzIyXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nMjJfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzIySXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMjJfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzIyXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZzIzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFN0cmluZzIzXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyM18gPSBvdGhlci5yZXBlYXRlZFN0cmluZzIzXzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyM0lzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzIzXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmcyM18pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTdHJpbmcyNF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmcyNF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMjRfID0gb3RoZXIucmVwZWF0ZWRTdHJpbmcyNF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjRJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyNF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU3RyaW5nMjRfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nMjVfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU3RyaW5nMjVfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFN0cmluZzI1XyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nMjVfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzI1SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMjVfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzI1Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZzI2Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFN0cmluZzI2Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyNl8gPSBvdGhlci5yZXBlYXRlZFN0cmluZzI2XzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyNklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzI2Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmcyNl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTdHJpbmcyN18uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmcyN18uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMjdfID0gb3RoZXIucmVwZWF0ZWRTdHJpbmcyN187CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjdJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyN18uYWRkQWxsKG90aGVyLnJlcGVhdGVkU3RyaW5nMjdfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nMjhfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU3RyaW5nMjhfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFN0cmluZzI4XyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nMjhfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzI4SXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMjhfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzI4Xyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZzI5Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFN0cmluZzI5Xy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyOV8gPSBvdGhlci5yZXBlYXRlZFN0cmluZzI5XzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyOUlzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzI5Xy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmcyOV8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIGlmICghb3RoZXIucmVwZWF0ZWRTdHJpbmczMF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICBpZiAocmVwZWF0ZWRTdHJpbmczMF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMzBfID0gb3RoZXIucmVwZWF0ZWRTdHJpbmczMF87CiAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMzBJc011dGFibGUoKTsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmczMF8uYWRkQWxsKG90aGVyLnJlcGVhdGVkU3RyaW5nMzBfKTsKICAgICAgICAgIH0KICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0KICAgICAgICBpZiAoIW90aGVyLnJlcGVhdGVkU3RyaW5nMzFfLmlzRW1wdHkoKSkgewogICAgICAgICAgaWYgKHJlcGVhdGVkU3RyaW5nMzFfLmlzRW1wdHkoKSkgewogICAgICAgICAgICByZXBlYXRlZFN0cmluZzMxXyA9IG90aGVyLnJlcGVhdGVkU3RyaW5nMzFfOwogICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzMxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMzFfLmFkZEFsbChvdGhlci5yZXBlYXRlZFN0cmluZzMxXyk7CiAgICAgICAgICB9CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFvdGhlci5yZXBlYXRlZFN0cmluZzMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgIGlmIChyZXBlYXRlZFN0cmluZzMyXy5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmczMl8gPSBvdGhlci5yZXBlYXRlZFN0cmluZzMyXzsKICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmczMklzTXV0YWJsZSgpOwogICAgICAgICAgICByZXBlYXRlZFN0cmluZzMyXy5hZGRBbGwob3RoZXIucmVwZWF0ZWRTdHJpbmczMl8pOwogICAgICAgICAgfQogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZzFfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTAKICAgICAgICAgICAgICBjYXNlIDE4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyXy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE4CiAgICAgICAgICAgICAgY2FzZSAyNjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nM18uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNgogICAgICAgICAgICAgIGNhc2UgMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZzRfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMzQKICAgICAgICAgICAgICBjYXNlIDQyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nNUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmc1Xy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDQyCiAgICAgICAgICAgICAgY2FzZSA1MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzZJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nNl8uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA1MAogICAgICAgICAgICAgIGNhc2UgNTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc3SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZzdfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgNTgKICAgICAgICAgICAgICBjYXNlIDY2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nOElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmc4Xy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDY2CiAgICAgICAgICAgICAgY2FzZSA3NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzlJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nOV8uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA3NAogICAgICAgICAgICAgIGNhc2UgODI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxMElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxMF8uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4MgogICAgICAgICAgICAgIGNhc2UgOTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxMUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxMV8uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5MAogICAgICAgICAgICAgIGNhc2UgOTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxMl8uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA5OAogICAgICAgICAgICAgIGNhc2UgMTA2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTNJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMTNfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTA2CiAgICAgICAgICAgICAgY2FzZSAxMTQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxNElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxNF8uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMTQKICAgICAgICAgICAgICBjYXNlIDEyMjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzE1SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZzE1Xy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDEyMgogICAgICAgICAgICAgIGNhc2UgMTMwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTZJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMTZfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTMwCiAgICAgICAgICAgICAgY2FzZSAxMzg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxN0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcxN18uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxMzgKICAgICAgICAgICAgICBjYXNlIDE0NjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzE4SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZzE4Xy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE0NgogICAgICAgICAgICAgIGNhc2UgMTU0OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTlJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMTlfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTU0CiAgICAgICAgICAgICAgY2FzZSAxNjI6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyMElzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyMF8uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNjIKICAgICAgICAgICAgICBjYXNlIDE3MDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzIxSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZzIxXy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE3MAogICAgICAgICAgICAgIGNhc2UgMTc4OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjJJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMjJfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTc4CiAgICAgICAgICAgICAgY2FzZSAxODY6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyM0lzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyM18uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxODYKICAgICAgICAgICAgICBjYXNlIDE5NDogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzI0SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZzI0Xy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE5NAogICAgICAgICAgICAgIGNhc2UgMjAyOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjVJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMjVfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjAyCiAgICAgICAgICAgICAgY2FzZSAyMTA6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyNklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyNl8uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMTAKICAgICAgICAgICAgICBjYXNlIDIxODogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzI3SXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZzI3Xy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDIxOAogICAgICAgICAgICAgIGNhc2UgMjI2OiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjhJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMjhfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjI2CiAgICAgICAgICAgICAgY2FzZSAyMzQ6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyOUlzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmcyOV8uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyMzQKICAgICAgICAgICAgICBjYXNlIDI0MjogewogICAgICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGJzID0gaW5wdXQucmVhZEJ5dGVzKCk7CiAgICAgICAgICAgICAgICBlbnN1cmVSZXBlYXRlZFN0cmluZzMwSXNNdXRhYmxlKCk7CiAgICAgICAgICAgICAgICByZXBlYXRlZFN0cmluZzMwXy5hZGQoYnMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDI0MgogICAgICAgICAgICAgIGNhc2UgMjUwOiB7CiAgICAgICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgYnMgPSBpbnB1dC5yZWFkQnl0ZXMoKTsKICAgICAgICAgICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMzFJc011dGFibGUoKTsKICAgICAgICAgICAgICAgIHJlcGVhdGVkU3RyaW5nMzFfLmFkZChicyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjUwCiAgICAgICAgICAgICAgY2FzZSAyNTg6IHsKICAgICAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBicyA9IGlucHV0LnJlYWRCeXRlcygpOwogICAgICAgICAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmczMklzTXV0YWJsZSgpOwogICAgICAgICAgICAgICAgcmVwZWF0ZWRTdHJpbmczMl8uYWRkKGJzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAyNTgKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFN0cmluZzFJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZzFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzFfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFN0cmluZzFfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcxLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzFMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzFfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcxLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzFDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMUJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzFfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEgPSAxOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nMSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nMSgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nMSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMV8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFN0cmluZzEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFN0cmluZzEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU3RyaW5nMV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmcxKCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAxKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzFCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFN0cmluZzJJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzJfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFN0cmluZzJfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmcyLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzJfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIgPSAyOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmcyLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmcyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMkJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzJfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nMiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nMigKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMl8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDI7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFN0cmluZzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFN0cmluZzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcySXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU3RyaW5nMl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmcyKCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMiA9IDI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzJCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcySXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmczXyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFN0cmluZzNJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZzNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzNfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFN0cmluZzNfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmczLgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzNMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nM18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzNfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMgPSAzOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmczLgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzNDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczXy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmczIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nMyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmczIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nM0J5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzNfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMgPSAzOzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nMyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nMygKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmczSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmczXy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nMyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nM0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nM18uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFN0cmluZzMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFN0cmluZzMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmczSXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU3RyaW5nM18pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zID0gMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmczKCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nM18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMyA9IDM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzNCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmczSXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmczXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwNDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmc0XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFN0cmluZzRJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZzRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzRfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFN0cmluZzRfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA4OwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc0LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nNF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzQgPSA0OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmc0LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc0Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmc0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nNChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc0Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzQgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nNEJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzRfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzQgPSA0OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nNCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nNCgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc0Xy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nNCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nNElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nNF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDg7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFN0cmluZzQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFN0cmluZzQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc0SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU3RyaW5nNF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ180ID0gNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmc0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nNF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA4KTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNCA9IDQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzRCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc0SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc0Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwODsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmc1XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFN0cmluZzVJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZzVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzVfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFN0cmluZzVfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDEwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzUgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc1LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzVMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nNV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzVfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzUgPSA1OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmc1LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzVDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc1Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNSA9IDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmc1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nNShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc1Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzUgPSA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nNUJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzVfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzUgPSA1OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nNSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nNSgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc1SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc1Xy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNSA9IDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nNSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nNUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nNV8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMTA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNSA9IDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFN0cmluZzUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFN0cmluZzUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc1SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU3RyaW5nNV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ181ID0gNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmc1KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nNV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDEwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNSA9IDU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzVCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc1SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc1Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAxMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmc2XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFN0cmluZzZJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZzZfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzZfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFN0cmluZzZfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDIwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzYgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc2LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzZMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nNl8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzZfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzYgPSA2OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmc2LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzZDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc2Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmc2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nNihpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc2Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzYgPSA2OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nNkJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzZfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzYgPSA2OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nNiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nNigKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc2SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc2Xy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nNiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nNklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nNl8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMjA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFN0cmluZzYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFN0cmluZzYoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc2SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU3RyaW5nNl8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ182ID0gNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmc2KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nNl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDIwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNiA9IDY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzZCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc2SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc2Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAyMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmc3XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFN0cmluZzdJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZzdfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzdfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFN0cmluZzdfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDQwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzcgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc3LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzdMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nN18ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzdfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzcgPSA3OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmc3LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzdDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc3Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNyA9IDc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmc3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nNyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc3Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzcgPSA3OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nN0J5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzdfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzcgPSA3OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nNyB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nNygKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc3SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc3Xy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNyA9IDc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nNyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nN0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nN18uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwNDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNyA9IDc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFN0cmluZzcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFN0cmluZzcoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc3SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU3RyaW5nN18pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ183ID0gNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmc3KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nN18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDQwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfNyA9IDc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzdCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc3SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc3Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA0MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmc4XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFN0cmluZzhJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZzhfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzhfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFN0cmluZzhfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDgwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzggPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc4LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzhMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nOF8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzhfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzggPSA4OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmc4LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzhDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc4Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfOCA9IDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmc4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nOChpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc4Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzggPSA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nOEJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzhfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzggPSA4OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nOCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nOCgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc4SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc4Xy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfOCA9IDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nOCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nOElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nOF8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwODA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfOCA9IDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFN0cmluZzggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFN0cmluZzgoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc4SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU3RyaW5nOF8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ184ID0gODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmc4KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nOF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDgwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfOCA9IDg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzhCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc4SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc4Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDA4MDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmc5XyA9CiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QuZW1wdHlMaXN0KCk7CiAgICAgIHByaXZhdGUgdm9pZCBlbnN1cmVSZXBlYXRlZFN0cmluZzlJc011dGFibGUoKSB7CiAgICAgICAgaWYgKCFyZXBlYXRlZFN0cmluZzlfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzlfID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuTGF6eVN0cmluZ0FycmF5TGlzdChyZXBlYXRlZFN0cmluZzlfKTsKICAgICAgICB9CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMTAwOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBBIGxpc3QgY29udGFpbmluZyB0aGUgcmVwZWF0ZWRTdHJpbmc5LgogICAgICAgKi8KICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xTdHJpbmdMaXN0CiAgICAgICAgICBnZXRSZXBlYXRlZFN0cmluZzlMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nOV8ubWFrZUltbXV0YWJsZSgpOwogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzlfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgY291bnQgb2YgcmVwZWF0ZWRTdHJpbmc5LgogICAgICAgKi8KICAgICAgcHVibGljIGludCBnZXRSZXBlYXRlZFN0cmluZzlDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc5Xy5zaXplKCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmc5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlcGVhdGVkU3RyaW5nOShpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmc5Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCBvZiB0aGUgdmFsdWUgdG8gcmV0dXJuLgogICAgICAgKiBAcmV0dXJuIFRoZSBieXRlcyBvZiB0aGUgcmVwZWF0ZWRTdHJpbmc5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nOUJ5dGVzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzlfLmdldEJ5dGVTdHJpbmcoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzkgPSA5OzwvY29kZT4KICAgICAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBzZXQgdGhlIHZhbHVlIGF0LgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nOSB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkU3RyaW5nOSgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc5SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc5Xy5zZXQoaW5kZXgsIHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHJlcGVhdGVkU3RyaW5nOSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkU3RyaW5nOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nOUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nOV8uYWRkKHZhbHVlKTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAxMDA7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWVzIFRoZSByZXBlYXRlZFN0cmluZzkgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRBbGxSZXBlYXRlZFN0cmluZzkoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc5SXNNdXRhYmxlKCk7CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2VMaXRlLkJ1aWxkZXIuYWRkQWxsKAogICAgICAgICAgICB2YWx1ZXMsIHJlcGVhdGVkU3RyaW5nOV8pOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ185ID0gOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUmVwZWF0ZWRTdHJpbmc5KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nOV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMTAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfOSA9IDk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzkgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzlCeXRlcygKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmc5SXNNdXRhYmxlKCk7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmc5Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDEwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxMF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxMElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMTBfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzEwXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcxMF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAyMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTBMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMTBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxMF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTAuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMTBDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxMF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEwID0gMTA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzEwKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzEwXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEwID0gMTA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzEwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTBCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxMF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzEwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcxMCgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxMElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMTBfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMCA9IDEwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzEwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcxMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTBJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzEwXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMCA9IDEwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcxMCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMTAoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxMElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzEwXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMjAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEwID0gMTA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMTAoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxMF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMjAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTAgPSAxMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzEwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTBJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzEwXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDIwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxMV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxMUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMTFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzExXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcxMV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA0MDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTFMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMTFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTEuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMTFDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxMV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzExID0gMTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzExKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzExXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzExID0gMTE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzExIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTFCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxMV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzExIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcxMSgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxMUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMTFfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMSA9IDExOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzExIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcxMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTFJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzExXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMSA9IDExOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcxMSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMTEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxMUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzExXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwNDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzExID0gMTE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMTEoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxMV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwNDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTEgPSAxMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzExQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTFJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzExXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDQwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxMl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMTJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzEyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcxMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDA4MDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMTJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMTJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEyID0gMTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzEyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzEyXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEyID0gMTI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzEyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTJCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxMl8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzEyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcxMigKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMTJfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMiA9IDEyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzEyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcxMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzEyXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMiA9IDEyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcxMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMTIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzEyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwODAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEyID0gMTI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMTIoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxMl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwODAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTIgPSAxMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzEyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzEyXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDgwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxM18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxM0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMTNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzEzXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcxM18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDEwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTNMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMTNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxM187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTMuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMTNDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxM18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEzID0gMTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzEzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzEzXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEzID0gMTM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzEzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTNCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxM18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzEzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcxMygKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxM0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMTNfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMyA9IDEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzEzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcxMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTNJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzEzXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xMyA9IDEzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcxMyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMTMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxM0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzEzXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAxMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzEzID0gMTM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMTMoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxM18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAxMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTMgPSAxMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzEzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTNJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzEzXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMTAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxNF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxNElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMTRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzE0XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcxNF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDIwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMTRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMTRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxNF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzE0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE0Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzE0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxNF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzE0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcxNCgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxNElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMTRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNCA9IDE0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzE0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcxNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE0Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNCA9IDE0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcxNCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMTQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxNElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzE0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAyMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE0ID0gMTQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMTQoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxNF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAyMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTQgPSAxNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzE0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE0Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMjAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxNV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxNUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMTVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzE1XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcxNV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDQwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTVMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMTVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxNV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTUuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMTVDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxNV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzE1KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE1Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzE1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTVCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxNV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzE1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcxNSgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxNUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMTVfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzE1IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcxNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTVJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE1Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNSA9IDE1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcxNSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMTUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxNUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzE1Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA0MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE1ID0gMTU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMTUoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxNV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA0MDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTUgPSAxNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzE1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTVJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE1Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwNDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxNl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxNklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMTZfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzE2XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcxNl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDgwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTZMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMTZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxNl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTYuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMTZDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxNl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxNiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzE2KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE2Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzE2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTZCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxNl8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzE2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcxNigKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxNklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMTZfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNiA9IDE2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzE2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcxNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTZJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE2Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNiA9IDE2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcxNiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMTYoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxNklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzE2Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDA4MDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE2ID0gMTY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMTYoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxNl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDA4MDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTYgPSAxNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzE2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTZJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE2Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwODAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxN18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxN0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMTdfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzE3XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcxN18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMTAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTdMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMTdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxN187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTcuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMTdDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxN18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE3ID0gMTc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxNyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzE3KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE3Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE3ID0gMTc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzE3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTdCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxN18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzE3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcxNygKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxN0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMTdfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNyA9IDE3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzE3IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcxNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTdJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE3Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xNyA9IDE3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcxNyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMTcoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxN0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzE3Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDEwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE3ID0gMTc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMTcoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxN18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDEwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTcgPSAxNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzE3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTdJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE3Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAxMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxOF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxOElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMThfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzE4XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcxOF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMjAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTggPSAxODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMThMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMThfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxOF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTggPSAxODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMThDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxOF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE4ID0gMTg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzE4KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE4Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE4ID0gMTg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzE4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMThCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxOF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTggPSAxODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzE4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcxOCgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxOElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMThfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xOCA9IDE4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzE4IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcxOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMThJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE4Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xOCA9IDE4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcxOCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMTgoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxOElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzE4Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDIwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE4ID0gMTg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMTgoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxOF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDIwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTggPSAxODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzE4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMThJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE4Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAyMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcxOV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxOUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMTlfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzE5XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcxOV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwNDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTlMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMTlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxOV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMTkuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMTlDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxOV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE5ID0gMTk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcxOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzE5KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzE5Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE5ID0gMTk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzE5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMTlCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcxOV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzE5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcxOSgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxOUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMTlfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xOSA9IDE5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzE5IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcxOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTlJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE5Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18xOSA9IDE5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcxOSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMTkoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcxOUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzE5Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDQwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzE5ID0gMTk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMTkoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcxOV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDQwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMTkgPSAxOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMTkgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzE5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMTlJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzE5Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA0MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyMF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyMElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMjBfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzIwXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcyMF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwODAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjBMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMjBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyMF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjAuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjBDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyMF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIwID0gMjA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzIwKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzIwXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIwID0gMjA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzIwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjBCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyMF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzIwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcyMCgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyMElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMjBfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMCA9IDIwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzIwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcyMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjBJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzIwXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMCA9IDIwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcyMCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMjAoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyMElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzIwXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDgwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIwID0gMjA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMjAoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyMF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDgwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjAgPSAyMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzIwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjBJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzIwXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDA4MDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyMV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyMUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMjFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzIxXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcyMV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAxMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjFMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMjFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjEuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjFDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyMV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIxID0gMjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzIxKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzIxXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIxID0gMjE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzIxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjFCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyMV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzIxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcyMSgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyMUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMjFfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMSA9IDIxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzIxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcyMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjFJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzIxXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMSA9IDIxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcyMSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMjEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyMUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzIxXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMTAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIxID0gMjE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMjEoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyMV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMTAwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjEgPSAyMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzIxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjFJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzIxXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDEwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyMl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMjJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzIyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcyMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAyMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMjJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIyID0gMjI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzIyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzIyXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIyID0gMjI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzIyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjJCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyMl8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzIyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcyMigKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMjJfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMiA9IDIyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzIyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcyMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzIyXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMiA9IDIyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcyMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMjIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzIyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMjAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIyID0gMjI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMjIoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyMl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMjAwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjIgPSAyMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzIyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzIyXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDIwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyM18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyM0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMjNfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzIzXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcyM18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA0MDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjNMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMjNfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyM187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjMuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjNDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyM18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIzID0gMjM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyMyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzIzKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzIzXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIzID0gMjM7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzIzIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjNCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyM18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzIzIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcyMygKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyM0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMjNfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMyA9IDIzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzIzIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcyMygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjNJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzIzXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yMyA9IDIzOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcyMyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMjMoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyM0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzIzXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwNDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzIzID0gMjM7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMjMoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyM18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwNDAwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjMgPSAyMzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjMgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzIzQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjNJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzIzXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDQwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyNF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyNElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMjRfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzI0XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcyNF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDA4MDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjRMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMjRfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyNF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjQuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjRDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyNF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyNCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzI0KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI0Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzI0IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjRCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyNF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzI0IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcyNCgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyNElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMjRfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNCA9IDI0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzI0IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcyNCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI0Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNCA9IDI0OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcyNCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMjQoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyNElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzI0Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwODAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI0ID0gMjQ7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMjQoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyNF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwODAwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjQgPSAyNDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjQgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzI0Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjRJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI0Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDgwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyNV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyNUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMjVfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzI1XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcyNV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDEwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjVMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMjVfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyNV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjUuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjVDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyNV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI1ID0gMjU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyNSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzI1KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI1Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI1ID0gMjU7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzI1IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjVCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyNV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzI1IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcyNSgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyNUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMjVfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNSA9IDI1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzI1IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcyNSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjVJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI1Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNSA9IDI1OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcyNSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMjUoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyNUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzI1Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAxMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI1ID0gMjU7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMjUoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyNV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAxMDAwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjUgPSAyNTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjUgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzI1Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjVJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI1Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMTAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyNl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyNklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMjZfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzI2XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcyNl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDIwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjZMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMjZfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyNl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjYuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjZDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyNl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI2ID0gMjY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyNiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzI2KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI2Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI2ID0gMjY7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzI2IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjZCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyNl8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzI2IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcyNigKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyNklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMjZfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNiA9IDI2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzI2IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcyNigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjZJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI2Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNiA9IDI2OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcyNiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMjYoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyNklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzI2Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAyMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI2ID0gMjY7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMjYoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyNl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAyMDAwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjYgPSAyNjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjYgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzI2Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjZJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI2Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMjAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyN18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyN0lzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMjdfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzI3XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcyN18pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDQwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjdMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMjdfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyN187CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjcuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjdDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyN18uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyNyBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzI3KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI3Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzI3IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjdCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyN18uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzI3IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcyNygKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyN0lzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMjdfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNyA9IDI3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzI3IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcyNygKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjdJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI3Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yNyA9IDI3OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcyNyB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMjcoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyN0lzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzI3Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA0MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI3ID0gMjc7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMjcoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyN18gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDA0MDAwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjcgPSAyNzs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjcgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzI3Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjdJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI3Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwNDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyOF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyOElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMjhfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzI4XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcyOF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDgwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjggPSAyODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjguCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjhMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMjhfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyOF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjggPSAyODs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjguCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjhDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyOF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI4ID0gMjg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyOCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzI4KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI4Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI4ID0gMjg7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzI4IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjhCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyOF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjggPSAyODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzI4IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcyOCgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyOElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMjhfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yOCA9IDI4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzI4IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcyOCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjhJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI4Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yOCA9IDI4OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcyOCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMjgoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyOElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzI4Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDA4MDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI4ID0gMjg7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMjgoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyOF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDA4MDAwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjggPSAyODs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjggdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzI4Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjhJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI4Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwODAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmcyOV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyOUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMjlfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzI5XyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmcyOV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MTAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjlMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMjlfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyOV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMjkuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMjlDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyOV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI5ID0gMjk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmcyOSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzI5KGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzI5Xy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI5ID0gMjk7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzI5IGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMjlCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmcyOV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzI5IHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmcyOSgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyOUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMjlfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yOSA9IDI5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzI5IHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmcyOSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjlJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI5Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18yOSA9IDI5OzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmcyOSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMjkoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmcyOUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzI5Xyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDEwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzI5ID0gMjk7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMjkoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmcyOV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDEwMDAwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMjkgPSAyOTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMjkgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzI5Qnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMjlJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzI5Xy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgxMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmczMF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmczMElzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMzBfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzMwXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmczMF8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MjAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMzBMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMzBfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczMF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMzAuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMzBDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczMF8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMwID0gMzA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmczMCBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzMwKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzMwXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMwID0gMzA7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzMwIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMzBCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczMF8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzMwIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmczMCgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmczMElzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMzBfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMCA9IDMwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzMwIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmczMCgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMzBJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzMwXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMCA9IDMwOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmczMCB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMzAoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmczMElzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzMwXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDIwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMwID0gMzA7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMzAoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmczMF8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDIwMDAwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzAgPSAzMDs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMzAgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzMwQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMzBJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzMwXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgyMDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmczMV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmczMUlzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMzFfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzMxXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmczMV8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4NDAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMzFMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMzFfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczMV87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMzEuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMzFDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczMV8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMxID0gMzE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmczMSBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzMxKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzMxXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMxID0gMzE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzMxIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMzFCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczMV8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzMxIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmczMSgKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmczMUlzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMzFfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMSA9IDMxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzMxIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmczMSgKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMzFJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzMxXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMSA9IDMxOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmczMSB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMzEoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmczMUlzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzMxXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDQwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMxID0gMzE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMzEoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmczMV8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDQwMDAwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzEgPSAzMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMzEgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzMxQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMzFJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzMxXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg0MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QgcmVwZWF0ZWRTdHJpbmczMl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICBwcml2YXRlIHZvaWQgZW5zdXJlUmVwZWF0ZWRTdHJpbmczMklzTXV0YWJsZSgpIHsKICAgICAgICBpZiAoIXJlcGVhdGVkU3RyaW5nMzJfLmlzTW9kaWZpYWJsZSgpKSB7CiAgICAgICAgICByZXBlYXRlZFN0cmluZzMyXyA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkxhenlTdHJpbmdBcnJheUxpc3QocmVwZWF0ZWRTdHJpbmczMl8pOwogICAgICAgIH0KICAgICAgICBiaXRGaWVsZDBfIHw9IDB4ODAwMDAwMDA7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gQSBsaXN0IGNvbnRhaW5pbmcgdGhlIHJlcGVhdGVkU3RyaW5nMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5Qcm90b2NvbFN0cmluZ0xpc3QKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMzJMaXN0KCkgewogICAgICAgIHJlcGVhdGVkU3RyaW5nMzJfLm1ha2VJbW11dGFibGUoKTsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczMl87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGNvdW50IG9mIHJlcGVhdGVkU3RyaW5nMzIuCiAgICAgICAqLwogICAgICBwdWJsaWMgaW50IGdldFJlcGVhdGVkU3RyaW5nMzJDb3VudCgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczMl8uc2l6ZSgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybi4KICAgICAgICogQHJldHVybiBUaGUgcmVwZWF0ZWRTdHJpbmczMiBhdCB0aGUgZ2l2ZW4gaW5kZXguCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXBlYXRlZFN0cmluZzMyKGludCBpbmRleCkgewogICAgICAgIHJldHVybiByZXBlYXRlZFN0cmluZzMyXy5nZXQoaW5kZXgpOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSB2YWx1ZSB0byByZXR1cm4uCiAgICAgICAqIEByZXR1cm4gVGhlIGJ5dGVzIG9mIHRoZSByZXBlYXRlZFN0cmluZzMyIGF0IHRoZSBnaXZlbiBpbmRleC4KICAgICAgICovCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcKICAgICAgICAgIGdldFJlcGVhdGVkU3RyaW5nMzJCeXRlcyhpbnQgaW5kZXgpIHsKICAgICAgICByZXR1cm4gcmVwZWF0ZWRTdHJpbmczMl8uZ2V0Qnl0ZVN0cmluZyhpbmRleCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggdG8gc2V0IHRoZSB2YWx1ZSBhdC4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzMyIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRTdHJpbmczMigKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLlN0cmluZyB2YWx1ZSkgewogICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7IHRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOyB9CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmczMklzTXV0YWJsZSgpOwogICAgICAgIHJlcGVhdGVkU3RyaW5nMzJfLnNldChpbmRleCwgdmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSByZXBlYXRlZFN0cmluZzMyIHRvIGFkZC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRTdHJpbmczMigKICAgICAgICAgIGphdmEubGFuZy5TdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzMyXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+cmVwZWF0ZWQgc3RyaW5nIHJlcGVhdGVkX3N0cmluZ18zMiA9IDMyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlcyBUaGUgcmVwZWF0ZWRTdHJpbmczMiB0byBhZGQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZEFsbFJlcGVhdGVkU3RyaW5nMzIoCiAgICAgICAgICBqYXZhLmxhbmcuSXRlcmFibGU8amF2YS5sYW5nLlN0cmluZz4gdmFsdWVzKSB7CiAgICAgICAgZW5zdXJlUmVwZWF0ZWRTdHJpbmczMklzTXV0YWJsZSgpOwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RNZXNzYWdlTGl0ZS5CdWlsZGVyLmFkZEFsbCgKICAgICAgICAgICAgdmFsdWVzLCByZXBlYXRlZFN0cmluZzMyXyk7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDgwMDAwMDAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5yZXBlYXRlZCBzdHJpbmcgcmVwZWF0ZWRfc3RyaW5nXzMyID0gMzI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclJlcGVhdGVkU3RyaW5nMzIoKSB7CiAgICAgICAgcmVwZWF0ZWRTdHJpbmczMl8gPQogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5MYXp5U3RyaW5nQXJyYXlMaXN0LmVtcHR5TGlzdCgpOwogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDgwMDAwMDAwKTs7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPnJlcGVhdGVkIHN0cmluZyByZXBlYXRlZF9zdHJpbmdfMzIgPSAzMjs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYnl0ZXMgb2YgdGhlIHJlcGVhdGVkU3RyaW5nMzIgdG8gYWRkLgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZFN0cmluZzMyQnl0ZXMoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgdmFsdWUpIHsKICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkgeyB0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oKTsgfQogICAgICAgIGVuc3VyZVJlcGVhdGVkU3RyaW5nMzJJc011dGFibGUoKTsKICAgICAgICByZXBlYXRlZFN0cmluZzMyXy5hZGQodmFsdWUpOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHg4MDAwMDAwMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHMpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcykKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcyBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcz4KICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxUZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHM+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHMgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHM+IHBhcnNlcigpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RNZXNzYWdlV2l0aE1hbnlSZXBlYXRlZFB0ckZpZWxkcyBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICAvKioKICAgKiBQcm90b2J1ZiBzZXJ2aWNlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5UZXN0U2VydmljZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGFic3RyYWN0IGNsYXNzIFRlc3RTZXJ2aWNlCiAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlIHsKICAgIHByb3RlY3RlZCBUZXN0U2VydmljZSgpIHt9CgogICAgcHVibGljIGludGVyZmFjZSBJbnRlcmZhY2UgewogICAgICAvKioKICAgICAgICogPGNvZGU+cnBjIEZvbygucHJvdG9idWZfdW5pdHRlc3QuRm9vUmVxdWVzdCkgcmV0dXJucyAoLnByb3RvYnVmX3VuaXR0ZXN0LkZvb1Jlc3BvbnNlKTs8L2NvZGU+CiAgICAgICAqLwogICAgICBwdWJsaWMgYWJzdHJhY3Qgdm9pZCBmb28oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdCByZXF1ZXN0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDYWxsYmFjazxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlPiBkb25lKTsKCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5ycGMgQmFyKC5wcm90b2J1Zl91bml0dGVzdC5CYXJSZXF1ZXN0KSByZXR1cm5zICgucHJvdG9idWZfdW5pdHRlc3QuQmFyUmVzcG9uc2UpOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBhYnN0cmFjdCB2b2lkIGJhcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXF1ZXN0IHJlcXVlc3QsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NhbGxiYWNrPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2U+IGRvbmUpOwoKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuU2VydmljZSBuZXdSZWZsZWN0aXZlU2VydmljZSgKICAgICAgICBmaW5hbCBJbnRlcmZhY2UgaW1wbCkgewogICAgICByZXR1cm4gbmV3IFRlc3RTZXJ2aWNlKCkgewogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgIHZvaWQgZm9vKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0IHJlcXVlc3QsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2FsbGJhY2s8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZT4gZG9uZSkgewogICAgICAgICAgaW1wbC5mb28oY29udHJvbGxlciwgcmVxdWVzdCwgZG9uZSk7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljICB2b2lkIGJhcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCByZXF1ZXN0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NhbGxiYWNrPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2U+IGRvbmUpIHsKICAgICAgICAgIGltcGwuYmFyKGNvbnRyb2xsZXIsIHJlcXVlc3QsIGRvbmUpOwogICAgICAgIH0KCiAgICAgIH07CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkJsb2NraW5nU2VydmljZQogICAgICAgIG5ld1JlZmxlY3RpdmVCbG9ja2luZ1NlcnZpY2UoZmluYWwgQmxvY2tpbmdJbnRlcmZhY2UgaW1wbCkgewogICAgICByZXR1cm4gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQmxvY2tpbmdTZXJ2aWNlKCkgewogICAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLlNlcnZpY2VEZXNjcmlwdG9yCiAgICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UgY2FsbEJsb2NraW5nTWV0aG9kKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk1ldGhvZERlc2NyaXB0b3IgbWV0aG9kLAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlIHJlcXVlc3QpCiAgICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VFeGNlcHRpb24gewogICAgICAgICAgaWYgKG1ldGhvZC5nZXRTZXJ2aWNlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgICAgICJTZXJ2aWNlLmNhbGxCbG9ja2luZ01ldGhvZCgpIGdpdmVuIG1ldGhvZCBkZXNjcmlwdG9yIGZvciAiICsKICAgICAgICAgICAgICAid3Jvbmcgc2VydmljZSB0eXBlLiIpOwogICAgICAgICAgfQogICAgICAgICAgc3dpdGNoKG1ldGhvZC5nZXRJbmRleCgpKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICByZXR1cm4gaW1wbC5mb28oY29udHJvbGxlciwgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdClyZXF1ZXN0KTsKICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgIHJldHVybiBpbXBsLmJhcihjb250cm9sbGVyLCAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXF1ZXN0KXJlcXVlc3QpOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoIkNhbid0IGdldCBoZXJlLiIpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZQogICAgICAgICAgICBnZXRSZXF1ZXN0UHJvdG90eXBlKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk1ldGhvZERlc2NyaXB0b3IgbWV0aG9kKSB7CiAgICAgICAgICBpZiAobWV0aG9kLmdldFNlcnZpY2UoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICAgIlNlcnZpY2UuZ2V0UmVxdWVzdFByb3RvdHlwZSgpIGdpdmVuIG1ldGhvZCAiICsKICAgICAgICAgICAgICAiZGVzY3JpcHRvciBmb3Igd3Jvbmcgc2VydmljZSB0eXBlLiIpOwogICAgICAgICAgfQogICAgICAgICAgc3dpdGNoKG1ldGhvZC5nZXRJbmRleCgpKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdC5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLkFzc2VydGlvbkVycm9yKCJDYW4ndCBnZXQgaGVyZS4iKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UKICAgICAgICAgICAgZ2V0UmVzcG9uc2VQcm90b3R5cGUoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QpIHsKICAgICAgICAgIGlmIChtZXRob2QuZ2V0U2VydmljZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICAgICAiU2VydmljZS5nZXRSZXNwb25zZVByb3RvdHlwZSgpIGdpdmVuIG1ldGhvZCAiICsKICAgICAgICAgICAgICAiZGVzY3JpcHRvciBmb3Igd3Jvbmcgc2VydmljZSB0eXBlLiIpOwogICAgICAgICAgfQogICAgICAgICAgc3dpdGNoKG1ldGhvZC5nZXRJbmRleCgpKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoIkNhbid0IGdldCBoZXJlLiIpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgIH07CiAgICB9CgogICAgLyoqCiAgICAgKiA8Y29kZT5ycGMgRm9vKC5wcm90b2J1Zl91bml0dGVzdC5Gb29SZXF1ZXN0KSByZXR1cm5zICgucHJvdG9idWZfdW5pdHRlc3QuRm9vUmVzcG9uc2UpOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgZm9vKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdCByZXF1ZXN0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2FsbGJhY2s8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZT4gZG9uZSk7CgogICAgLyoqCiAgICAgKiA8Y29kZT5ycGMgQmFyKC5wcm90b2J1Zl91bml0dGVzdC5CYXJSZXF1ZXN0KSByZXR1cm5zICgucHJvdG9idWZfdW5pdHRlc3QuQmFyUmVzcG9uc2UpOzwvY29kZT4KICAgICAqLwogICAgcHVibGljIGFic3RyYWN0IHZvaWQgYmFyKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCByZXF1ZXN0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2FsbGJhY2s8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZT4gZG9uZSk7CgogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuU2VydmljZURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5nZXREZXNjcmlwdG9yKCkuZ2V0U2VydmljZXMoKS5nZXQoMCk7CiAgICB9CiAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5TZXJ2aWNlRGVzY3JpcHRvcgogICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICByZXR1cm4gZ2V0RGVzY3JpcHRvcigpOwogICAgfQoKICAgIHB1YmxpYyBmaW5hbCB2b2lkIGNhbGxNZXRob2QoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5NZXRob2REZXNjcmlwdG9yIG1ldGhvZCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UgcmVxdWVzdCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NhbGxiYWNrPAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlPiBkb25lKSB7CiAgICAgIGlmIChtZXRob2QuZ2V0U2VydmljZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKAogICAgICAgICAgIlNlcnZpY2UuY2FsbE1ldGhvZCgpIGdpdmVuIG1ldGhvZCBkZXNjcmlwdG9yIGZvciB3cm9uZyAiICsKICAgICAgICAgICJzZXJ2aWNlIHR5cGUuIik7CiAgICAgIH0KICAgICAgc3dpdGNoKG1ldGhvZC5nZXRJbmRleCgpKSB7CiAgICAgICAgY2FzZSAwOgogICAgICAgICAgdGhpcy5mb28oY29udHJvbGxlciwgKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdClyZXF1ZXN0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY1V0aWwuPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2U+c3BlY2lhbGl6ZUNhbGxiYWNrKAogICAgICAgICAgICAgIGRvbmUpKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICB0aGlzLmJhcihjb250cm9sbGVyLCAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXF1ZXN0KXJlcXVlc3QsCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjVXRpbC48cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZT5zcGVjaWFsaXplQ2FsbGJhY2soCiAgICAgICAgICAgICAgZG9uZSkpOwogICAgICAgICAgcmV0dXJuOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLkFzc2VydGlvbkVycm9yKCJDYW4ndCBnZXQgaGVyZS4iKTsKICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2UKICAgICAgICBnZXRSZXF1ZXN0UHJvdG90eXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QpIHsKICAgICAgaWYgKG1ldGhvZC5nZXRTZXJ2aWNlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAiU2VydmljZS5nZXRSZXF1ZXN0UHJvdG90eXBlKCkgZ2l2ZW4gbWV0aG9kICIgKwogICAgICAgICAgImRlc2NyaXB0b3IgZm9yIHdyb25nIHNlcnZpY2UgdHlwZS4iKTsKICAgICAgfQogICAgICBzd2l0Y2gobWV0aG9kLmdldEluZGV4KCkpIHsKICAgICAgICBjYXNlIDA6CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXF1ZXN0LmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICAgIGNhc2UgMToKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoIkNhbid0IGdldCBoZXJlLiIpOwogICAgICB9CiAgICB9CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZQogICAgICAgIGdldFJlc3BvbnNlUHJvdG90eXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuTWV0aG9kRGVzY3JpcHRvciBtZXRob2QpIHsKICAgICAgaWYgKG1ldGhvZC5nZXRTZXJ2aWNlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAiU2VydmljZS5nZXRSZXNwb25zZVByb3RvdHlwZSgpIGdpdmVuIG1ldGhvZCAiICsKICAgICAgICAgICJkZXNjcmlwdG9yIGZvciB3cm9uZyBzZXJ2aWNlIHR5cGUuIik7CiAgICAgIH0KICAgICAgc3dpdGNoKG1ldGhvZC5nZXRJbmRleCgpKSB7CiAgICAgICAgY2FzZSAwOgogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgY2FzZSAxOgogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHRocm93IG5ldyBqYXZhLmxhbmcuQXNzZXJ0aW9uRXJyb3IoIkNhbid0IGdldCBoZXJlLiIpOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBTdHViIG5ld1N0dWIoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDaGFubmVsIGNoYW5uZWwpIHsKICAgICAgcmV0dXJuIG5ldyBTdHViKGNoYW5uZWwpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgU3R1YiBleHRlbmRzIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFNlcnZpY2UgaW1wbGVtZW50cyBJbnRlcmZhY2UgewogICAgICBwcml2YXRlIFN0dWIoY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDaGFubmVsIGNoYW5uZWwpIHsKICAgICAgICB0aGlzLmNoYW5uZWwgPSBjaGFubmVsOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2hhbm5lbCBjaGFubmVsOwoKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2hhbm5lbCBnZXRDaGFubmVsKCkgewogICAgICAgIHJldHVybiBjaGFubmVsOwogICAgICB9CgogICAgICBwdWJsaWMgIHZvaWQgZm9vKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1JlcXVlc3QgcmVxdWVzdCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2FsbGJhY2s8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZT4gZG9uZSkgewogICAgICAgIGNoYW5uZWwuY2FsbE1ldGhvZCgKICAgICAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXRob2RzKCkuZ2V0KDApLAogICAgICAgICAgY29udHJvbGxlciwKICAgICAgICAgIHJlcXVlc3QsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNVdGlsLmdlbmVyYWxpemVDYWxsYmFjaygKICAgICAgICAgICAgZG9uZSwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZS5jbGFzcywKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkpOwogICAgICB9CgogICAgICBwdWJsaWMgIHZvaWQgYmFyKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlcXVlc3QgcmVxdWVzdCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ2FsbGJhY2s8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZT4gZG9uZSkgewogICAgICAgIGNoYW5uZWwuY2FsbE1ldGhvZCgKICAgICAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXRob2RzKCkuZ2V0KDEpLAogICAgICAgICAgY29udHJvbGxlciwKICAgICAgICAgIHJlcXVlc3QsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlLmdldERlZmF1bHRJbnN0YW5jZSgpLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNVdGlsLmdlbmVyYWxpemVDYWxsYmFjaygKICAgICAgICAgICAgZG9uZSwKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZS5jbGFzcywKICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkpOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBCbG9ja2luZ0ludGVyZmFjZSBuZXdCbG9ja2luZ1N0dWIoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CbG9ja2luZ1JwY0NoYW5uZWwgY2hhbm5lbCkgewogICAgICByZXR1cm4gbmV3IEJsb2NraW5nU3R1YihjaGFubmVsKTsKICAgIH0KCiAgICBwdWJsaWMgaW50ZXJmYWNlIEJsb2NraW5nSW50ZXJmYWNlIHsKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVzcG9uc2UgZm9vKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5ScGNDb250cm9sbGVyIGNvbnRyb2xsZXIsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1JlcXVlc3QgcmVxdWVzdCkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VFeGNlcHRpb247CgogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXNwb25zZSBiYXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVxdWVzdCByZXF1ZXN0KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuU2VydmljZUV4Y2VwdGlvbjsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjbGFzcyBCbG9ja2luZ1N0dWIgaW1wbGVtZW50cyBCbG9ja2luZ0ludGVyZmFjZSB7CiAgICAgIHByaXZhdGUgQmxvY2tpbmdTdHViKGNvbS5nb29nbGUucHJvdG9idWYuQmxvY2tpbmdScGNDaGFubmVsIGNoYW5uZWwpIHsKICAgICAgICB0aGlzLmNoYW5uZWwgPSBjaGFubmVsOwogICAgICB9CgogICAgICBwcml2YXRlIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuQmxvY2tpbmdScGNDaGFubmVsIGNoYW5uZWw7CgogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb29SZXNwb25zZSBmb28oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLlJwY0NvbnRyb2xsZXIgY29udHJvbGxlciwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9vUmVxdWVzdCByZXF1ZXN0KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuU2VydmljZUV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlKSBjaGFubmVsLmNhbGxCbG9ja2luZ01ldGhvZCgKICAgICAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXRob2RzKCkuZ2V0KDApLAogICAgICAgICAgY29udHJvbGxlciwKICAgICAgICAgIHJlcXVlc3QsCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvb1Jlc3BvbnNlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICAgICAgfQoKCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkJhclJlc3BvbnNlIGJhcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuUnBjQ29udHJvbGxlciBjb250cm9sbGVyLAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5CYXJSZXF1ZXN0IHJlcXVlc3QpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2UpIGNoYW5uZWwuY2FsbEJsb2NraW5nTWV0aG9kKAogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1ldGhvZHMoKS5nZXQoMSksCiAgICAgICAgICBjb250cm9sbGVyLAogICAgICAgICAgcmVxdWVzdCwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uQmFyUmVzcG9uc2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogICAgICB9CgogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5UZXN0U2VydmljZSkKICB9CgogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0lOVDMyX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAxOwogIC8qKgogICAqIDxwcmU+CiAgICogU2luZ3VsYXIKICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gb3B0aW9uYWxJbnQzMkV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU5UNjRfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDI7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5Mb25nPiBvcHRpb25hbEludDY0RXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9VSU5UMzJfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDM7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiBvcHRpb25hbFVpbnQzMkV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfVUlOVDY0X0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA0OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuTG9uZz4gb3B0aW9uYWxVaW50NjRFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NJTlQzMl9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gNTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IG9wdGlvbmFsU2ludDMyRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TSU5UNjRfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDY7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5Mb25nPiBvcHRpb25hbFNpbnQ2NEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRklYRUQzMl9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gNzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IG9wdGlvbmFsRml4ZWQzMkV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRklYRUQ2NF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gODsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkxvbmc+IG9wdGlvbmFsRml4ZWQ2NEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfU0ZJWEVEMzJfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDk7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiBvcHRpb25hbFNmaXhlZDMyRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TRklYRUQ2NF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTA7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5Mb25nPiBvcHRpb25hbFNmaXhlZDY0RXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9GTE9BVF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTE7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5GbG9hdD4gb3B0aW9uYWxGbG9hdEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkZsb2F0LmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0RPVUJMRV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTI7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5Eb3VibGU+IG9wdGlvbmFsRG91YmxlRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuRG91YmxlLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0JPT0xfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDEzOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuQm9vbGVhbj4gb3B0aW9uYWxCb29sRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbi5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9TVFJJTkdfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDE0OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuU3RyaW5nPiBvcHRpb25hbFN0cmluZ0V4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9CWVRFU19FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTU7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gb3B0aW9uYWxCeXRlc0V4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMR1JPVVBfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDE2OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uPiBvcHRpb25hbEdyb3VwRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uLmNsYXNzLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uT3B0aW9uYWxHcm91cF9leHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX05FU1RFRF9NRVNTQUdFX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAxODsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gb3B0aW9uYWxOZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmNsYXNzLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX0ZPUkVJR05fTUVTU0FHRV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTk7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2U+IG9wdGlvbmFsRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbk1lc3NhZ2UuY2xhc3MsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfSU1QT1JUX01FU1NBR0VfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDIwOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZT4gb3B0aW9uYWxJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5jbGFzcywKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfTkVTVEVEX0VOVU1fRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDIxOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPiBvcHRpb25hbE5lc3RlZEVudW1FeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfRk9SRUlHTl9FTlVNX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAyMjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bT4gb3B0aW9uYWxGb3JlaWduRW51bUV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduRW51bS5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9JTVBPUlRfRU5VTV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMjM7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtPiBvcHRpb25hbEltcG9ydEVudW1FeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1NUUklOR19QSUVDRV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMjQ7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5TdHJpbmc+IG9wdGlvbmFsU3RyaW5nUGllY2VFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT1BUSU9OQUxfQ09SRF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMjU7CiAgLyoqCiAgICogPHByZT4KICAgKiBUT0RPOiBjdHlwZT1DT1JEIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIGV4dGVuc2lvbi4gQWRkCiAgICogY3R5cGU9Q09SRCBvcHRpb24gYmFjayBhZnRlciBpdCBpcyBzdXBwb3J0ZWQuCiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLlN0cmluZz4gb3B0aW9uYWxDb3JkRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1BVQkxJQ19JTVBPUlRfTUVTU0FHRV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMjY7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlPiBvcHRpb25hbFB1YmxpY0ltcG9ydE1lc3NhZ2VFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLmNsYXNzLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydFB1YmxpYy5QdWJsaWNJbXBvcnRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPUFRJT05BTF9MQVpZX01FU1NBR0VfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDI3OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiBvcHRpb25hbExhenlNZXNzYWdlRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmNsYXNzLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9QVElPTkFMX1VOVkVSSUZJRURfTEFaWV9NRVNTQUdFX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAyODsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4gb3B0aW9uYWxVbnZlcmlmaWVkTGF6eU1lc3NhZ2VFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuY2xhc3MsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfSU5UMzJfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDMxOwogIC8qKgogICAqIDxwcmU+CiAgICogUmVwZWF0ZWQKICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IHJlcGVhdGVkSW50MzJFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lOVDY0X0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAzMjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+PiByZXBlYXRlZEludDY0RXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9VSU5UMzJfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDMzOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IHJlcGVhdGVkVWludDMyRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9VSU5UNjRfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDM0OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4+IHJlcGVhdGVkVWludDY0RXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TSU5UMzJfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDM1OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IHJlcGVhdGVkU2ludDMyRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TSU5UNjRfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDM2OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4+IHJlcGVhdGVkU2ludDY0RXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9GSVhFRDMyX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAzNzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+PiByZXBlYXRlZEZpeGVkMzJFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0ZJWEVENjRfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDM4OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4+IHJlcGVhdGVkRml4ZWQ2NEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfU0ZJWEVEMzJfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDM5OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IHJlcGVhdGVkU2ZpeGVkMzJFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NGSVhFRDY0X0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA0MDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+PiByZXBlYXRlZFNmaXhlZDY0RXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9GTE9BVF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gNDE7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5GbG9hdD4+IHJlcGVhdGVkRmxvYXRFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5GbG9hdC5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9ET1VCTEVfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDQyOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPj4gcmVwZWF0ZWREb3VibGVFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Eb3VibGUuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQk9PTF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gNDM7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Cb29sZWFuPj4gcmVwZWF0ZWRCb29sRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuQm9vbGVhbi5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9TVFJJTkdfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDQ0OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPj4gcmVwZWF0ZWRTdHJpbmdFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfQllURVNfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDQ1OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmc+PiByZXBlYXRlZEJ5dGVzRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURHUk9VUF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gNDY7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24+PiByZXBlYXRlZEdyb3VwRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlJlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uLmNsYXNzLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uUmVwZWF0ZWRHcm91cF9leHRlbnNpb24uZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX05FU1RFRF9NRVNTQUdFX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA0ODsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4+IHJlcGVhdGVkTmVzdGVkTWVzc2FnZUV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9GT1JFSUdOX01FU1NBR0VfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDQ5OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlPj4gcmVwZWF0ZWRGb3JlaWduTWVzc2FnZUV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5Gb3JlaWduTWVzc2FnZS5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25NZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSRVBFQVRFRF9JTVBPUlRfTUVTU0FHRV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gNTA7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRNZXNzYWdlPj4gcmVwZWF0ZWRJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5jbGFzcywKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuSW1wb3J0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTkVTVEVEX0VOVU1fRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDUxOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtPj4gcmVwZWF0ZWROZXN0ZWRFbnVtRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0ZPUkVJR05fRU5VTV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gNTI7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+PiByZXBlYXRlZEZvcmVpZ25FbnVtRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0lNUE9SVF9FTlVNX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA1MzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8Y29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0+PiByZXBlYXRlZEltcG9ydEVudW1FeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX1NUUklOR19QSUVDRV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gNTQ7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+PiByZXBlYXRlZFN0cmluZ1BpZWNlRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFJFUEVBVEVEX0NPUkRfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDU1OwogIC8qKgogICAqIDxwcmU+CiAgICogVE9ETzogY3R5cGU9Q09SRCBpcyBub3Qgc3VwcG9ydGVkIGZvciBleHRlbnNpb24uIEFkZAogICAqIGN0eXBlPUNPUkQgb3B0aW9uIGJhY2sgYWZ0ZXIgaXQgaXMgc3VwcG9ydGVkLgogICAqIDwvcHJlPgogICAqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+PiByZXBlYXRlZENvcmRFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfTEFaWV9NRVNTQUdFX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA1NzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZT4+IHJlcGVhdGVkTGF6eU1lc3NhZ2VFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuY2xhc3MsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9JTlQzMl9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gNjE7CiAgLyoqCiAgICogPHByZT4KICAgKiBTaW5ndWxhciB3aXRoIGRlZmF1bHRzCiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRJbnQzMkV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9JTlQ2NF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gNjI7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0SW50NjRFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfVUlOVDMyX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA2MzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRVaW50MzJFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfVUlOVDY0X0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA2NDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRVaW50NjRFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfU0lOVDMyX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA2NTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRTaW50MzJFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfU0lOVDY0X0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA2NjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRTaW50NjRFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfRklYRUQzMl9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gNjc7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiBkZWZhdWx0Rml4ZWQzMkV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9GSVhFRDY0X0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA2ODsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkxvbmc+IGRlZmF1bHRGaXhlZDY0RXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX1NGSVhFRDMyX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA2OTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IGRlZmF1bHRTZml4ZWQzMkV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9TRklYRUQ2NF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gNzA7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5Mb25nPiBkZWZhdWx0U2ZpeGVkNjRFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfRkxPQVRfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDcxOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuRmxvYXQ+IGRlZmF1bHRGbG9hdEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkZsb2F0LmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfRE9VQkxFX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA3MjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkRvdWJsZT4gZGVmYXVsdERvdWJsZUV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkRvdWJsZS5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0JPT0xfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDczOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuQm9vbGVhbj4gZGVmYXVsdEJvb2xFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERFRkFVTFRfU1RSSU5HX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA3NDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLlN0cmluZz4gZGVmYXVsdFN0cmluZ0V4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX0JZVEVTX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA3NTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nPiBkZWZhdWx0Qnl0ZXNFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBERUZBVUxUX05FU1RFRF9FTlVNX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA4MTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bT4gZGVmYXVsdE5lc3RlZEVudW1FeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0uY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9GT1JFSUdOX0VOVU1fRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDgyOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtPiBkZWZhdWx0Rm9yZWlnbkVudW1FeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9JTVBPUlRfRU5VTV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gODM7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYudGVzdC5Vbml0dGVzdEltcG9ydC5JbXBvcnRFbnVtPiBkZWZhdWx0SW1wb3J0RW51bUV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LkltcG9ydEVudW0uY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9TVFJJTkdfUElFQ0VfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDg0OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0U3RyaW5nUGllY2VFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgREVGQVVMVF9DT1JEX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA4NTsKICAvKioKICAgKiA8cHJlPgogICAqIFRPRE86IGN0eXBlPUNPUkQgaXMgbm90IHN1cHBvcnRlZCBmb3IgZXh0ZW5zaW9uLiBBZGQKICAgKiBjdHlwZT1DT1JEIG9wdGlvbiBiYWNrIGFmdGVyIGl0IGlzIHN1cHBvcnRlZC4KICAgKiA8L3ByZT4KICAgKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBqYXZhLmxhbmcuU3RyaW5nPiBkZWZhdWx0Q29yZEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLlN0cmluZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9VSU5UMzJfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDExMTsKICAvKioKICAgKiA8cHJlPgogICAqIEZvciBvbmVvZiB0ZXN0CiAgICogPC9wcmU+CiAgICoKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsRXh0ZW5zaW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IG9uZW9mVWludDMyRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBPTkVPRl9ORVNURURfTUVTU0FHRV9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTEyOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxFeHRlbnNpb25zLAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlPiBvbmVvZk5lc3RlZE1lc3NhZ2VFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UuY2xhc3MsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FT0ZfU1RSSU5HX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAxMTM7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGphdmEubGFuZy5TdHJpbmc+IG9uZW9mU3RyaW5nRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuU3RyaW5nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE9ORU9GX0JZVEVTX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAxMTQ7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdEFsbEV4dGVuc2lvbnMsCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZz4gb25lb2ZCeXRlc0V4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE1ZX0VYVEVOU0lPTl9TVFJJTkdfRklFTERfTlVNQkVSID0gNTA7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RGaWVsZE9yZGVyaW5ncywKICAgICAgamF2YS5sYW5nLlN0cmluZz4gbXlFeHRlbnNpb25TdHJpbmcgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5TdHJpbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTVlfRVhURU5TSU9OX0lOVF9GSUVMRF9OVU1CRVIgPSA1OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEZpZWxkT3JkZXJpbmdzIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RmllbGRPcmRlcmluZ3MsCiAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiBteUV4dGVuc2lvbkludCA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0lOVDMyX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA5MDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+PiBwYWNrZWRJbnQzMkV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0lOVDY0X0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA5MTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+PiBwYWNrZWRJbnQ2NEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1VJTlQzMl9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gOTI7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPj4gcGFja2VkVWludDMyRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfVUlOVDY0X0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA5MzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+PiBwYWNrZWRVaW50NjRFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9TSU5UMzJfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDk0OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IHBhY2tlZFNpbnQzMkV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX1NJTlQ2NF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gOTU7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gcGFja2VkU2ludDY0RXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfRklYRUQzMl9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gOTY7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPj4gcGFja2VkRml4ZWQzMkV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUEFDS0VEX0ZJWEVENjRfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDk3OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4+IHBhY2tlZEZpeGVkNjRFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9TRklYRUQzMl9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gOTg7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPj4gcGFja2VkU2ZpeGVkMzJFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9TRklYRUQ2NF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gOTk7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gcGFja2VkU2ZpeGVkNjRFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9GTE9BVF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTAwOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+PiBwYWNrZWRGbG9hdEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkZsb2F0LmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9ET1VCTEVfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDEwMTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0UGFja2VkRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkRvdWJsZT4+IHBhY2tlZERvdWJsZUV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkRvdWJsZS5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQQUNLRURfQk9PTF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTAyOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RQYWNrZWRFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuQm9vbGVhbj4+IHBhY2tlZEJvb2xFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFBBQ0tFRF9FTlVNX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAxMDM7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFBhY2tlZEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+PiBwYWNrZWRFbnVtRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLkZvcmVpZ25FbnVtLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOUEFDS0VEX0lOVDMyX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA5MDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5JbnRlZ2VyPj4gdW5wYWNrZWRJbnQzMkV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5QQUNLRURfSU5UNjRfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDkxOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+PiB1bnBhY2tlZEludDY0RXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuTG9uZy5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlBBQ0tFRF9VSU5UMzJfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDkyOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+PiB1bnBhY2tlZFVpbnQzMkV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5QQUNLRURfVUlOVDY0X0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA5MzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5Mb25nPj4gdW5wYWNrZWRVaW50NjRFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOUEFDS0VEX1NJTlQzMl9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gOTQ7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNrZWRFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IHVucGFja2VkU2ludDMyRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlBBQ0tFRF9TSU5UNjRfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDk1OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkxvbmc+PiB1bnBhY2tlZFNpbnQ2NEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5QQUNLRURfRklYRUQzMl9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gOTY7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNrZWRFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuSW50ZWdlcj4+IHVucGFja2VkRml4ZWQzMkV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5QQUNLRURfRklYRUQ2NF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gOTc7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNrZWRFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4+IHVucGFja2VkRml4ZWQ2NEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkxvbmcuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5QQUNLRURfU0ZJWEVEMzJfRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDk4OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkludGVnZXI+PiB1bnBhY2tlZFNmaXhlZDMyRXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBVTlBBQ0tFRF9TRklYRUQ2NF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gOTk7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNrZWRFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuTG9uZz4+IHVucGFja2VkU2ZpeGVkNjRFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Mb25nLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOUEFDS0VEX0ZMT0FUX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAxMDA7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNrZWRFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRmxvYXQ+PiB1bnBhY2tlZEZsb2F0RXh0ZW5zaW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuRmxvYXQuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5QQUNLRURfRE9VQkxFX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSAxMDE7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNrZWRFeHRlbnNpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0VW5wYWNrZWRFeHRlbnNpb25zLAogICAgICBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuRG91YmxlPj4gdW5wYWNrZWREb3VibGVFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Eb3VibGUuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVU5QQUNLRURfQk9PTF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTAyOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkRXh0ZW5zaW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdFVucGFja2VkRXh0ZW5zaW9ucywKICAgICAgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLkJvb2xlYW4+PiB1bnBhY2tlZEJvb2xFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5Cb29sZWFuLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFVOUEFDS0VEX0VOVU1fRVhURU5TSU9OX0ZJRUxEX05VTUJFUiA9IDEwMzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0+PiB1bnBhY2tlZEVudW1FeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uRm9yZWlnbkVudW0uY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEVTVF9BTExfVFlQRVNfRklFTERfTlVNQkVSID0gNTM2ODYwMDAwOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEh1Z2VGaWVsZE51bWJlcnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RIdWdlRmllbGROdW1iZXJzLAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcz4gdGVzdEFsbFR5cGVzID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3RBbGxUeXBlcy5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEVTVF9FWFRFTlNJT05fSU5TSURFX1RBQkxFX0VYVEVOU0lPTl9GSUVMRF9OVU1CRVIgPSA1OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGUsCiAgICAgIGphdmEubGFuZy5JbnRlZ2VyPiB0ZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGVFeHRlbnNpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIGphdmEubGFuZy5JbnRlZ2VyLmNsYXNzLAogICAgICAgIG51bGwpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOTkVSX0ZJRUxEX05VTUJFUiA9IDM7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpb25hbEdyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXAgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFByb3RvLlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cCwKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbj4gaW5uZXIgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UHJvdG8uVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uSW5uZXJFeHRlbnNpb24uY2xhc3MsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RQcm90by5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbi5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19PcHRpb25hbEdyb3VwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19PcHRpb25hbEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfUmVwZWF0ZWRHcm91cF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfUmVwZWF0ZWRHcm91cF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdERlcHJlY2F0ZWRGaWVsZHNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdERlcHJlY2F0ZWRGaWVsZHNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REZXByZWNhdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RGVwcmVjYXRlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVzZXJ2ZWRGaWVsZHNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlc2VydmVkRmllbGRzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsRXh0ZW5zaW9uc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT3B0aW9uYWxHcm91cF9leHRlbnNpb25fZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT3B0aW9uYWxHcm91cF9leHRlbnNpb25fZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RHcm91cF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0R3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RHcm91cF9PcHRpb25hbEdyb3VwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RHcm91cF9PcHRpb25hbEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0R3JvdXBFeHRlbnNpb25fZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEdyb3VwRXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkRXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRFeHRlbnNpb25fZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRFeHRlbnNpb25fT3B0aW9uYWxHcm91cF9leHRlbnNpb25fZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEV4dGVuc2lvbl9PcHRpb25hbEdyb3VwX2V4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDaGlsZEV4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uRGF0YV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25EYXRhX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25EYXRhX05lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25EYXRhX05lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uRGF0YV9OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFfTmVzdGVkRHluYW1pY0V4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uRGF0YV9OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFfTmVzdGVkRHluYW1pY0V4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkQ2hpbGRFeHRlbnNpb25fZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGFfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkRW51bV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRFbnVtX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRFbnVtTm9NYXNrX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEVudW1Ob01hc2tfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEVudW1NdWx0aV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRFbnVtTXVsdGlfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE5vTWFza011bHRpX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE5vTWFza011bHRpX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRGb3JlaWduX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEZvcmVpZ25fZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Rm9yZWlnbk5lc3RlZF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Rm9yZWlnbk5lc3RlZF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX05lc3RlZE5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9OZXN0ZWROZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVhbGx5TGFyZ2VUYWdOdW1iZXJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVjdXJzaXZlTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVjdXJzaXZlTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25BX1N1Yk1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfU3ViTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfU3ViR3JvdXBfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfU3ViR3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25BX1N1Ykdyb3VwUl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQV9TdWJHcm91cFJfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25CX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25CX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdElzSW5pdGlhbGl6ZWRfU3ViTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9TdWJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9TdWJNZXNzYWdlX1N1Ykdyb3VwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJc0luaXRpYWxpemVkX1N1Yk1lc3NhZ2VfU3ViR3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REdXBGaWVsZE51bWJlcl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REdXBGaWVsZE51bWJlcl9Gb29fZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER1cEZpZWxkTnVtYmVyX0Zvb19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER1cEZpZWxkTnVtYmVyX0Jhcl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfQmFyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFYWdlck1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RMYXp5TWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TGF6eU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RMYXp5TWVzc2FnZVJlcGVhdGVkX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RMYXp5TWVzc2FnZVJlcGVhdGVkX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNYXliZUxhenlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVhZ2VyTWF5YmVMYXp5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNYXliZUxhenlfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNYXliZUxhenlfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRNZXNzYWdlSGFzQml0c19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDYW1lbENhc2VGaWVsZE5hbWVzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDYW1lbENhc2VGaWVsZE5hbWVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RmllbGRPcmRlcmluZ3NfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZpZWxkT3JkZXJpbmdzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RmllbGRPcmRlcmluZ3NfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RmllbGRPcmRlcmluZ3NfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczFfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczFfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25PcmRlcmluZ3MyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25PcmRlcmluZ3MyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMl9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzM19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMl9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzM19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRyZW1lRGVmYXVsdFZhbHVlc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU3BhcnNlRW51bU1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU3BhcnNlRW51bU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09uZVN0cmluZ19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbmVTdHJpbmdfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01vcmVTdHJpbmdfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTW9yZVN0cmluZ19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT25lQnl0ZXNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT25lQnl0ZXNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01vcmVCeXRlc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Nb3JlQnl0ZXNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X01hbnlPcHRpb25hbFN0cmluZ19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYW55T3B0aW9uYWxTdHJpbmdfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDMyTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbnQzMk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1VpbnQzMk1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVWludDMyTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfSW50NjRNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDY0TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVWludDY0TWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9VaW50NjRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Cb29sTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Cb29sTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mX0Zvb0dyb3VwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZl9Gb29Hcm91cF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlX0Zvb0dyb3VwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGVfRm9vR3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZjJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mMl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mMl9Gb29Hcm91cF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2YyX0Zvb0dyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2YyX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mMl9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRPbmVvZl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRPbmVvZl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkT25lb2ZfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRPbmVvZl9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFja2VkVHlwZXNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VW5wYWNrZWRUeXBlc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhY2tlZEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhY2tlZEV4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZEV4dGVuc2lvbnNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFVucGFja2VkRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER5bmFtaWNFeHRlbnNpb25zX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REeW5hbWljRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER5bmFtaWNFeHRlbnNpb25zX0R5bmFtaWNNZXNzYWdlVHlwZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHluYW1pY0V4dGVuc2lvbnNfRHluYW1pY01lc3NhZ2VUeXBlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVwZWF0ZWRTdHJpbmdfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcGVhdGVkU3RyaW5nX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplc19maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX1JlcGVhdGVkRmllbGRzR2VuZXJhdG9yX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfR3JvdXAxX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfR3JvdXAxX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX1JlcGVhdGVkRmllbGRzR2VuZXJhdG9yX0dyb3VwMl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX1JlcGVhdGVkRmllbGRzR2VuZXJhdG9yX0dyb3VwMl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9PcHRpb25hbEdyb3VwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfT3B0aW9uYWxHcm91cF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9SZXBlYXRlZEdyb3VwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRHcm91cF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lcmdlRXhjZXB0aW9uX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXJnZUV4Y2VwdGlvbl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENvbW1lbnRJbmplY3Rpb25NZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VTaXplX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2l6ZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRm9vUmVxdWVzdF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29SZXF1ZXN0X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29SZXNwb25zZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29SZXNwb25zZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRm9vQ2xpZW50TWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29DbGllbnRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29TZXJ2ZXJNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Zvb1NlcnZlck1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0JhclJlcXVlc3RfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQmFyUmVxdWVzdF9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQmFyUmVzcG9uc2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQmFyUmVzcG9uc2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RKc29uTmFtZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SnNvbk5hbWVfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RIdWdlRmllbGROdW1iZXJzX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RIdWdlRmllbGROdW1iZXJzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SHVnZUZpZWxkTnVtYmVyc19PcHRpb25hbEdyb3VwX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RIdWdlRmllbGROdW1iZXJzX09wdGlvbmFsR3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RIdWdlRmllbGROdW1iZXJzX1N0cmluZ1N0cmluZ01hcEVudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RIdWdlRmllbGROdW1iZXJzX1N0cmluZ1N0cmluZ01hcEVudHJ5X2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcl9MYXllcjFPcHRpb25hbEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcl9MYXllcjFPcHRpb25hbEdyb3VwX0xheWVyMlJlcGVhdGVkR3JvdXBfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9MYXllcjJSZXBlYXRlZEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcl9MYXllcjFPcHRpb25hbEdyb3VwX0xheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUludDMyU2ltcGxlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlJbnQzMlNpbXBsZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUludDMyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlJbnQzMl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU1vc3RseUludDMyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlNb3N0bHlJbnQzMl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXJfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlVaW50MzJTaW1wbGVfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeVVpbnQzMlNpbXBsZV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeVVpbnQzMl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5VWludDMyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5T25lVWludDMyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlPbmVVaW50MzJfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlPbmVJbnQzMkJpZ0ZpZWxkTnVtYmVyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlcl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyX05lc3RlZF9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzJfTmVzdGVkX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FbnVtUGFyc2VUZXN0ZXJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRW51bVBhcnNlVGVzdGVyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Cb29sUGFyc2VUZXN0ZXJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQm9vbFBhcnNlVGVzdGVyX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbnQzMlBhcnNlVGVzdGVyX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDMyUGFyc2VUZXN0ZXJfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDY0UGFyc2VUZXN0ZXJfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfSW50NjRQYXJzZVRlc3Rlcl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfSW5saW5lZFN0cmluZ0lkeFJlZ3Jlc3Npb25Qcm90b19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9TdHJpbmdQYXJzZVRlc3Rlcl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9TdHJpbmdQYXJzZVRlc3Rlcl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQmFkRmllbGROYW1lc19kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9CYWRGaWVsZE5hbWVzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbl9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbl9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmVkYWN0ZWRGaWVsZHNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmVkYWN0ZWRGaWVsZHNfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlZGFjdGVkRmllbGRzX01hcFJlZGFjdGVkU3RyaW5nRW50cnlfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmVkYWN0ZWRGaWVsZHNfTWFwUmVkYWN0ZWRTdHJpbmdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmVkYWN0ZWRGaWVsZHNfTWFwVW5yZWRhY3RlZFN0cmluZ0VudHJ5X2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlZGFjdGVkRmllbGRzX01hcFVucmVkYWN0ZWRTdHJpbmdFbnRyeV9maWVsZEFjY2Vzc29yVGFibGU7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENvcmRfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENvcmRfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYWNrZWRFbnVtU21hbGxSYW5nZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0VudW1zRm9yQmVuY2htYXJrX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0VudW1zRm9yQmVuY2htYXJrX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHNfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzX2ZpZWxkQWNjZXNzb3JUYWJsZTsKCiAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICByZXR1cm4gZGVzY3JpcHRvcjsKICB9CiAgcHJpdmF0ZSBzdGF0aWMgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgZGVzY3JpcHRvcjsKICBzdGF0aWMgewogICAgamF2YS5sYW5nLlN0cmluZ1tdIGRlc2NyaXB0b3JEYXRhID0gewogICAgICAiXG5cMDM2Z29vZ2xlL3Byb3RvYnVmL3VuaXR0ZXN0LnByb3RvXDAyMlwwMjFwcm90b2IiICsKICAgICAgInVmX3VuaXR0ZXN0XDAzMiVnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW0iICsKICAgICAgInBvcnQucHJvdG9cIlwzMzZcMDMyXG5cMDE0VGVzdEFsbFR5cGVzXDAyMlwwMjZcblwwMTZvcHRpb25hbF8iICsKICAgICAgImludDMyXDAzMFwwMDEgXDAwMShcMDA1XDAyMlwwMjZcblwwMTZvcHRpb25hbF9pbnQ2NFwwMzBcMDAyIFwwMDEoXDAwM1wwMjJcMDI3XG5cMDE3byIgKwogICAgICAicHRpb25hbF91aW50MzJcMDMwXDAwMyBcMDAxKFxyXDAyMlwwMjdcblwwMTdvcHRpb25hbF91aW50NjRcMDMwIiArCiAgICAgICJcMDA0IFwwMDEoXDAwNFwwMjJcMDI3XG5cMDE3b3B0aW9uYWxfc2ludDMyXDAzMFwwMDUgXDAwMShcMDIxXDAyMlwwMjdcblwwMTdvcHRpb24iICsKICAgICAgImFsX3NpbnQ2NFwwMzBcMDA2IFwwMDEoXDAyMlwwMjJcMDMwXG5cMDIwb3B0aW9uYWxfZml4ZWQzMlwwMzBcMDA3IFwwMDEoIiArCiAgICAgICJcMDA3XDAyMlwwMzBcblwwMjBvcHRpb25hbF9maXhlZDY0XDAzMFwwMTAgXDAwMShcMDA2XDAyMlwwMzFcblwwMjFvcHRpb25hbF8iICsKICAgICAgInNmaXhlZDMyXDAzMFx0IFwwMDEoXDAxN1wwMjJcMDMxXG5cMDIxb3B0aW9uYWxfc2ZpeGVkNjRcMDMwXG4gXDAwMSgiICsKICAgICAgIlwwMjBcMDIyXDAyNlxuXDAxNm9wdGlvbmFsX2Zsb2F0XDAzMFwwMTMgXDAwMShcMDAyXDAyMlwwMjdcblwwMTdvcHRpb25hbF9kbyIgKwogICAgICAidWJsZVwwMzBcMDE0IFwwMDEoXDAwMVwwMjJcMDI1XG5ccm9wdGlvbmFsX2Jvb2xcMDMwXHIgXDAwMShcMDEwXDAyMlwwMjdcblwwMTdvcHQiICsKICAgICAgImlvbmFsX3N0cmluZ1wwMzBcMDE2IFwwMDEoXHRcMDIyXDAyNlxuXDAxNm9wdGlvbmFsX2J5dGVzXDAzMFwwMTcgXDAwMSIgKwogICAgICAiKFwwMTRcMDIyRFxuXHJvcHRpb25hbGdyb3VwXDAzMFwwMjAgXDAwMShcbjItLnByb3RvYnVmX3VuaSIgKwogICAgICAidHRlc3QuVGVzdEFsbFR5cGVzLk9wdGlvbmFsR3JvdXBcMDIyTlxuXDAyN29wdGkiICsKICAgICAgIm9uYWxfbmVzdGVkX21lc3NhZ2VcMDMwXDAyMiBcMDAxKFwwMTMyLS5wcm90b2J1Zl91bmkiICsKICAgICAgInR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlXDAyMkNcblwwMzBvcHRpIiArCiAgICAgICJvbmFsX2ZvcmVpZ25fbWVzc2FnZVwwMzBcMDIzIFwwMDEoXDAxMzIhLnByb3RvYnVmX3VuIiArCiAgICAgICJpdHRlc3QuRm9yZWlnbk1lc3NhZ2VcMDIySFxuXDAyN29wdGlvbmFsX2ltcG9ydCIgKwogICAgICAiX21lc3NhZ2VcMDMwXDAyNCBcMDAxKFwwMTMyXCcucHJvdG9idWZfdW5pdHRlc3RfaW1wb3IiICsKICAgICAgInQuSW1wb3J0TWVzc2FnZVwwMjJIXG5cMDI0b3B0aW9uYWxfbmVzdGVkX2VudW1cMDMwIiArCiAgICAgICJcMDI1IFwwMDEoXDAxNjIqLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OIiArCiAgICAgICJlc3RlZEVudW1cMDIyPVxuXDAyNW9wdGlvbmFsX2ZvcmVpZ25fZW51bVwwMzBcMDI2IFwwMDEoXDAxNiIgKwogICAgICAiMlwwMzYucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW1cMDIyQlxuXDAyNG9wdGkiICsKICAgICAgIm9uYWxfaW1wb3J0X2VudW1cMDMwXDAyNyBcMDAxKFwwMTYyJC5wcm90b2J1Zl91bml0dGUiICsKICAgICAgInN0X2ltcG9ydC5JbXBvcnRFbnVtXDAyMiFcblwwMjVvcHRpb25hbF9zdHJpbmdfIiArCiAgICAgICJwaWVjZVwwMzBcMDMwIFwwMDEoXHRCXDAwMlwwMTBcMDAyXDAyMlwwMzFcblxyb3B0aW9uYWxfY29yZFwwMzBcMDMxIFwwMDEoXHRCXDAwMiIgKwogICAgICAiXDAxMFwwMDFcMDIyVVxuXDAzNm9wdGlvbmFsX3B1YmxpY19pbXBvcnRfbWVzc2FnZVwwMzBcMDMyIFwwMDEiICsKICAgICAgIihcMDEzMi0ucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LlB1YmxpY0ltcG8iICsKICAgICAgInJ0TWVzc2FnZVwwMjJQXG5cMDI1b3B0aW9uYWxfbGF6eV9tZXNzYWdlXDAzMFwwMzMgXDAwMShcMDEzIiArCiAgICAgICIyLS5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkIiArCiAgICAgICJNZXNzYWdlQlwwMDIoXDAwMVwwMjJbXG4gb3B0aW9uYWxfdW52ZXJpZmllZF9sYXp5XyIgKwogICAgICAibWVzc2FnZVwwMzBcMDM0IFwwMDEoXDAxMzItLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbCIgKwogICAgICAibFR5cGVzLk5lc3RlZE1lc3NhZ2VCXDAwMnhcMDAxXDAyMlwwMjZcblwwMTZyZXBlYXRlZF9pbnQiICsKICAgICAgIjMyXDAzMFwwMzcgXDAwMyhcMDA1XDAyMlwwMjZcblwwMTZyZXBlYXRlZF9pbnQ2NFwwMzAgIFwwMDMoXDAwM1wwMjJcMDI3XG5cMDE3cmVwZSIgKwogICAgICAiYXRlZF91aW50MzJcMDMwISBcMDAzKFxyXDAyMlwwMjdcblwwMTdyZXBlYXRlZF91aW50NjRcMDMwXCIgXDAwMyIgKwogICAgICAiKFwwMDRcMDIyXDAyN1xuXDAxN3JlcGVhdGVkX3NpbnQzMlwwMzAjIFwwMDMoXDAyMVwwMjJcMDI3XG5cMDE3cmVwZWF0ZWRfIiArCiAgICAgICJzaW50NjRcMDMwJCBcMDAzKFwwMjJcMDIyXDAzMFxuXDAyMHJlcGVhdGVkX2ZpeGVkMzJcMDMwJSBcMDAzKFwwMDdcMDIyXDAzMCIgKwogICAgICAiXG5cMDIwcmVwZWF0ZWRfZml4ZWQ2NFwwMzAmIFwwMDMoXDAwNlwwMjJcMDMxXG5cMDIxcmVwZWF0ZWRfc2ZpIiArCiAgICAgICJ4ZWQzMlwwMzBcJyBcMDAzKFwwMTdcMDIyXDAzMVxuXDAyMXJlcGVhdGVkX3NmaXhlZDY0XDAzMCggXDAwMyhcMDIwXDAyMlwwMjYiICsKICAgICAgIlxuXDAxNnJlcGVhdGVkX2Zsb2F0XDAzMCkgXDAwMyhcMDAyXDAyMlwwMjdcblwwMTdyZXBlYXRlZF9kb3VibCIgKwogICAgICAiZVwwMzAqIFwwMDMoXDAwMVwwMjJcMDI1XG5ccnJlcGVhdGVkX2Jvb2xcMDMwKyBcMDAzKFwwMTBcMDIyXDAyN1xuXDAxN3JlcGVhdCIgKwogICAgICAiZWRfc3RyaW5nXDAzMCwgXDAwMyhcdFwwMjJcMDI2XG5cMDE2cmVwZWF0ZWRfYnl0ZXNcMDMwLSBcMDAzKFwwMTRcMDIyIiArCiAgICAgICJEXG5ccnJlcGVhdGVkZ3JvdXBcMDMwLiBcMDAzKFxuMi0ucHJvdG9idWZfdW5pdHRlIiArCiAgICAgICJzdC5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cFwwMjJOXG5cMDI3cmVwZWF0ZSIgKwogICAgICAiZF9uZXN0ZWRfbWVzc2FnZVwwMzAwIFwwMDMoXDAxMzItLnByb3RvYnVmX3VuaXR0ZSIgKwogICAgICAic3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VcMDIyQ1xuXDAzMHJlcGVhdGUiICsKICAgICAgImRfZm9yZWlnbl9tZXNzYWdlXDAzMDEgXDAwMyhcMDEzMiEucHJvdG9idWZfdW5pdHQiICsKICAgICAgImVzdC5Gb3JlaWduTWVzc2FnZVwwMjJIXG5cMDI3cmVwZWF0ZWRfaW1wb3J0X21lIiArCiAgICAgICJzc2FnZVwwMzAyIFwwMDMoXDAxMzJcJy5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSSIgKwogICAgICAibXBvcnRNZXNzYWdlXDAyMkhcblwwMjRyZXBlYXRlZF9uZXN0ZWRfZW51bVwwMzAzIFwwMDMiICsKICAgICAgIihcMDE2MioucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3QiICsKICAgICAgImVkRW51bVwwMjI9XG5cMDI1cmVwZWF0ZWRfZm9yZWlnbl9lbnVtXDAzMDQgXDAwMyhcMDE2MlwwMzYuIiArCiAgICAgICJwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bVwwMjJCXG5cMDI0cmVwZWF0ZSIgKwogICAgICAiZF9pbXBvcnRfZW51bVwwMzA1IFwwMDMoXDAxNjIkLnByb3RvYnVmX3VuaXR0ZXN0XyIgKwogICAgICAiaW1wb3J0LkltcG9ydEVudW1cMDIyIVxuXDAyNXJlcGVhdGVkX3N0cmluZ19waWUiICsKICAgICAgImNlXDAzMDYgXDAwMyhcdEJcMDAyXDAxMFwwMDJcMDIyXDAzMVxuXHJyZXBlYXRlZF9jb3JkXDAzMDcgXDAwMyhcdEJcMDAyXDAxMFwwMDFcMDIyIiArCiAgICAgICJQXG5cMDI1cmVwZWF0ZWRfbGF6eV9tZXNzYWdlXDAzMDkgXDAwMyhcMDEzMi0ucHJvdG9idSIgKwogICAgICAiZl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZUJcMDAyKCIgKwogICAgICAiXDAwMVwwMjJcMDMxXG5ccmRlZmF1bHRfaW50MzJcMDMwPSBcMDAxKFwwMDU6XDAwMjQxXDAyMlwwMzFcblxyZGVmYXVsdF8iICsKICAgICAgImludDY0XDAzMD4gXDAwMShcMDAzOlwwMDI0MlwwMjJcMDMyXG5cMDE2ZGVmYXVsdF91aW50MzJcMDMwPyBcMDAxKFxyOiIgKwogICAgICAiXDAwMjQzXDAyMlwwMzJcblwwMTZkZWZhdWx0X3VpbnQ2NFwwMzBAIFwwMDEoXDAwNDpcMDAyNDRcMDIyXDAzM1xuXDAxNmRlZmF1IiArCiAgICAgICJsdF9zaW50MzJcMDMwQSBcMDAxKFwwMjE6XDAwMy00NVwwMjJcMDMyXG5cMDE2ZGVmYXVsdF9zaW50NjRcMDMwQiIgKwogICAgICAiIFwwMDEoXDAyMjpcMDAyNDZcMDIyXDAzM1xuXDAxN2RlZmF1bHRfZml4ZWQzMlwwMzBDIFwwMDEoXDAwNzpcMDAyNDdcMDIyXDAzM1xuIiArCiAgICAgICJcMDE3ZGVmYXVsdF9maXhlZDY0XDAzMEQgXDAwMShcMDA2OlwwMDI0OFwwMjJcMDM0XG5cMDIwZGVmYXVsdF9zZiIgKwogICAgICAiaXhlZDMyXDAzMEUgXDAwMShcMDE3OlwwMDI0OVwwMjJcMDM1XG5cMDIwZGVmYXVsdF9zZml4ZWQ2NFwwMzBGIFwwMDEiICsKICAgICAgIihcMDIwOlwwMDMtNTBcMDIyXDAzM1xuXHJkZWZhdWx0X2Zsb2F0XDAzMEcgXDAwMShcMDAyOlwwMDQ1MS41XDAyMlwwMzVcblwwMTYiICsKICAgICAgImRlZmF1bHRfZG91YmxlXDAzMEggXDAwMShcMDAxOlwwMDU1MjAwMFwwMjJcMDMyXG5cMDE0ZGVmYXVsdF9iIiArCiAgICAgICJvb2xcMDMwSSBcMDAxKFwwMTA6XDAwNHRydWVcMDIyXDAzNVxuXDAxNmRlZmF1bHRfc3RyaW5nXDAzMEogXDAwMShcdDoiICsKICAgICAgIlwwMDVoZWxsb1wwMjJcMDM0XG5ccmRlZmF1bHRfYnl0ZXNcMDMwSyBcMDAxKFwwMTQ6XDAwNXdvcmxkXDAyMkxcblwwMjMiICsKICAgICAgImRlZmF1bHRfbmVzdGVkX2VudW1cMDMwUSBcMDAxKFwwMTYyKi5wcm90b2J1Zl91bmkiICsKICAgICAgInR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtOlwwMDNCQVJcMDIySVxuXDAyNGRlIiArCiAgICAgICJmYXVsdF9mb3JlaWduX2VudW1cMDMwUiBcMDAxKFwwMTYyXDAzNi5wcm90b2J1Zl91bml0IiArCiAgICAgICJ0ZXN0LkZvcmVpZ25FbnVtOlwwMTNGT1JFSUdOX0JBUlwwMjJNXG5cMDIzZGVmYXVsdCIgKwogICAgICAiX2ltcG9ydF9lbnVtXDAzMFMgXDAwMShcMDE2MiQucHJvdG9idWZfdW5pdHRlc3RfaSIgKwogICAgICAibXBvcnQuSW1wb3J0RW51bTpcbklNUE9SVF9CQVJcMDIyJVxuXDAyNGRlZmF1bHRfIiArCiAgICAgICJzdHJpbmdfcGllY2VcMDMwVCBcMDAxKFx0OlwwMDNhYmNCXDAwMlwwMTBcMDAyXDAyMlwwMzVcblwwMTRkZWZhdWx0X2MiICsKICAgICAgIm9yZFwwMzBVIFwwMDEoXHQ6XDAwMzEyM0JcMDAyXDAxMFwwMDFcMDIyXDAyNlxuXDAxNG9uZW9mX3VpbnQzMlwwMzBvIFwwMDEoXHIiICsKICAgICAgIkhcMDAwXDAyMk1cblwwMjRvbmVvZl9uZXN0ZWRfbWVzc2FnZVwwMzBwIFwwMDEoXDAxMzItLnByb3RvIiArCiAgICAgICJidWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VIIiArCiAgICAgICJcMDAwXDAyMlwwMjZcblwwMTRvbmVvZl9zdHJpbmdcMDMwcSBcMDAxKFx0SFwwMDBcMDIyXDAyNVxuXDAxM29uZW9mX2J5dGVzIiArCiAgICAgICJcMDMwciBcMDAxKFwwMTRIXDAwMFwwMjJcMDMwXG5cbm9uZW9mX2NvcmRcMDMwcyBcMDAxKFx0QlwwMDJcMDEwXDAwMUhcMDAwXDAyMiBcblwwMjJvbiIgKwogICAgICAiZW9mX3N0cmluZ19waWVjZVwwMzB0IFwwMDEoXHRCXDAwMlwwMTBcMDAySFwwMDBcMDIyVlxuXDAzMW9uZW9mX2xhIiArCiAgICAgICJ6eV9uZXN0ZWRfbWVzc2FnZVwwMzB1IFwwMDEoXDAxMzItLnByb3RvYnVmX3VuaXR0IiArCiAgICAgICJlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VCXDAwMihcMDAxSFwwMDBcMDMyXDAzM1xuXHIiICsKICAgICAgIk5lc3RlZE1lc3NhZ2VcMDIyXG5cblwwMDJiYlwwMzBcMDAxIFwwMDEoXDAwNVwwMzJcMDMyXG5cck9wdGlvbmFsR3JvIiArCiAgICAgICJ1cFwwMjJcdFxuXDAwMWFcMDMwXDAyMSBcMDAxKFwwMDVcMDMyXDAzMlxuXHJSZXBlYXRlZEdyb3VwXDAyMlx0XG5cMDAxYVwwMzAvIFwwMDEoIiArCiAgICAgICJcMDA1XCI5XG5cbk5lc3RlZEVudW1cMDIyXDAwN1xuXDAwM0ZPT1wwMjBcMDAxXDAyMlwwMDdcblwwMDNCQVJcMDIwXDAwMlwwMjJcMDA3XG5cMDAzQkFaIiArCiAgICAgICJcMDIwXDAwM1wwMjJcMDIwXG5cMDAzTkVHXDAyMFwzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wwMDFCXHJcblwwMTNvbmVvZl9maWVsZFwiXDI2NFwwMDJcblwwMjIiICsKICAgICAgIk5lc3RlZFRlc3RBbGxUeXBlc1wwMjI0XG5cMDA1Y2hpbGRcMDMwXDAwMSBcMDAxKFwwMTMyJS5wcm90IiArCiAgICAgICJvYnVmX3VuaXR0ZXN0Lk5lc3RlZFRlc3RBbGxUeXBlc1wwMjIwXG5cMDA3cGF5bCIgKwogICAgICAib2FkXDAzMFwwMDIgXDAwMShcMDEzMlwwMzcucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cCIgKwogICAgICAiZXNcMDIyPVxuXDAxNnJlcGVhdGVkX2NoaWxkXDAzMFwwMDMgXDAwMyhcMDEzMiUucHJvdG9idWZfdW4iICsKICAgICAgIml0dGVzdC5OZXN0ZWRUZXN0QWxsVHlwZXNcMDIyPVxuXG5sYXp5X2NoaWxkXDAzMCIgKwogICAgICAiXDAwNCBcMDAxKFwwMTMyJS5wcm90b2J1Zl91bml0dGVzdC5OZXN0ZWRUZXN0QWxsVCIgKwogICAgICAieXBlc0JcMDAyKFwwMDFcMDIyOFxuXDAxM2VhZ2VyX2NoaWxkXDAzMFwwMDUgXDAwMShcMDEzMlwwMzcucHJvdG9idWYiICsKICAgICAgIl91bml0dGVzdC5UZXN0QWxsVHlwZXNCXDAwMihcMDAwXCJcMjM1XDAwMlxuXDAyNFRlc3REZXByZSIgKwogICAgICAiY2F0ZWRGaWVsZHNcMDIyXDAzNFxuXDAyMGRlcHJlY2F0ZWRfaW50MzJcMDMwXDAwMSBcMDAxKFwwMDVCXDAwMlwwMzAiICsKICAgICAgIlwwMDFcMDIyJlxuXDAzMmRlcHJlY2F0ZWRfcmVwZWF0ZWRfc3RyaW5nXDAzMFwwMDQgXDAwMyhcdEJcMDAyXDAzMCIgKwogICAgICAiXDAwMVwwMjJNXG5cMDIyZGVwcmVjYXRlZF9tZXNzYWdlXDAzMFwwMDMgXDAwMShcMDEzMi0ucHJvdG9idWYiICsKICAgICAgIl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZUJcMDAyXDAzMFwwMDEiICsKICAgICAgIlwwMjJcJ1xuXDAzMWRlcHJlY2F0ZWRfaW50MzJfaW5fb25lb2ZcMDMwXDAwMiBcMDAxKFwwMDVCXDAwMlwwMzBcMDAxSCIgKwogICAgICAiXDAwMFwwMjI3XG5cMDA2bmVzdGVkXDAzMFwwMDUgXDAwMShcMDEzMlwnLnByb3RvYnVmX3VuaXR0ZXN0LlRlIiArCiAgICAgICJzdERlcHJlY2F0ZWRGaWVsZHNCXDAxNlxuXDAxNG9uZW9mX2ZpZWxkc1wiXDAzM1xuXDAyNVRlIiArCiAgICAgICJzdERlcHJlY2F0ZWRNZXNzYWdlOlwwMDJcMDMwXDAwMVwiJlxuXDAxNkZvcmVpZ25NZXNzYWciICsKICAgICAgImVcMDIyXHRcblwwMDFjXDAzMFwwMDEgXDAwMShcMDA1XDAyMlx0XG5cMDAxZFwwMzBcMDAyIFwwMDEoXDAwNVwiMFxuXDAyMlRlc3RSZXNlcnZlZEYiICsKICAgICAgImllbGRzSlwwMDRcMDEwXDAwMlwwMjBcMDAzSlwwMDRcMDEwXDAxN1wwMjBcMDIwSlwwMDRcMDEwXHRcMDIwXDAxNFJcMDAzYmFyUlwwMDNiYXpcIlwwMzVcblwwMjFUZXMiICsKICAgICAgInRBbGxFeHRlbnNpb25zKlwwMTBcMDEwXDAwMVwwMjBcMjAwXDIwMFwyMDBcMjAwXDAwMlwiJFxuXDAyN09wdGlvbmFsR3JvdSIgKwogICAgICAicF9leHRlbnNpb25cMDIyXHRcblwwMDFhXDAzMFwwMjEgXDAwMShcMDA1XCIkXG5cMDI3UmVwZWF0ZWRHcm91cF8iICsKICAgICAgImV4dGVuc2lvblwwMjJcdFxuXDAwMWFcMDMwLyBcMDAxKFwwMDVcIlwyNzBcMDAxXG5cMDM0VGVzdE1peGVkRmllbGRzIiArCiAgICAgICJBbmRFeHRlbnNpb25zXDAyMlx0XG5cMDAxYVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcdFxuXDAwMWJcMDMwXDAwMyBcMDAzKFwwMDcqXDAwNFwwMTBcMDAyXDAyMCIgKwogICAgICAiXDAwMypcMDA0XDAxMFwwMDRcMDIwXDAwNTI6XG5cMDAxY1wwMjIvLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNaXgiICsKICAgICAgImVkRmllbGRzQW5kRXh0ZW5zaW9uc1wwMzBcMDAyIFwwMDEoXDAwNTI6XG5cMDAxZFwwMjIvLnByb3RvIiArCiAgICAgICJidWZfdW5pdHRlc3QuVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9uIiArCiAgICAgICJzXDAzMFwwMDQgXDAwMyhcMDA3XCJcMjY1XDAwMVxuXHRUZXN0R3JvdXBcMDIyQVxuXHJvcHRpb25hbGdyb3VwXDAzMFwwMjAiICsKICAgICAgIiBcMDAxKFxuMioucHJvdG9idWZfdW5pdHRlc3QuVGVzdEdyb3VwLk9wdGlvIiArCiAgICAgICJuYWxHcm91cFwwMjI9XG5cMDI1b3B0aW9uYWxfZm9yZWlnbl9lbnVtXDAzMFwwMjYgXDAwMShcMDE2MiIgKwogICAgICAiXDAzNi5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bVwwMzImXG5cck9wdGlvIiArCiAgICAgICJuYWxHcm91cFwwMjJcdFxuXDAwMWFcMDMwXDAyMSBcMDAxKFwwMDVcMDIyXG5cblwwMDJ6elwwMzBZIFwwMDEoXDAwNVwiXDAzNlxuXDAyMlRlc3RHIiArCiAgICAgICJyb3VwRXh0ZW5zaW9uKlwwMTBcMDEwXDAwMVwwMjBcMjAwXDIwMFwyMDBcMjAwXDAwMlwiXDI2N1wwMDNcblwwMjNUZXN0TmVzdGVkRXgiICsKICAgICAgInRlbnNpb25cMDMyJFxuXDAyN09wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uXDAyMlx0XG5cMDAxYVwwMzAiICsKICAgICAgIlwwMjEgXDAwMShcMDA1MjlcblwwMDR0ZXN0XDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsIiArCiAgICAgICJsRXh0ZW5zaW9uc1wwMzBcMzUyXDAwNyBcMDAxKFx0OlwwMDR0ZXN0MkZcblwwMjduZXN0ZWRfc3RyaW4iICsKICAgICAgImdfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEUiICsKICAgICAgInh0ZW5zaW9uc1wwMzBcMzUzXDAwNyBcMDAxKFx0MlwyMDZcMDAxXG5cMDI3b3B0aW9uYWxncm91cF9leHRlbiIgKwogICAgICAic2lvblwwMjIlLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RHcm91cEV4dGVucyIgKwogICAgICAiaW9uXDAzMFwwMjAgXDAwMShcbjI+LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWQiICsKICAgICAgIkV4dGVuc2lvbi5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbjJuXG5cMDM3b3B0IiArCiAgICAgICJpb25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uXDAyMiUucHJvdG9idWZfIiArCiAgICAgICJ1bml0dGVzdC5UZXN0R3JvdXBFeHRlbnNpb25cMDMwXDAyNiBcMDAxKFwwMTYyXDAzNi5wcm90IiArCiAgICAgICJvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtXCJsXG5cMDIyVGVzdENoaWxkRXgiICsKICAgICAgInRlbnNpb25cMDIyXHRcblwwMDFhXDAzMFwwMDEgXDAwMShcdFwwMjJcdFxuXDAwMWJcMDMwXDAwMiBcMDAxKFx0XDAyMkBcblwwMjJvcHRpb25hIiArCiAgICAgICJsX2V4dGVuc2lvblwwMzBcMDAzIFwwMDEoXDAxMzIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlIiArCiAgICAgICJzdEFsbEV4dGVuc2lvbnNcIlwzMjZcMDAyXG5cMDI2VGVzdENoaWxkRXh0ZW5zaW9uRGEiICsKICAgICAgInRhXDAyMlx0XG5cMDAxYVwwMzBcMDAxIFwwMDEoXHRcMDIyXHRcblwwMDFiXDAzMFwwMDIgXDAwMShcdFwwMjJhXG5cMDIyb3B0aW9uYWxfZXh0IiArCiAgICAgICJlbnNpb25cMDMwXDAwMyBcMDAxKFwwMTMyRS5wcm90b2J1Zl91bml0dGVzdC5UZXN0Q2hpIiArCiAgICAgICJsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEIiArCiAgICAgICJhdGFcMDMyXDMwMlwwMDFcblwwMzNOZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFcMDIyclxuXDAwN2QiICsKICAgICAgInluYW1pY1wwMzBcMjAwXDMwNFwyNTZcMzAzXDAwMSBcMDAxKFwwMTMyXS5wcm90b2J1Zl91bml0dGVzdC5UZXMiICsKICAgICAgInRDaGlsZEV4dGVuc2lvbkRhdGEuTmVzdGVkVGVzdEFsbEV4dGVuc2kiICsKICAgICAgIm9uc0RhdGEuTmVzdGVkRHluYW1pY0V4dGVuc2lvbnNcMDMyL1xuXDAyN05lc3RlIiArCiAgICAgICJkRHluYW1pY0V4dGVuc2lvbnNcMDIyXHRcblwwMDFhXDAzMFwwMDEgXDAwMShcMDA1XDAyMlx0XG5cMDAxYlwwMzBcMDAyIFwwMDEoXDAwNSIgKwogICAgICAiXCJbXG5cMDMwVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uXDAyMlx0XG5cMDAxYVwwMzBcMDAxIFwwMDEoXDAwNVwwMjIiICsKICAgICAgIjRcblwwMDVjaGlsZFwwMzBcMDAyIFwwMDEoXDAxMzIlLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RDIiArCiAgICAgICJoaWxkRXh0ZW5zaW9uXCJjXG5cMDM0VGVzdE5lc3RlZENoaWxkRXh0ZW5zaW8iICsKICAgICAgIm5EYXRhXDAyMlx0XG5cMDAxYVwwMzBcMDAxIFwwMDEoXDAwNVwwMjI4XG5cMDA1Y2hpbGRcMDMwXDAwMiBcMDAxKFwwMTMyKS5wcm90b2IiICsKICAgICAgInVmX3VuaXR0ZXN0LlRlc3RDaGlsZEV4dGVuc2lvbkRhdGFcIlRcblwwMjBUZSIgKwogICAgICAic3RSZXF1aXJlZEVudW1cMDIyNVxuXHJyZXF1aXJlZF9lbnVtXDAzMFwwMDEgXDAwMihcMDE2MlwwMzYuIiArCiAgICAgICJwcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bVwwMjJcdFxuXDAwMWFcMDMwXDAwMiBcMDAxKFwwMDUiICsKICAgICAgIlwiXDI2M1wwMDFcblwwMjZUZXN0UmVxdWlyZWRFbnVtTm9NYXNrXDAyMktcblxycmVxdWlyZWRfIiArCiAgICAgICJlbnVtXDAzMFwwMDEgXDAwMihcMDE2MjQucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpIiArCiAgICAgICJyZWRFbnVtTm9NYXNrLk5lc3RlZEVudW1cMDIyXHRcblwwMDFhXDAzMFwwMDIgXDAwMShcMDA1XCJBXG5cbk4iICsKICAgICAgImVzdGVkRW51bVwwMjJcMDE3XG5cMDEzVU5TUEVDSUZJRURcMDIwXDAwMFwwMjJcMDA3XG5cMDAzRk9PXDAyMFwwMDJcMDIyXDAwN1xuXDAwM0IiICsKICAgICAgIkFSXDAyMGRcMDIyXDAyMFxuXDAwM0JBWlwwMjBcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMDAxXCJcMjYzXDAwMlxuXDAyNVRlc3RSZXF1aXJlZEUiICsKICAgICAgIm51bU11bHRpXDAyMkxcblwwMTdyZXF1aXJlZF9lbnVtXzRcMDMwXDAwNCBcMDAyKFwwMTYyMy5wcm90IiArCiAgICAgICJvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEVudW1NdWx0aS5OZXN0IiArCiAgICAgICJlZEVudW1cMDIyXDAxM1xuXDAwM2FfM1wwMzBcMDAzIFwwMDEoXDAwNVwwMjJMXG5cMDE3cmVxdWlyZWRfZW51bV8yXDAzMFwwMDIiICsKICAgICAgIiBcMDAyKFwwMTYyMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRFbnUiICsKICAgICAgIm1NdWx0aS5OZXN0ZWRFbnVtXDAyMjdcblwwMTdyZXF1aXJlZF9lbnVtXzFcMDMwXDAwMSBcMDAyIiArCiAgICAgICIoXDAxNjJcMDM2LnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtXCI4XG5cbk5lIiArCiAgICAgICJzdGVkRW51bVwwMjJcMDE3XG5cMDEzVU5TUEVDSUZJRURcMDIwXDAwMFwwMjJcMDA3XG5cMDAzRk9PXDAyMFwwMDFcMDIyXDAwN1xuXDAwM0JBIiArCiAgICAgICJSXDAyMFwwMDJcMDIyXDAwN1xuXDAwM0JBWlwwMjBkXCJcMzA0XDAwM1xuXDAyN1Rlc3RSZXF1aXJlZE5vTWFza011bHRpIiArCiAgICAgICJcMDIyXDAzM1xuXDAyM3JlcXVpcmVkX2ZpeGVkMzJfODBcMDMwUCBcMDAyKFwwMDdcMDIyXDAzM1xuXDAyM3JlcXVpcmUiICsKICAgICAgImRfZml4ZWQzMl83MFwwMzBGIFwwMDIoXDAwN1wwMjJPXG5cMDIwcmVxdWlyZWRfZW51bV82NFwwMzBAIiArCiAgICAgICIgXDAwMihcMDE2MjUucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NIiArCiAgICAgICJhc2tNdWx0aS5OZXN0ZWRFbnVtXDAyMk5cblwwMTdyZXF1aXJlZF9lbnVtXzRcMDMwXDAwNCIgKwogICAgICAiIFwwMDIoXDAxNjI1LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZE5vTSIgKwogICAgICAiYXNrTXVsdGkuTmVzdGVkRW51bVwwMjJcMDEzXG5cMDAzYV8zXDAzMFwwMDMgXDAwMShcMDA1XDAyMk5cblwwMTdyZXF1IiArCiAgICAgICJpcmVkX2VudW1fMlwwMzBcMDAyIFwwMDIoXDAxNjI1LnByb3RvYnVmX3VuaXR0ZXN0LlRlIiArCiAgICAgICJzdFJlcXVpcmVkTm9NYXNrTXVsdGkuTmVzdGVkRW51bVwwMjI3XG5cMDE3cmVxdSIgKwogICAgICAiaXJlZF9lbnVtXzFcMDMwXDAwMSBcMDAyKFwwMTYyXDAzNi5wcm90b2J1Zl91bml0dGVzdC5GbyIgKwogICAgICAicmVpZ25FbnVtXCI4XG5cbk5lc3RlZEVudW1cMDIyXDAxN1xuXDAxM1VOU1BFQ0lGSUVEXDAyMFwwMDAiICsKICAgICAgIlwwMjJcMDA3XG5cMDAzRk9PXDAyMFwwMDFcMDIyXDAwN1xuXDAwM0JBUlwwMjBcMDAyXDAyMlwwMDdcblwwMDNCQVpcMDIwZFwiXDIyMlwwMDZcblwwMTRUZXN0UmVxdSIgKwogICAgICAiaXJlZFwwMjJcdFxuXDAwMWFcMDMwXDAwMSBcMDAyKFwwMDVcMDIyXDAxNlxuXDAwNmR1bW15MlwwMzBcMDAyIFwwMDEoXDAwNVwwMjJcdFxuXDAwMWJcMDMwXDAwMyBcMDAyIiArCiAgICAgICIoXDAwNVwwMjJcMDE2XG5cMDA2ZHVtbXk0XDAzMFwwMDQgXDAwMShcMDA1XDAyMlwwMTZcblwwMDZkdW1teTVcMDMwXDAwNSBcMDAxKFwwMDVcMDIyXDAxNlxuXDAwNmR1IiArCiAgICAgICJtbXk2XDAzMFwwMDYgXDAwMShcMDA1XDAyMlwwMTZcblwwMDZkdW1teTdcMDMwXDAwNyBcMDAxKFwwMDVcMDIyXDAxNlxuXDAwNmR1bW15OFwwMzBcMDEwIFwwMDEiICsKICAgICAgIihcMDA1XDAyMlwwMTZcblwwMDZkdW1teTlcMDMwXHQgXDAwMShcMDA1XDAyMlwwMTdcblwwMDdkdW1teTEwXDAzMFxuIFwwMDEoXDAwNVwwMjJcMDE3XG5cMDA3ZCIgKwogICAgICAidW1teTExXDAzMFwwMTMgXDAwMShcMDA1XDAyMlwwMTdcblwwMDdkdW1teTEyXDAzMFwwMTQgXDAwMShcMDA1XDAyMlwwMTdcblwwMDdkdW1teTEzIiArCiAgICAgICJcMDMwXHIgXDAwMShcMDA1XDAyMlwwMTdcblwwMDdkdW1teTE0XDAzMFwwMTYgXDAwMShcMDA1XDAyMlwwMTdcblwwMDdkdW1teTE1XDAzMFwwMTcgXDAwMShcMDA1IiArCiAgICAgICJcMDIyXDAxN1xuXDAwN2R1bW15MTZcMDMwXDAyMCBcMDAxKFwwMDVcMDIyXDAxN1xuXDAwN2R1bW15MTdcMDMwXDAyMSBcMDAxKFwwMDVcMDIyXDAxN1xuXDAwN2R1IiArCiAgICAgICJtbXkxOFwwMzBcMDIyIFwwMDEoXDAwNVwwMjJcMDE3XG5cMDA3ZHVtbXkxOVwwMzBcMDIzIFwwMDEoXDAwNVwwMjJcMDE3XG5cMDA3ZHVtbXkyMFwwMzAiICsKICAgICAgIlwwMjQgXDAwMShcMDA1XDAyMlwwMTdcblwwMDdkdW1teTIxXDAzMFwwMjUgXDAwMShcMDA1XDAyMlwwMTdcblwwMDdkdW1teTIyXDAzMFwwMjYgXDAwMShcMDA1XDAyMiIgKwogICAgICAiXDAxN1xuXDAwN2R1bW15MjNcMDMwXDAyNyBcMDAxKFwwMDVcMDIyXDAxN1xuXDAwN2R1bW15MjRcMDMwXDAzMCBcMDAxKFwwMDVcMDIyXDAxN1xuXDAwN2R1bSIgKwogICAgICAibXkyNVwwMzBcMDMxIFwwMDEoXDAwNVwwMjJcMDE3XG5cMDA3ZHVtbXkyNlwwMzBcMDMyIFwwMDEoXDAwNVwwMjJcMDE3XG5cMDA3ZHVtbXkyN1wwMzBcMDMzIiArCiAgICAgICIgXDAwMShcMDA1XDAyMlwwMTdcblwwMDdkdW1teTI4XDAzMFwwMzQgXDAwMShcMDA1XDAyMlwwMTdcblwwMDdkdW1teTI5XDAzMFwwMzUgXDAwMShcMDA1XDAyMlwwMTciICsKICAgICAgIlxuXDAwN2R1bW15MzBcMDMwXDAzNiBcMDAxKFwwMDVcMDIyXDAxN1xuXDAwN2R1bW15MzFcMDMwXDAzNyBcMDAxKFwwMDVcMDIyXDAxN1xuXDAwN2R1bW0iICsKICAgICAgInkzMlwwMzAgIFwwMDEoXDAwNVwwMjJcdFxuXDAwMWNcMDMwISBcMDAyKFwwMDVcMDIyO1xuXDAyMG9wdGlvbmFsX2ZvcmVpZ24iICsKICAgICAgIlwwMzBcIiBcMDAxKFwwMTMyIS5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnIiArCiAgICAgICJlMlZcblwwMDZzaW5nbGVcMDIyJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRSIgKwogICAgICAieHRlbnNpb25zXDAzMFwzNTBcMDA3IFwwMDEoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlRlcyIgKwogICAgICAidFJlcXVpcmVkMlVcblwwMDVtdWx0aVwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlQiICsKICAgICAgImVzdEFsbEV4dGVuc2lvbnNcMDMwXDM1MVwwMDcgXDAwMyhcMDEzMlwwMzcucHJvdG9idWZfdW5pdHQiICsKICAgICAgImVzdC5UZXN0UmVxdWlyZWRcIlwzNDRcMDAxXG5cMDIzVGVzdFJlcXVpcmVkRm9yZWlnbiIgKwogICAgICAiXDAyMjlcblwwMjBvcHRpb25hbF9tZXNzYWdlXDAzMFwwMDEgXDAwMShcMDEzMlwwMzcucHJvdG9idWZfdW4iICsKICAgICAgIml0dGVzdC5UZXN0UmVxdWlyZWRcMDIyOVxuXDAyMHJlcGVhdGVkX21lc3NhZ2VcMDMwIiArCiAgICAgICJcMDAyIFwwMDMoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZFwwMjJcciIgKwogICAgICAiXG5cMDA1ZHVtbXlcMDMwXDAwMyBcMDAxKFwwMDVcMDIySFxuXDAyNW9wdGlvbmFsX2xhenlfbWVzc2FnZVwwMzBcMDA0IiArCiAgICAgICIgXDAwMShcMDEzMiUucHJvdG9idWZfdW5pdHRlc3QuTmVzdGVkVGVzdEFsbFR5IiArCiAgICAgICJwZXNCXDAwMihcMDAxXCJcMzA2XDAwMVxuXDAyM1Rlc3RSZXF1aXJlZE1lc3NhZ2VcMDIyOVxuXDAyMG9wdGlvIiArCiAgICAgICJuYWxfbWVzc2FnZVwwMzBcMDAxIFwwMDEoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlRlIiArCiAgICAgICJzdFJlcXVpcmVkXDAyMjlcblwwMjByZXBlYXRlZF9tZXNzYWdlXDAzMFwwMDIgXDAwMyhcMDEzMlwwMzcucCIgKwogICAgICAicm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRcMDIyOVxuXDAyMHJlcXVpcmUiICsKICAgICAgImRfbWVzc2FnZVwwMzBcMDAzIFwwMDIoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3QiICsKICAgICAgIlJlcXVpcmVkXCJcMjYzXDAwM1xuXDAzMVRlc3ROZXN0ZWRSZXF1aXJlZEZvcmVpZ25cMDIyOyIgKwogICAgICAiXG5cMDA1Y2hpbGRcMDMwXDAwMSBcMDAxKFwwMTMyLC5wcm90b2J1Zl91bml0dGVzdC5UZXN0TmUiICsKICAgICAgInN0ZWRSZXF1aXJlZEZvcmVpZ25cMDIyN1xuXDAwN3BheWxvYWRcMDMwXDAwMiBcMDAxKFwwMTMyJi5wIiArCiAgICAgICJyb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZEZvcmVpZ25cMDIyXHJcblwwMDUiICsKICAgICAgImR1bW15XDAzMFwwMDMgXDAwMShcMDA1XDAyMjpcblxycmVxdWlyZWRfZW51bVwwMzBcMDA1IFwwMDEoXDAxMzIjLnBybyIgKwogICAgICAidG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkRW51bVwwMjJIXG5cMDI1cmVxdWkiICsKICAgICAgInJlZF9lbnVtX25vX21hc2tcMDMwXDAwNiBcMDAxKFwwMTMyKS5wcm90b2J1Zl91bml0dGUiICsKICAgICAgInN0LlRlc3RSZXF1aXJlZEVudW1Ob01hc2tcMDIyRVxuXDAyM3JlcXVpcmVkX2VuIiArCiAgICAgICJ1bV9tdWx0aVwwMzBcMDA3IFwwMDEoXDAxMzIoLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSIiArCiAgICAgICJlcXVpcmVkRW51bU11bHRpXDAyMkRcblwwMjByZXF1aXJlZF9ub19tYXNrXDAzMFx0IFwwMDEiICsKICAgICAgIihcMDEzMioucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJlcXVpcmVkTm9NYXMiICsKICAgICAgImtNdWx0aVwiWlxuXDAyMVRlc3RGb3JlaWduTmVzdGVkXDAyMkVcblwwMTZmb3JlaWduX24iICsKICAgICAgImVzdGVkXDAzMFwwMDEgXDAwMShcMDEzMi0ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFQiICsKICAgICAgInlwZXMuTmVzdGVkTWVzc2FnZVwiXDAyMlxuXDAyMFRlc3RFbXB0eU1lc3NhZ2VcIioiICsKICAgICAgIlxuXDAzNlRlc3RFbXB0eU1lc3NhZ2VXaXRoRXh0ZW5zaW9ucypcMDEwXDAxMFwwMDFcMDIwXDIwMFwyMDBcMjAwIiArCiAgICAgICJcMjAwXDAwMlwiWVxuXDAyN1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlXDAzMj5cblxyTmVzdGVkTSIgKwogICAgICAiZXNzYWdlXDAyMlxuXG5cMDAyYmJcMDMwXDAwMSBcMDAxKFwwMDVcMDMyIVxuXDAyM05lc3RlZE5lc3RlZE1lc3NhZyIgKwogICAgICAiZVwwMjJcblxuXDAwMmNjXDAzMFwwMDEgXDAwMShcMDA1XCI3XG5cMDMzVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmEiICsKICAgICAgIm5nZXMqXDAwNFwwMTAqXDAyMCsqXDAwNlwwMTBcMjU3IFwwMjBcMjI0ISpcblwwMTBcMjAwXDIwMFwwMDRcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDJcIjRcblwwMzBUZXN0UmUiICsKICAgICAgImFsbHlMYXJnZVRhZ051bWJlclwwMjJcdFxuXDAwMWFcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXHJcblwwMDJiYlwwMzBcMzc3XDM3N1wzNzdcMTc3IiArCiAgICAgICIgXDAwMShcMDA1XCJVXG5cMDI0VGVzdFJlY3Vyc2l2ZU1lc3NhZ2VcMDIyMlxuXDAwMWFcMDMwXDAwMSBcMDAxKFwwMTMyIiArCiAgICAgICJcJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVjdXJzaXZlTWVzc2FnZSIgKwogICAgICAiXDAyMlx0XG5cMDAxaVwwMzBcMDAyIFwwMDEoXDAwNVwiXDM0NlwwMDNcblwwMjRUZXN0TXV0dWFsUmVjdXJzaW9uQVwwMjIzXG5cMDAyIiArCiAgICAgICJiYlwwMzBcMDAxIFwwMDEoXDAxMzJcJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUiIgKwogICAgICAiZWN1cnNpb25CXDAyMkJcblwwMTBzdWJncm91cFwwMzBcMDAyIFwwMDEoXG4yMC5wcm90b2J1Zl91IiArCiAgICAgICJuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BLlN1Ykdyb3VwXDAyMkRcbiIgKwogICAgICAiXHRzdWJncm91cHJcMDMwXDAwNSBcMDAzKFxuMjEucHJvdG9idWZfdW5pdHRlc3QuVGVzIiArCiAgICAgICJ0TXV0dWFsUmVjdXJzaW9uQS5TdWJHcm91cFJcMDMyQFxuXG5TdWJNZXNzYWciICsKICAgICAgImVcMDIyMlxuXDAwMWJcMDMwXDAwMSBcMDAxKFwwMTMyXCcucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dCIgKwogICAgICAidWFsUmVjdXJzaW9uQlwwMzJcMjE1XDAwMVxuXDAxMFN1Ykdyb3VwXDAyMkdcblwwMTNzdWJfbWVzc2FnIiArCiAgICAgICJlXDAzMFwwMDMgXDAwMShcMDEzMjIucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVhbFJlIiArCiAgICAgICJjdXJzaW9uQS5TdWJNZXNzYWdlXDAyMjhcblwwMTdub3RfaW5fdGhpc19zY2NcMDMwXDAwNCIgKwogICAgICAiIFwwMDEoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wwMzI9XG4iICsKICAgICAgIlx0U3ViR3JvdXBSXDAyMjBcblwwMDdwYXlsb2FkXDAzMFwwMDYgXDAwMShcMDEzMlwwMzcucHJvdG9idWZfdSIgKwogICAgICAibml0dGVzdC5UZXN0QWxsVHlwZXNcImJcblwwMjRUZXN0TXV0dWFsUmVjdXJzIiArCiAgICAgICJpb25CXDAyMjJcblwwMDFhXDAzMFwwMDEgXDAwMShcMDEzMlwnLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3QiICsKICAgICAgIk11dHVhbFJlY3Vyc2lvbkFcMDIyXDAyNlxuXDAxNm9wdGlvbmFsX2ludDMyXDAzMFwwMDIgXDAwMShcMDA1IiArCiAgICAgICJcIlwzMTJcMDAxXG5cMDIxVGVzdElzSW5pdGlhbGl6ZWRcMDIyRFxuXDAxM3N1Yl9tZXNzYWdlXDAzMFwwMDEgIiArCiAgICAgICJcMDAxKFwwMTMyLy5wcm90b2J1Zl91bml0dGVzdC5UZXN0SXNJbml0aWFsaXplIiArCiAgICAgICJkLlN1Yk1lc3NhZ2VcMDMyb1xuXG5TdWJNZXNzYWdlXDAyMkpcblwwMTBzdWJncm91cFwwMzBcMDAxIiArCiAgICAgICIgXDAwMShcbjI4LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RJc0luaXRpYWxpeiIgKwogICAgICAiZWQuU3ViTWVzc2FnZS5TdWJHcm91cFwwMzJcMDI1XG5cMDEwU3ViR3JvdXBcMDIyXHRcblwwMDFpXDAzMCIgKwogICAgICAiXDAwMiBcMDAyKFwwMDVcIlwyNjNcMDAxXG5cMDIyVGVzdER1cEZpZWxkTnVtYmVyXDAyMlx0XG5cMDAxYVwwMzBcMDAxIFwwMDEoXDAwNVwwMjIiICsKICAgICAgIjZcblwwMDNmb29cMDMwXDAwMiBcMDAxKFxuMikucHJvdG9idWZfdW5pdHRlc3QuVGVzdER1cCIgKwogICAgICAiRmllbGROdW1iZXIuRm9vXDAyMjZcblwwMDNiYXJcMDMwXDAwMyBcMDAxKFxuMikucHJvdG9idWZfIiArCiAgICAgICJ1bml0dGVzdC5UZXN0RHVwRmllbGROdW1iZXIuQmFyXDAzMlwwMjBcblwwMDNGb29cMDIyXHQiICsKICAgICAgIlxuXDAwMWFcMDMwXDAwMSBcMDAxKFwwMDVcMDMyXDAyMFxuXDAwM0JhclwwMjJcdFxuXDAwMWFcMDMwXDAwMSBcMDAxKFwwMDVcIkxcblwwMjBUZXN0RWFnZXIiICsKICAgICAgIk1lc3NhZ2VcMDIyOFxuXDAxM3N1Yl9tZXNzYWdlXDAzMFwwMDEgXDAwMShcMDEzMlwwMzcucHJvdG9idWZfIiArCiAgICAgICJ1bml0dGVzdC5UZXN0QWxsVHlwZXNCXDAwMihcMDAwXCJLXG5cMDE3VGVzdExhenlNZXMiICsKICAgICAgInNhZ2VcMDIyOFxuXDAxM3N1Yl9tZXNzYWdlXDAzMFwwMDEgXDAwMShcMDEzMlwwMzcucHJvdG9idWZfdW5pIiArCiAgICAgICJ0dGVzdC5UZXN0QWxsVHlwZXNCXDAwMihcMDAxXCJXXG5cMDI3VGVzdExhenlNZXNzYWciICsKICAgICAgImVSZXBlYXRlZFwwMjI8XG5cMDIwcmVwZWF0ZWRfbWVzc2FnZVwwMzBcMDAxIFwwMDMoXDAxMzJcIi5wciIgKwogICAgICAib3RvYnVmX3VuaXR0ZXN0LlRlc3RMYXp5TWVzc2FnZVwiXDIxN1wwMDJcblwwMjJUZXN0IiArCiAgICAgICJFYWdlck1heWJlTGF6eVwwMjI0XG5cMDEzbWVzc2FnZV9mb29cMDMwXDAwMSBcMDAxKFwwMTMyXDAzNy5wciIgKwogICAgICAib3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wwMjI0XG5cMDEzbWVzc2FnZV8iICsKICAgICAgImJhclwwMzBcMDAyIFwwMDEoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXAiICsKICAgICAgImVzXDAyMkhcblwwMTNtZXNzYWdlX2JhelwwMzBcMDAzIFwwMDEoXDAxMzIzLnByb3RvYnVmX3VuaXR0IiArCiAgICAgICJlc3QuVGVzdEVhZ2VyTWF5YmVMYXp5Lk5lc3RlZE1lc3NhZ2VcMDMyQ1xuXHIiICsKICAgICAgIk5lc3RlZE1lc3NhZ2VcMDIyMlxuXDAwNnBhY2tlZFwwMzBcMDAxIFwwMDEoXDAxMzJcIi5wcm90b2J1ZiIgKwogICAgICAiX3VuaXR0ZXN0LlRlc3RQYWNrZWRUeXBlc1wiXDIwMFwwMDJcblwwMzBUZXN0TmVzdGVkIiArCiAgICAgICJNZXNzYWdlSGFzQml0c1wwMjJaXG5cMDI3b3B0aW9uYWxfbmVzdGVkX21lc3NhZyIgKwogICAgICAiZVwwMzBcMDAxIFwwMDEoXDAxMzI5LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZSIgKwogICAgICAic3NhZ2VIYXNCaXRzLk5lc3RlZE1lc3NhZ2VcMDMyXDIwN1wwMDFcblxyTmVzdGVkTWVzIiArCiAgICAgICJzYWdlXDAyMiRcblwwMzRuZXN0ZWRtZXNzYWdlX3JlcGVhdGVkX2ludDMyXDAzMFwwMDEgXDAwMyIgKwogICAgICAiKFwwMDVcMDIyUFxuJW5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfZm9yZWlnbm1lc3MiICsKICAgICAgImFnZVwwMzBcMDAyIFwwMDMoXDAxMzIhLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXMiICsKICAgICAgInNhZ2VcIlwzNDVcMDAzXG5cMDI3VGVzdENhbWVsQ2FzZUZpZWxkTmFtZXNcMDIyXDAyNlxuXDAxNlByaW0iICsKICAgICAgIml0aXZlRmllbGRcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXDAyM1xuXDAxM1N0cmluZ0ZpZWxkXDAzMFwwMDIgXDAwMShcdFwwMjIxXG4iICsKICAgICAgIlx0RW51bUZpZWxkXDAzMFwwMDMgXDAwMShcMDE2MlwwMzYucHJvdG9idWZfdW5pdHRlc3QuRm9yIiArCiAgICAgICJlaWduRW51bVwwMjI3XG5cMDE0TWVzc2FnZUZpZWxkXDAzMFwwMDQgXDAwMShcMDEzMiEucHJvdG9idSIgKwogICAgICAiZl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZVwwMjJcMDM0XG5cMDIwU3RyaW5nUGllY2UiICsKICAgICAgIkZpZWxkXDAzMFwwMDUgXDAwMShcdEJcMDAyXDAxMFwwMDJcMDIyXDAyNVxuXHRDb3JkRmllbGRcMDMwXDAwNiBcMDAxKFx0QlwwMDJcMDEwXDAwMVwwMjJcMDM2IiArCiAgICAgICJcblwwMjZSZXBlYXRlZFByaW1pdGl2ZUZpZWxkXDAzMFwwMDcgXDAwMyhcMDA1XDAyMlwwMzNcblwwMjNSZXBlYXQiICsKICAgICAgImVkU3RyaW5nRmllbGRcMDMwXDAxMCBcMDAzKFx0XDAyMjlcblwwMjFSZXBlYXRlZEVudW1GaWVsZCIgKwogICAgICAiXDAzMFx0IFwwMDMoXDAxNjJcMDM2LnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtXDAyMj8iICsKICAgICAgIlxuXDAyNFJlcGVhdGVkTWVzc2FnZUZpZWxkXDAzMFxuIFwwMDMoXDAxMzIhLnByb3RvYnVmXyIgKwogICAgICAidW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2VcMDIyJFxuXDAzMFJlcGVhdGVkU3RyaW4iICsKICAgICAgImdQaWVjZUZpZWxkXDAzMFwwMTMgXDAwMyhcdEJcMDAyXDAxMFwwMDJcMDIyXDAzNVxuXDAyMVJlcGVhdGVkQ29yZEZpZSIgKwogICAgICAibGRcMDMwXDAxNCBcMDAzKFx0QlwwMDJcMDEwXDAwMVwiXDMyNVwwMDFcblwwMjJUZXN0RmllbGRPcmRlcmluZ3NcMDIyXDAyMVxuXHRtIiArCiAgICAgICJ5X3N0cmluZ1wwMzBcMDEzIFwwMDEoXHRcMDIyXDAxNlxuXDAwNm15X2ludFwwMzBcMDAxIFwwMDEoXDAwM1wwMjJcMDIwXG5cMDEwbXlfZmxvIiArCiAgICAgICJhdFwwMzBlIFwwMDEoXDAwMlwwMjJVXG5cMDI3b3B0aW9uYWxfbmVzdGVkX21lc3NhZ2VcMDMwXDMxMFwwMDEgXDAwMSIgKwogICAgICAiKFwwMTMyMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZyIgKwogICAgICAicy5OZXN0ZWRNZXNzYWdlXDAzMlwnXG5cck5lc3RlZE1lc3NhZ2VcMDIyXG5cblwwMDJvb1wwMzBcMDAyIiArCiAgICAgICIgXDAwMShcMDAzXDAyMlxuXG5cMDAyYmJcMDMwXDAwMSBcMDAxKFwwMDUqXDAwNFwwMTBcMDAyXDAyMFwwMTMqXDAwNFwwMTBcMDE0XDAyMGVcIlwyMzRcMDAxXG5cMDI3VGVzdEV4dCIgKwogICAgICAiZW5zaW9uT3JkZXJpbmdzMVwwMjJcMDIxXG5cdG15X3N0cmluZ1wwMzBcMDAxIFwwMDEoXHQyblxuXDAyM3QiICsKICAgICAgImVzdF9leHRfb3JkZXJpbmdzMVwwMjIlLnByb3RvYnVmX3VuaXR0ZXN0LlQiICsKICAgICAgImVzdEZpZWxkT3JkZXJpbmdzXDAzMFxyIFwwMDEoXDAxMzIqLnByb3RvYnVmX3VuaXR0IiArCiAgICAgICJlc3QuVGVzdEV4dGVuc2lvbk9yZGVyaW5nczFcIlwzMjRcMDAyXG5cMDI3VGVzdEV4dGUiICsKICAgICAgIm5zaW9uT3JkZXJpbmdzMlwwMjJcMDIxXG5cdG15X3N0cmluZ1wwMzBcMDAxIFwwMDEoXHRcMDMyXDI2NVwwMDFcblwwMjdUIiArCiAgICAgICJlc3RFeHRlbnNpb25PcmRlcmluZ3MzXDAyMlwwMjFcblx0bXlfc3RyaW5nXDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlx0MlwyMDZcMDAxXG5cMDIzdGVzdF9leHRfb3JkZXJpbmdzM1wwMjIlLnByb3RvYnVmX3VuaSIgKwogICAgICAidHRlc3QuVGVzdEZpZWxkT3JkZXJpbmdzXDAzMFwwMTYgXDAwMShcMDEzMkIucHJvdG9idSIgKwogICAgICAiZl91bml0dGVzdC5UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMi5UZXN0RSIgKwogICAgICAieHRlbnNpb25PcmRlcmluZ3MzMm5cblwwMjN0ZXN0X2V4dF9vcmRlcmluZ3MiICsKICAgICAgIjJcMDIyJS5wcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MiICsKICAgICAgIlwwMzBcMDE0IFwwMDEoXDAxMzIqLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnNpb24iICsKICAgICAgIk9yZGVyaW5nczJcIlwyNjZcMDA3XG5cMDMwVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzXDAyMiIgKwogICAgICAiP1xuXHJlc2NhcGVkX2J5dGVzXDAzMFwwMDEgXDAwMShcMDE0OihcXDAwMFxcMDAxXFwwMDdcXDAxMCIgKwogICAgICAiXFwwMTRcXG5cXHJcXHRcXDAxM1xcXFxcXFwnXFxcIlxcMzc2XDAyMiBcblwwMTRsYXJnZV91aW50MzIiICsKICAgICAgIlwwMzBcMDAyIFwwMDEoXHI6XG40Mjk0OTY3Mjk1XDAyMipcblwwMTRsYXJnZV91aW50NjRcMDMwXDAwMyBcMDAxKFwwMDQiICsKICAgICAgIjpcMDI0MTg0NDY3NDQwNzM3MDk1NTE2MTVcMDIyIFxuXDAxM3NtYWxsX2ludDMyXDAzMFwwMDQgIiArCiAgICAgICJcMDAxKFwwMDU6XDAxMy0yMTQ3NDgzNjQ3XDAyMilcblwwMTNzbWFsbF9pbnQ2NFwwMzBcMDA1IFwwMDEoXDAwMzpcMDI0LSIgKwogICAgICAiOTIyMzM3MjAzNjg1NDc3NTgwN1wwMjJcJ1xuXDAyMnJlYWxseV9zbWFsbF9pbnQzIiArCiAgICAgICIyXDAzMFwwMjUgXDAwMShcMDA1OlwwMTMtMjE0NzQ4MzY0OFwwMjIwXG5cMDIycmVhbGx5X3NtYWxsX2ludCIgKwogICAgICAiNjRcMDMwXDAyNiBcMDAxKFwwMDM6XDAyNC05MjIzMzcyMDM2ODU0Nzc1ODA4XDAyMlwwMzBcblwwMTN1dGY4X3MiICsKICAgICAgInRyaW5nXDAzMFwwMDYgXDAwMShcdDpcMDAzXDM0MVwyMTBcMjY0XDAyMlwwMjVcblxuemVyb19mbG9hdFwwMzBcMDA3IFwwMDEoXDAwMjpcMDAxMFwwMjIiICsKICAgICAgIlwwMjRcblx0b25lX2Zsb2F0XDAzMFwwMTAgXDAwMShcMDAyOlwwMDExXDAyMlwwMzBcblwwMTNzbWFsbF9mbG9hdFwwMzBcdCBcMDAxIiArCiAgICAgICIoXDAwMjpcMDAzMS41XDAyMlwwMzZcblwwMjJuZWdhdGl2ZV9vbmVfZmxvYXRcMDMwXG4gXDAwMShcMDAyOlwwMDItMVwwMjIiICsKICAgICAgIlwwMzRcblwwMTZuZWdhdGl2ZV9mbG9hdFwwMzBcMDEzIFwwMDEoXDAwMjpcMDA0LTEuNVwwMjJcMDMyXG5cMDEzbGFyZ2VfZiIgKwogICAgICAibG9hdFwwMzBcMDE0IFwwMDEoXDAwMjpcMDA1MmUrMDhcMDIyJFxuXDAyNHNtYWxsX25lZ2F0aXZlX2Zsb2EiICsKICAgICAgInRcMDMwXHIgXDAwMShcMDAyOlwwMDYtOGUtMjhcMDIyXDAyN1xuXG5pbmZfZG91YmxlXDAzMFwwMTYgXDAwMShcMDAxOlwwMDNpbmYiICsKICAgICAgIlwwMjJcMDM0XG5cMDE2bmVnX2luZl9kb3VibGVcMDMwXDAxNyBcMDAxKFwwMDE6XDAwNC1pbmZcMDIyXDAyN1xuXG5uYW5fZG8iICsKICAgICAgInVibGVcMDMwXDAyMCBcMDAxKFwwMDE6XDAwM25hblwwMjJcMDI2XG5cdGluZl9mbG9hdFwwMzBcMDIxIFwwMDEoXDAwMjpcMDAzaW5mXDAyMiIgKwogICAgICAiXDAzM1xuXHJuZWdfaW5mX2Zsb2F0XDAzMFwwMjIgXDAwMShcMDAyOlwwMDQtaW5mXDAyMlwwMjZcblx0bmFuX2Zsb2EiICsKICAgICAgInRcMDMwXDAyMyBcMDAxKFwwMDI6XDAwM25hblwwMjIrXG5cMDE0Y3BwX3RyaWdyYXBoXDAzMFwwMjQgXDAwMShcdDpcMDI1PyA/ICIgKwogICAgICAiPz8gPz8gPz8/ID8/LyA/Py1cMDIyIFxuXDAyMHN0cmluZ193aXRoX3plcm9cMDMwXDAyNyAiICsKICAgICAgIlwwMDEoXHQ6XDAwNmhlbFwwMDBsb1wwMjJcIlxuXDAxN2J5dGVzX3dpdGhfemVyb1wwMzBcMDMwIFwwMDEoXDAxNDpcdHdvIiArCiAgICAgICJyXFwwMDBsZFwwMjIoXG5cMDI2c3RyaW5nX3BpZWNlX3dpdGhfemVyb1wwMzBcMDMxIFwwMDEoXHQ6IiArCiAgICAgICJcMDA0YWJcMDAwY0JcMDAyXDAxMFwwMDJcMDIyIFxuXDAxNmNvcmRfd2l0aF96ZXJvXDAzMFwwMzIgXDAwMShcdDpcMDA0MTJcMDAwM0IiICsKICAgICAgIlwwMDJcMDEwXDAwMVwwMjImXG5cMDIycmVwbGFjZW1lbnRfc3RyaW5nXDAzMFwwMzMgXDAwMShcdDpcbiR7dW5rbm8iICsKICAgICAgIndufVwiS1xuXDAyMVNwYXJzZUVudW1NZXNzYWdlXDAyMjZcblwwMTNzcGFyc2VfZW51bVwwMzAiICsKICAgICAgIlwwMDEgXDAwMShcMDE2MiEucHJvdG9idWZfdW5pdHRlc3QuVGVzdFNwYXJzZUVudW0iICsKICAgICAgIlwiXDAzMVxuXHRPbmVTdHJpbmdcMDIyXDAxNFxuXDAwNGRhdGFcMDMwXDAwMSBcMDAxKFx0XCJcMDMyXG5cbk1vcmVTdHJpbiIgKwogICAgICAiZ1wwMjJcMDE0XG5cMDA0ZGF0YVwwMzBcMDAxIFwwMDMoXHRcIlwwMzBcblwwMTBPbmVCeXRlc1wwMjJcMDE0XG5cMDA0ZGF0YVwwMzBcMDAxIFwwMDEoIiArCiAgICAgICJcMDE0XCJcMDMxXG5cdE1vcmVCeXRlc1wwMjJcMDE0XG5cMDA0ZGF0YVwwMzBcMDAxIFwwMDMoXDAxNFwiXDM1M1wwMDNcblwwMjJNYW55T3B0IiArCiAgICAgICJpb25hbFN0cmluZ1wwMjJcMDE0XG5cMDA0c3RyMVwwMzBcMDAxIFwwMDEoXHRcMDIyXDAxNFxuXDAwNHN0cjJcMDMwXDAwMiBcMDAxKFx0XDAyMiIgKwogICAgICAiXDAxNFxuXDAwNHN0cjNcMDMwXDAwMyBcMDAxKFx0XDAyMlwwMTRcblwwMDRzdHI0XDAzMFwwMDQgXDAwMShcdFwwMjJcMDE0XG5cMDA0c3RyNVwwMzBcMDA1IFwwMDEoIiArCiAgICAgICJcdFwwMjJcMDE0XG5cMDA0c3RyNlwwMzBcMDA2IFwwMDEoXHRcMDIyXDAxNFxuXDAwNHN0cjdcMDMwXDAwNyBcMDAxKFx0XDAyMlwwMTRcblwwMDRzdHI4XDAzMFwwMTAgIiArCiAgICAgICJcMDAxKFx0XDAyMlwwMTRcblwwMDRzdHI5XDAzMFx0IFwwMDEoXHRcMDIyXHJcblwwMDVzdHIxMFwwMzBcbiBcMDAxKFx0XDAyMlxyXG5cMDA1c3RyMSIgKwogICAgICAiMVwwMzBcMDEzIFwwMDEoXHRcMDIyXHJcblwwMDVzdHIxMlwwMzBcMDE0IFwwMDEoXHRcMDIyXHJcblwwMDVzdHIxM1wwMzBcciBcMDAxKFx0XDAyMlxyXG4iICsKICAgICAgIlwwMDVzdHIxNFwwMzBcMDE2IFwwMDEoXHRcMDIyXHJcblwwMDVzdHIxNVwwMzBcMDE3IFwwMDEoXHRcMDIyXHJcblwwMDVzdHIxNlwwMzBcMDIwIFwwMDEiICsKICAgICAgIihcdFwwMjJcclxuXDAwNXN0cjE3XDAzMFwwMjEgXDAwMShcdFwwMjJcclxuXDAwNXN0cjE4XDAzMFwwMjIgXDAwMShcdFwwMjJcclxuXDAwNXN0cjEiICsKICAgICAgIjlcMDMwXDAyMyBcMDAxKFx0XDAyMlxyXG5cMDA1c3RyMjBcMDMwXDAyNCBcMDAxKFx0XDAyMlxyXG5cMDA1c3RyMjFcMDMwXDAyNSBcMDAxKFx0XDAyMlxyXG4iICsKICAgICAgIlwwMDVzdHIyMlwwMzBcMDI2IFwwMDEoXHRcMDIyXHJcblwwMDVzdHIyM1wwMzBcMDI3IFwwMDEoXHRcMDIyXHJcblwwMDVzdHIyNFwwMzBcMDMwIFwwMDEiICsKICAgICAgIihcdFwwMjJcclxuXDAwNXN0cjI1XDAzMFwwMzEgXDAwMShcdFwwMjJcclxuXDAwNXN0cjI2XDAzMFwwMzIgXDAwMShcdFwwMjJcclxuXDAwNXN0cjIiICsKICAgICAgIjdcMDMwXDAzMyBcMDAxKFx0XDAyMlxyXG5cMDA1c3RyMjhcMDMwXDAzNCBcMDAxKFx0XDAyMlxyXG5cMDA1c3RyMjlcMDMwXDAzNSBcMDAxKFx0XDAyMlxyXG4iICsKICAgICAgIlwwMDVzdHIzMFwwMzBcMDM2IFwwMDEoXHRcMDIyXHJcblwwMDVzdHIzMVwwMzBcMDM3IFwwMDEoXHRcMDIyXHJcblwwMDVzdHIzMlwwMzAgIFwwMDEiICsKICAgICAgIihcdFwiXDAzNFxuXDAxNEludDMyTWVzc2FnZVwwMjJcMDE0XG5cMDA0ZGF0YVwwMzBcMDAxIFwwMDEoXDAwNVwiXDAzNVxuXHJVaW50IiArCiAgICAgICIzMk1lc3NhZ2VcMDIyXDAxNFxuXDAwNGRhdGFcMDMwXDAwMSBcMDAxKFxyXCJcMDM0XG5cMDE0SW50NjRNZXNzYWdlXDAyMiIgKwogICAgICAiXDAxNFxuXDAwNGRhdGFcMDMwXDAwMSBcMDAxKFwwMDNcIlwwMzVcblxyVWludDY0TWVzc2FnZVwwMjJcMDE0XG5cMDA0ZGF0YVwwMzBcMDAxIiArCiAgICAgICIgXDAwMShcMDA0XCJcMDMzXG5cMDEzQm9vbE1lc3NhZ2VcMDIyXDAxNFxuXDAwNGRhdGFcMDMwXDAwMSBcMDAxKFwwMTBcIlwzMjBcMDAxXG5cdFRlIiArCiAgICAgICJzdE9uZW9mXDAyMlwwMjFcblwwMDdmb29faW50XDAzMFwwMDEgXDAwMShcMDA1SFwwMDBcMDIyXDAyNFxuXG5mb29fc3RyaW5nIiArCiAgICAgICJcMDMwXDAwMiBcMDAxKFx0SFwwMDBcMDIyNlxuXDAxM2Zvb19tZXNzYWdlXDAzMFwwMDMgXDAwMShcMDEzMlwwMzcucHJvdG9idWYiICsKICAgICAgIl91bml0dGVzdC5UZXN0QWxsVHlwZXNIXDAwMFwwMjI5XG5cMDEwZm9vZ3JvdXBcMDMwXDAwNCBcMDAxIiArCiAgICAgICIoXG4yJS5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YuRm9vR3JvdSIgKwogICAgICAicEhcMDAwXDAzMiBcblwwMTBGb29Hcm91cFwwMjJcdFxuXDAwMWFcMDMwXDAwNSBcMDAxKFwwMDVcMDIyXHRcblwwMDFiXDAzMFwwMDYgXDAwMShcdEJcMDA1XG4iICsKICAgICAgIlwwMDNmb29cIlwzNDdcMDAxXG5cMDM0VGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZVwwMjJcMDE3XG4iICsKICAgICAgIlwwMDdmb29faW50XDAzMFwwMDEgXDAwMShcMDA1XDAyMlwwMjJcblxuZm9vX3N0cmluZ1wwMzBcMDAyIFwwMDEoXHRcMDIyNFxuXDAxM2ZvIiArCiAgICAgICJvX21lc3NhZ2VcMDMwXDAwMyBcMDAxKFwwMTMyXDAzNy5wcm90b2J1Zl91bml0dGVzdC5UZXN0IiArCiAgICAgICJBbGxUeXBlc1wwMjJKXG5cMDEwZm9vZ3JvdXBcMDMwXDAwNCBcMDAxKFxuMjgucHJvdG9idWZfdW4iICsKICAgICAgIml0dGVzdC5UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlLkZvb0ciICsKICAgICAgInJvdXBcMDMyIFxuXDAxMEZvb0dyb3VwXDAyMlx0XG5cMDAxYVwwMzBcMDA1IFwwMDEoXDAwNVwwMjJcdFxuXDAwMWJcMDMwXDAwNiBcMDAxKFx0XCJcMzYzIiArCiAgICAgICJcMDA3XG5cblRlc3RPbmVvZjJcMDIyXDAyMVxuXDAwN2Zvb19pbnRcMDMwXDAwMSBcMDAxKFwwMDVIXDAwMFwwMjJcMDI0XG5cbmZvb18iICsKICAgICAgInN0cmluZ1wwMzBcMDAyIFwwMDEoXHRIXDAwMFwwMjJcMDI2XG5cMDEwZm9vX2NvcmRcMDMwXDAwMyBcMDAxKFx0QlwwMDJcMDEwXDAwMUhcMDAwXDAyMlwwMzYiICsKICAgICAgIlxuXDAyMGZvb19zdHJpbmdfcGllY2VcMDMwXDAwNCBcMDAxKFx0QlwwMDJcMDEwXDAwMkhcMDAwXDAyMlwwMjNcblx0Zm9vX2J5IiArCiAgICAgICJ0ZXNcMDMwXDAwNSBcMDAxKFwwMTRIXDAwMFwwMjI8XG5cMDEwZm9vX2VudW1cMDMwXDAwNiBcMDAxKFwwMTYyKC5wcm90b2J1ZiIgKwogICAgICAiX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bUhcMDAwXDAyMkJcblwwMTNmb28iICsKICAgICAgIl9tZXNzYWdlXDAzMFwwMDcgXDAwMShcMDEzMisucHJvdG9idWZfdW5pdHRlc3QuVGVzdE8iICsKICAgICAgIm5lb2YyLk5lc3RlZE1lc3NhZ2VIXDAwMFwwMjI6XG5cMDEwZm9vZ3JvdXBcMDMwXDAxMCBcMDAxKFxuMiIgKwogICAgICAiJi5wcm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLkZvb0dyb3VwSCIgKwogICAgICAiXDAwMFwwMjJLXG5cMDIwZm9vX2xhenlfbWVzc2FnZVwwMzBcMDEzIFwwMDEoXDAxMzIrLnByb3RvYnVmX3UiICsKICAgICAgIm5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlQlwwMDIoXDAwMUhcMDAwXDAyMlwwMzQiICsKICAgICAgIlxuXDAxNmZvb19ieXRlc19jb3JkXDAzMFwwMzYgXDAwMShcMDE0QlwwMDJcMDEwXDAwMUhcMDAwXDAyMlwwMjRcblwwMDdiYXJfaW50XDAzMCIgKwogICAgICAiXDAxNCBcMDAxKFwwMDU6XDAwMTVIXDAwMVwwMjJcMDM0XG5cbmJhcl9zdHJpbmdcMDMwXHIgXDAwMShcdDpcMDA2U1RSSU5HSFwwMDEiICsKICAgICAgIlwwMjJcMDM0XG5cMDEwYmFyX2NvcmRcMDMwXDAxNiBcMDAxKFx0OlwwMDRDT1JEQlwwMDJcMDEwXDAwMUhcMDAxXDAyMiZcblwwMjBiYXJfc3QiICsKICAgICAgInJpbmdfcGllY2VcMDMwXDAxNyBcMDAxKFx0OlwwMDZTUElFQ0VCXDAwMlwwMTBcMDAySFwwMDFcMDIyXDAzMlxuXHRiYXJfYnkiICsKICAgICAgInRlc1wwMzBcMDIwIFwwMDEoXDAxNDpcMDA1QllURVNIXDAwMVwwMjJBXG5cMDEwYmFyX2VudW1cMDMwXDAyMSBcMDAxKFwwMTYyKC5wIiArCiAgICAgICJyb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZjIuTmVzdGVkRW51bTpcMDAzIiArCiAgICAgICJCQVJIXDAwMVwwMjIpXG5cMDM1YmFyX3N0cmluZ193aXRoX2VtcHR5X2RlZmF1bHRcMDMwXDAyNCIgKwogICAgICAiIFwwMDEoXHQ6XDAwMEhcMDAxXDAyMitcblwwMzNiYXJfY29yZF93aXRoX2VtcHR5X2RlZmF1bHRcMDMwIiArCiAgICAgICJcMDI1IFwwMDEoXHQ6XDAwMEJcMDAyXDAxMFwwMDFIXDAwMVwwMjIzXG4jYmFyX3N0cmluZ19waWVjZV93aXRoX2UiICsKICAgICAgIm1wdHlfZGVmYXVsdFwwMzBcMDI2IFwwMDEoXHQ6XDAwMEJcMDAyXDAxMFwwMDJIXDAwMVwwMjIoXG5cMDM0YmFyX2J5dGVzXyIgKwogICAgICAid2l0aF9lbXB0eV9kZWZhdWx0XDAzMFwwMjcgXDAwMShcMDE0OlwwMDBIXDAwMVwwMjJcMDE3XG5cMDA3YmF6X2ludFwwMzAiICsKICAgICAgIlwwMjIgXDAwMShcMDA1XDAyMlwwMjdcblxuYmF6X3N0cmluZ1wwMzBcMDIzIFwwMDEoXHQ6XDAwM0JBWlwwMzIgXG5cMDEwRm9vR3JvIiArCiAgICAgICJ1cFwwMjJcdFxuXDAwMWFcMDMwXHQgXDAwMShcMDA1XDAyMlx0XG5cMDAxYlwwMzBcbiBcMDAxKFx0XDAzMjNcblxyTmVzdGVkTWVzc2FnIiArCiAgICAgICJlXDAyMlwwMTdcblwwMDdtb29faW50XDAzMFwwMDEgXDAwMShcMDAzXDAyMlwwMjFcblx0Y29yZ2VfaW50XDAzMFwwMDIgXDAwMyhcMDA1XCJcJ1xuIiArCiAgICAgICJcbk5lc3RlZEVudW1cMDIyXDAwN1xuXDAwM0ZPT1wwMjBcMDAxXDAyMlwwMDdcblwwMDNCQVJcMDIwXDAwMlwwMjJcMDA3XG5cMDAzQkFaXDAyMFwwMDNCXDAwNSIgKwogICAgICAiXG5cMDAzZm9vQlwwMDVcblwwMDNiYXJcIlwyMTRcMDAyXG5cMDIxVGVzdFJlcXVpcmVkT25lb2ZcMDIyXDAyMVxuXDAwN2ZvIiArCiAgICAgICJvX2ludFwwMzBcMDAxIFwwMDEoXDAwNUhcMDAwXDAyMlwwMjRcblxuZm9vX3N0cmluZ1wwMzBcMDAyIFwwMDEoXHRIXDAwMFwwMjJJXG5cMDEzZiIgKwogICAgICAib29fbWVzc2FnZVwwMzBcMDAzIFwwMDEoXDAxMzIyLnByb3RvYnVmX3VuaXR0ZXN0LlRlcyIgKwogICAgICAidFJlcXVpcmVkT25lb2YuTmVzdGVkTWVzc2FnZUhcMDAwXDAyMlJcblwwMjBmb29fbGEiICsKICAgICAgInp5X21lc3NhZ2VcMDMwXDAwNCBcMDAxKFwwMTMyMi5wcm90b2J1Zl91bml0dGVzdC5UZXMiICsKICAgICAgInRSZXF1aXJlZE9uZW9mLk5lc3RlZE1lc3NhZ2VCXDAwMihcMDAxSFwwMDBcMDMyKFxuXHJOZSIgKwogICAgICAic3RlZE1lc3NhZ2VcMDIyXDAyN1xuXDAxN3JlcXVpcmVkX2RvdWJsZVwwMzBcMDAxIFwwMDIoXDAwMUJcMDA1XG5cMDAzIiArCiAgICAgICJmb29cIlwyNTJcMDAzXG5cMDE3VGVzdFBhY2tlZFR5cGVzXDAyMlwwMzBcblwwMTRwYWNrZWRfaW50MzJcMDMwIiArCiAgICAgICJaIFwwMDMoXDAwNUJcMDAyXDAyMFwwMDFcMDIyXDAzMFxuXDAxNHBhY2tlZF9pbnQ2NFwwMzBbIFwwMDMoXDAwM0JcMDAyXDAyMFwwMDFcMDIyXDAzMVxuXHJwIiArCiAgICAgICJhY2tlZF91aW50MzJcMDMwXFwgXDAwMyhcckJcMDAyXDAyMFwwMDFcMDIyXDAzMVxuXHJwYWNrZWRfdWludDY0XDAzMCIgKwogICAgICAiXSBcMDAzKFwwMDRCXDAwMlwwMjBcMDAxXDAyMlwwMzFcblxycGFja2VkX3NpbnQzMlwwMzBeIFwwMDMoXDAyMUJcMDAyXDAyMFwwMDFcMDIyXDAzMVxuXHIiICsKICAgICAgInBhY2tlZF9zaW50NjRcMDMwXyBcMDAzKFwwMjJCXDAwMlwwMjBcMDAxXDAyMlwwMzJcblwwMTZwYWNrZWRfZml4ZWQzIiArCiAgICAgICIyXDAzMGAgXDAwMyhcMDA3QlwwMDJcMDIwXDAwMVwwMjJcMDMyXG5cMDE2cGFja2VkX2ZpeGVkNjRcMDMwYSBcMDAzKFwwMDZCXDAwMlwwMjBcMDAxXDAyMiIgKwogICAgICAiXDAzM1xuXDAxN3BhY2tlZF9zZml4ZWQzMlwwMzBiIFwwMDMoXDAxN0JcMDAyXDAyMFwwMDFcMDIyXDAzM1xuXDAxN3BhY2tlZF9zIiArCiAgICAgICJmaXhlZDY0XDAzMGMgXDAwMyhcMDIwQlwwMDJcMDIwXDAwMVwwMjJcMDMwXG5cMDE0cGFja2VkX2Zsb2F0XDAzMGQgXDAwMyhcMDAyQiIgKwogICAgICAiXDAwMlwwMjBcMDAxXDAyMlwwMzFcblxycGFja2VkX2RvdWJsZVwwMzBlIFwwMDMoXDAwMUJcMDAyXDAyMFwwMDFcMDIyXDAyN1xuXDAxM3BhY2tlZCIgKwogICAgICAiX2Jvb2xcMDMwZiBcMDAzKFwwMTBCXDAwMlwwMjBcMDAxXDAyMjdcblwwMTNwYWNrZWRfZW51bVwwMzBnIFwwMDMoXDAxNjJcMDM2LnAiICsKICAgICAgInJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW1CXDAwMlwwMjBcMDAxXCJcMzEwXDAwM1xuXDAyMVRlcyIgKwogICAgICAidFVucGFja2VkVHlwZXNcMDIyXDAzMlxuXDAxNnVucGFja2VkX2ludDMyXDAzMFogXDAwMyhcMDA1QlwwMDIiICsKICAgICAgIlwwMjBcMDAwXDAyMlwwMzJcblwwMTZ1bnBhY2tlZF9pbnQ2NFwwMzBbIFwwMDMoXDAwM0JcMDAyXDAyMFwwMDBcMDIyXDAzM1xuXDAxN3VucGFjayIgKwogICAgICAiZWRfdWludDMyXDAzMFxcIFwwMDMoXHJCXDAwMlwwMjBcMDAwXDAyMlwwMzNcblwwMTd1bnBhY2tlZF91aW50NjRcMDMwXSIsCiAgICAgICIgXDAwMyhcMDA0QlwwMDJcMDIwXDAwMFwwMjJcMDMzXG5cMDE3dW5wYWNrZWRfc2ludDMyXDAzMF4gXDAwMyhcMDIxQlwwMDJcMDIwXDAwMFwwMjJcMDMzXG4iICsKICAgICAgIlwwMTd1bnBhY2tlZF9zaW50NjRcMDMwXyBcMDAzKFwwMjJCXDAwMlwwMjBcMDAwXDAyMlwwMzRcblwwMjB1bnBhY2tlZF9mIiArCiAgICAgICJpeGVkMzJcMDMwYCBcMDAzKFwwMDdCXDAwMlwwMjBcMDAwXDAyMlwwMzRcblwwMjB1bnBhY2tlZF9maXhlZDY0XDAzMGEgXDAwMyIgKwogICAgICAiKFwwMDZCXDAwMlwwMjBcMDAwXDAyMlwwMzVcblwwMjF1bnBhY2tlZF9zZml4ZWQzMlwwMzBiIFwwMDMoXDAxN0JcMDAyXDAyMFwwMDBcMDIyXDAzNVxuIiArCiAgICAgICJcMDIxdW5wYWNrZWRfc2ZpeGVkNjRcMDMwYyBcMDAzKFwwMjBCXDAwMlwwMjBcMDAwXDAyMlwwMzJcblwwMTZ1bnBhY2tlZCIgKwogICAgICAiX2Zsb2F0XDAzMGQgXDAwMyhcMDAyQlwwMDJcMDIwXDAwMFwwMjJcMDMzXG5cMDE3dW5wYWNrZWRfZG91YmxlXDAzMGUgXDAwMygiICsKICAgICAgIlwwMDFCXDAwMlwwMjBcMDAwXDAyMlwwMzFcblxydW5wYWNrZWRfYm9vbFwwMzBmIFwwMDMoXDAxMEJcMDAyXDAyMFwwMDBcMDIyOVxuXHJ1bnBhIiArCiAgICAgICJja2VkX2VudW1cMDMwZyBcMDAzKFwwMTYyXDAzNi5wcm90b2J1Zl91bml0dGVzdC5Gb3JlIiArCiAgICAgICJpZ25FbnVtQlwwMDJcMDIwXDAwMFwiIFxuXDAyNFRlc3RQYWNrZWRFeHRlbnNpb25zKlwwMTBcMDEwXDAwMVwwMjAiICsKICAgICAgIlwyMDBcMjAwXDIwMFwyMDBcMDAyXCJcIlxuXDAyNlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMqXDAxMFwwMTBcMDAxXDAyMFwyMDBcMjAwXDIwMFwyMDAiICsKICAgICAgIlwwMDJcIlwyMzFcMDA0XG5cMDI1VGVzdER5bmFtaWNFeHRlbnNpb25zXDAyMlwwMzFcblwwMjBzY2FsYXJfZXgiICsKICAgICAgInRlbnNpb25cMDMwXDMyMFwwMTcgXDAwMShcMDA3XDAyMjdcblwwMTZlbnVtX2V4dGVuc2lvblwwMzBcMzIxXDAxNyBcMDAxKFwwMTYyIiArCiAgICAgICJcMDM2LnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtXDAyMllcblwwMjZkeW5hbSIgKwogICAgICAiaWNfZW51bV9leHRlbnNpb25cMDMwXDMyMlwwMTcgXDAwMShcMDE2MjgucHJvdG9idWZfdW5pdCIgKwogICAgICAidGVzdC5UZXN0RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY0VudW1UeSIgKwogICAgICAicGVcMDIyPVxuXDAyMW1lc3NhZ2VfZXh0ZW5zaW9uXDAzMFwzMjNcMDE3IFwwMDEoXDAxMzIhLnByb3RvYnUiICsKICAgICAgImZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2VcMDIyX1xuXDAzMWR5bmFtaWNfbWVzIiArCiAgICAgICJzYWdlX2V4dGVuc2lvblwwMzBcMzI0XDAxNyBcMDAxKFwwMTMyOy5wcm90b2J1Zl91bml0dGVzIiArCiAgICAgICJ0LlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5hbWljTWVzc2FnZVR5IiArCiAgICAgICJwZVwwMjJcMDMzXG5cMDIycmVwZWF0ZWRfZXh0ZW5zaW9uXDAzMFwzMjVcMDE3IFwwMDMoXHRcMDIyXDAzNVxuXDAyMHBhY2tlIiArCiAgICAgICJkX2V4dGVuc2lvblwwMzBcMzI2XDAxNyBcMDAzKFwwMjFCXDAwMlwwMjBcMDAxXDAzMixcblwwMjJEeW5hbWljTWVzc2FnZSIgKwogICAgICAiVHlwZVwwMjJcMDI2XG5ccmR5bmFtaWNfZmllbGRcMDMwXDI2NFwwMjAgXDAwMShcMDA1XCJHXG5cMDE3RHluYW1pY0UiICsKICAgICAgIm51bVR5cGVcMDIyXDAyMFxuXDAxM0RZTkFNSUNfRk9PXDAyMFwyMzBcMDIxXDAyMlwwMjBcblwwMTNEWU5BTUlDX0JBUiIgKwogICAgICAiXDAyMFwyMzFcMDIxXDAyMlwwMjBcblwwMTNEWU5BTUlDX0JBWlwwMjBcMjMyXDAyMVwifFxuXDAyMlRlc3RSZXBlYXRlZFN0ciIgKwogICAgICAiaW5nXDAyMlwwMzBcblwwMjByZXBlYXRlZF9zdHJpbmcxXDAzMFwwMDEgXDAwMyhcdFwwMjJcMDMwXG5cMDIwcmVwZWF0ZSIgKwogICAgICAiZF9zdHJpbmcyXDAzMFwwMDIgXDAwMyhcdFwwMjJcMDMwXG5cMDIwcmVwZWF0ZWRfYnl0ZXMxMVwwMzBcMDEzIFwwMDMoIiArCiAgICAgICJcMDE0XDAyMlwwMzBcblwwMjByZXBlYXRlZF9ieXRlczEyXDAzMFwwMTQgXDAwMyhcMDE0XCJcMzAwXDAwMVxuI1Rlc3RSZXBlIiArCiAgICAgICJhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXNcMDIyXDAzMFxuXDAyMHJlcGVhdGVkXyIgKwogICAgICAiZml4ZWQzMlwwMzBcMDE0IFwwMDMoXDAwN1wwMjJcMDI2XG5cMDE2cmVwZWF0ZWRfaW50MzJcMDMwXHIgXDAwMyhcMDA1XDAyMlwwMzFcbiIgKwogICAgICAiXDAyMHJlcGVhdGVkX2ZpeGVkNjRcMDMwXDM3NlwwMTcgXDAwMyhcMDA2XDAyMlwwMjdcblwwMTZyZXBlYXRlZF9pbnQiICsKICAgICAgIjY0XDAzMFwzNzdcMDE3IFwwMDMoXDAwM1wwMjJcMDMwXG5cMDE2cmVwZWF0ZWRfZmxvYXRcMDMwXDM3NlwzNzdcMDE3IFwwMDMoXDAwMlwwMjJcMDMxXG5cMDE3ciIgKwogICAgICAiZXBlYXRlZF91aW50NjRcMDMwXDM3N1wzNzdcMDE3IFwwMDMoXDAwNFwiXDM2N1x0XG5cMDIwVGVzdFBhcnNpbmdNZSIgKwogICAgICAicmdlXDAyMjtcblwwMjJyZXF1aXJlZF9hbGxfdHlwZXNcMDMwXDAwMSBcMDAyKFwwMTMyXDAzNy5wcm90b2IiICsKICAgICAgInVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wwMjI7XG5cMDIyb3B0aW9uYWxfYWxsIiArCiAgICAgICJfdHlwZXNcMDMwXDAwMiBcMDAxKFwwMTMyXDAzNy5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsIiArCiAgICAgICJUeXBlc1wwMjI7XG5cMDIycmVwZWF0ZWRfYWxsX3R5cGVzXDAzMFwwMDMgXDAwMyhcMDEzMlwwMzcucHJvdCIgKwogICAgICAib2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXNcMDIySFxuXHJvcHRpb25hbGdyIiArCiAgICAgICJvdXBcMDMwXG4gXDAwMShcbjIxLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW4iICsKICAgICAgImdNZXJnZS5PcHRpb25hbEdyb3VwXDAyMkhcblxycmVwZWF0ZWRncm91cFwwMzBcMDI0ICIgKwogICAgICAiXDAwMyhcbjIxLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyZ2UiICsKICAgICAgIi5SZXBlYXRlZEdyb3VwXDAzMlwyNTJcMDA0XG5cMDI3UmVwZWF0ZWRGaWVsZHNHZW5lcmF0IiArCiAgICAgICJvclwwMjIvXG5cMDA2ZmllbGQxXDAzMFwwMDEgXDAwMyhcMDEzMlwwMzcucHJvdG9idWZfdW5pdHRlc3QuVCIgKwogICAgICAiZXN0QWxsVHlwZXNcMDIyL1xuXDAwNmZpZWxkMlwwMzBcMDAyIFwwMDMoXDAxMzJcMDM3LnByb3RvYnVmX3UiICsKICAgICAgIm5pdHRlc3QuVGVzdEFsbFR5cGVzXDAyMi9cblwwMDZmaWVsZDNcMDMwXDAwMyBcMDAzKFwwMTMyXDAzNy5wIiArCiAgICAgICJyb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wwMjJSXG5cMDA2Z3JvdXAxXDAzMCIgKwogICAgICAiXG4gXDAwMyhcbjJCLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyIiArCiAgICAgICJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDFcMDIyUlxuXDAwNmdybyIgKwogICAgICAidXAyXDAzMFwwMjQgXDAwMyhcbjJCLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW4iICsKICAgICAgImdNZXJnZS5SZXBlYXRlZEZpZWxkc0dlbmVyYXRvci5Hcm91cDJcMDIyLlxuIiArCiAgICAgICJcMDA0ZXh0MVwwMzBcMzUwXDAwNyBcMDAzKFwwMTMyXDAzNy5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsIiArCiAgICAgICJUeXBlc1wwMjIuXG5cMDA0ZXh0MlwwMzBcMzUxXDAwNyBcMDAzKFwwMTMyXDAzNy5wcm90b2J1Zl91bml0dGVzdCIgKwogICAgICAiLlRlc3RBbGxUeXBlc1wwMzI5XG5cMDA2R3JvdXAxXDAyMi9cblwwMDZmaWVsZDFcMDMwXDAxMyBcMDAxKFwwMTMyIiArCiAgICAgICJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wwMzI5XG5cMDA2R3JvdSIgKwogICAgICAicDJcMDIyL1xuXDAwNmZpZWxkMVwwMzBcMDI1IFwwMDEoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlQiICsKICAgICAgImVzdEFsbFR5cGVzXDAzMlJcblxyT3B0aW9uYWxHcm91cFwwMjJBXG5cMDMwb3B0aW9uYWwiICsKICAgICAgIl9ncm91cF9hbGxfdHlwZXNcMDMwXDAxMyBcMDAxKFwwMTMyXDAzNy5wcm90b2J1Zl91bml0dGUiICsKICAgICAgInN0LlRlc3RBbGxUeXBlc1wwMzJSXG5cclJlcGVhdGVkR3JvdXBcMDIyQVxuXDAzMHJlcGUiICsKICAgICAgImF0ZWRfZ3JvdXBfYWxsX3R5cGVzXDAzMFwwMjUgXDAwMShcMDEzMlwwMzcucHJvdG9idWZfdW4iICsKICAgICAgIml0dGVzdC5UZXN0QWxsVHlwZXMqXHRcMDEwXDM1MFwwMDdcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDIyW1xuXDAxNG9wdGlvbiIgKwogICAgICAiYWxfZXh0XDAyMiMucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhcnNpbmdNZSIgKwogICAgICAicmdlXDAzMFwzNTBcMDA3IFwwMDEoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeSIgKwogICAgICAicGVzMltcblwwMTRyZXBlYXRlZF9leHRcMDIyIy5wcm90b2J1Zl91bml0dGVzdC4iICsKICAgICAgIlRlc3RQYXJzaW5nTWVyZ2VcMDMwXDM1MVwwMDcgXDAwMyhcMDEzMlwwMzcucHJvdG9idWZfdW5pdHQiICsKICAgICAgImVzdC5UZXN0QWxsVHlwZXNcIlJcblwwMjJUZXN0TWVyZ2VFeGNlcHRpb25cMDIyPCIgKwogICAgICAiXG5cMDE2YWxsX2V4dGVuc2lvbnNcMDMwXDAwMSBcMDAxKFwwMTMyJC5wcm90b2J1Zl91bml0dGUiICsKICAgICAgInN0LlRlc3RBbGxFeHRlbnNpb25zXCJEXG5cMDMzVGVzdENvbW1lbnRJbmplYyIgKwogICAgICAidGlvbk1lc3NhZ2VcMDIyJVxuXDAwMWFcMDMwXDAwMSBcMDAxKFx0OlwwMzIqLyA8LSBOZWl0aGVyIHNoIiArCiAgICAgICJvdWxkIHRoaXMuXCJZXG5cMDE3VGVzdE1lc3NhZ2VTaXplXDAyMlxuXG5cMDAybTFcMDMwXDAwMSBcMDAxKCIgKwogICAgICAiXDAxMFwwMjJcblxuXDAwMm0yXDAzMFwwMDIgXDAwMShcMDAzXDAyMlxuXG5cMDAybTNcMDMwXDAwMyBcMDAxKFwwMTBcMDIyXG5cblwwMDJtNFwwMzBcMDA0IFwwMDEoXHRcMDIyXG5cbiIgKwogICAgICAiXDAwMm01XDAzMFwwMDUgXDAwMShcMDA1XDAyMlxuXG5cMDAybTZcMDMwXDAwNiBcMDAxKFwwMDNcIlwwMTRcblxuRm9vUmVxdWVzdFwiXHJcblwwMTNGIiArCiAgICAgICJvb1Jlc3BvbnNlXCJcMDIyXG5cMDIwRm9vQ2xpZW50TWVzc2FnZVwiXDAyMlxuXDAyMEZvb1NlciIgKwogICAgICAidmVyTWVzc2FnZVwiXDAxNFxuXG5CYXJSZXF1ZXN0XCJcclxuXDAxM0JhclJlc3BvbnNlXCIiICsKICAgICAgIlwyNDZcMDAxXG5cMDE0VGVzdEpzb25OYW1lXDAyMlwwMjNcblwwMTNmaWVsZF9uYW1lMVwwMzBcMDAxIFwwMDEoXDAwNVwwMjJcMDIyXG4iICsKICAgICAgIlxuZmllbGROYW1lMlwwMzBcMDAyIFwwMDEoXDAwNVwwMjJcMDIyXG5cbkZpZWxkTmFtZTNcMDMwXDAwMyBcMDAxKFwwMDVcMDIyXDAyNFxuIiArCiAgICAgICJcMDE0X2ZpZWxkX25hbWU0XDAzMFwwMDQgXDAwMShcMDA1XDAyMlwwMjNcblwwMTNGSUVMRF9OQU1FNVwwMzBcMDA1IFwwMDEoXDAwNSIgKwogICAgICAiXDAyMlwwMzJcblwwMTNmaWVsZF9uYW1lNlwwMzBcMDA2IFwwMDEoXDAwNVJcMDA1QHR5cGVcMDIyXDAyMlxuXG5maWVsZG5hbSIgKwogICAgICAiZTdcMDMwXDAwNyBcMDAxKFwwMDVcIlwzNzVcMDA1XG5cMDI0VGVzdEh1Z2VGaWVsZE51bWJlcnNcMDIyXDAzMlxuXDAxNm9wdCIgKwogICAgICAiaW9uYWxfaW50MzJcMDMwXDM2MFwzNzBcMzc3XDM3N1wwMDEgXDAwMShcMDA1XDAyMlwwMjRcblwwMTBmaXhlZF8zMlwwMzBcMzYxXDM3MFwzNzdcMzc3XDAwMSAiICsKICAgICAgIlwwMDEoXDAwNVwwMjJcMDM2XG5cMDE2cmVwZWF0ZWRfaW50MzJcMDMwXDM2MlwzNzBcMzc3XDM3N1wwMDEgXDAwMyhcMDA1QlwwMDJcMDIwXDAwMFwwMjJcMDM0XG5cMDE0cCIgKwogICAgICAiYWNrZWRfaW50MzJcMDMwXDM2M1wzNzBcMzc3XDM3N1wwMDEgXDAwMyhcMDA1QlwwMDJcMDIwXDAwMVwwMjI5XG5ccm9wdGlvbmFsX2VuIiArCiAgICAgICJ1bVwwMzBcMzY0XDM3MFwzNzdcMzc3XDAwMSBcMDAxKFwwMTYyXDAzNi5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduIiArCiAgICAgICJFbnVtXDAyMlwwMzNcblwwMTdvcHRpb25hbF9zdHJpbmdcMDMwXDM2NVwzNzBcMzc3XDM3N1wwMDEgXDAwMShcdFwwMjJcMDMyXG5cMDE2b3B0IiArCiAgICAgICJpb25hbF9ieXRlc1wwMzBcMzY2XDM3MFwzNzdcMzc3XDAwMSBcMDAxKFwwMTRcMDIyP1xuXDAyMG9wdGlvbmFsX21lc3NhZyIgKwogICAgICAiZVwwMzBcMzY3XDM3MFwzNzdcMzc3XDAwMSBcMDAxKFwwMTMyIS5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTSIgKwogICAgICAiZXNzYWdlXDAyMlBcblxyb3B0aW9uYWxncm91cFwwMzBcMzcwXDM3MFwzNzdcMzc3XDAwMSBcMDAxKFxuMjUucHJvdCIgKwogICAgICAib2J1Zl91bml0dGVzdC5UZXN0SHVnZUZpZWxkTnVtYmVycy5PcHRpbyIgKwogICAgICAibmFsR3JvdXBcMDIyW1xuXDAyMXN0cmluZ19zdHJpbmdfbWFwXDAzMFwzNzJcMzcwXDM3N1wzNzdcMDAxIFwwMDMoXDAxMzIiICsKICAgICAgIjwucHJvdG9idWZfdW5pdHRlc3QuVGVzdEh1Z2VGaWVsZE51bWJlcnMiICsKICAgICAgIi5TdHJpbmdTdHJpbmdNYXBFbnRyeVwwMjJcMDMyXG5cMDE0b25lb2ZfdWludDMyXDAzMFwzNzNcMzcwIiArCiAgICAgICJcMzc3XDM3N1wwMDEgXDAwMShcckhcMDAwXDAyMkNcblwwMjRvbmVvZl90ZXN0X2FsbF90eXBlc1wwMzBcMzc0XDM3MFwzNzdcMzc3XDAwMSAiICsKICAgICAgIlwwMDEoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc0hcMDAwXDAyMlwwMzIiICsKICAgICAgIlxuXDAxNG9uZW9mX3N0cmluZ1wwMzBcMzc1XDM3MFwzNzdcMzc3XDAwMSBcMDAxKFx0SFwwMDBcMDIyXDAzMVxuXDAxM29uZW9mX2J5dGUiICsKICAgICAgInNcMDMwXDM3NlwzNzBcMzc3XDM3N1wwMDEgXDAwMShcMDE0SFwwMDBcMDMyJFxuXHJPcHRpb25hbEdyb3VwXDAyMlwwMjNcblwwMDdncm91cF8iICsKICAgICAgImFcMDMwXDM3MVwzNzBcMzc3XDM3N1wwMDEgXDAwMShcMDA1XDAzMjZcblwwMjRTdHJpbmdTdHJpbmdNYXBFbnRyeVwwMjJcMDEzXG5cMDAzayIgKwogICAgICAiZXlcMDMwXDAwMSBcMDAxKFx0XDAyMlxyXG5cMDA1dmFsdWVcMDMwXDAwMiBcMDAxKFx0OlwwMDI4XDAwMSpcMDE0XDAxMFwzNDBcMjUyXDM3N1wzNzdcMDAxXDAyMFwzNjBcMzcwXDM3N1wzNzciICsKICAgICAgIlwwMDFCXHJcblwwMTNvbmVvZl9maWVsZFwiXDI2MVwwMDFcblwwMzBUZXN0RXh0ZW5zaW9uSW5zaWRlIiArCiAgICAgICJUYWJsZVwwMjJcMDE2XG5cMDA2ZmllbGQxXDAzMFwwMDEgXDAwMShcMDA1XDAyMlwwMTZcblwwMDZmaWVsZDJcMDMwXDAwMiBcMDAxKFwwMDVcMDIyXDAxNlxuIiArCiAgICAgICJcMDA2ZmllbGQzXDAzMFwwMDMgXDAwMShcMDA1XDAyMlwwMTZcblwwMDZmaWVsZDRcMDMwXDAwNCBcMDAxKFwwMDVcMDIyXDAxNlxuXDAwNmZpZWxkNlwwMzAiICsKICAgICAgIlwwMDYgXDAwMShcMDA1XDAyMlwwMTZcblwwMDZmaWVsZDdcMDMwXDAwNyBcMDAxKFwwMDVcMDIyXDAxNlxuXDAwNmZpZWxkOFwwMzBcMDEwIFwwMDEoXDAwNVwwMjJcMDE2XG4iICsKICAgICAgIlwwMDZmaWVsZDlcMDMwXHQgXDAwMShcMDA1XDAyMlwwMTdcblwwMDdmaWVsZDEwXDAzMFxuIFwwMDEoXDAwNSpcMDA0XDAxMFwwMDVcMDIwXDAwNlwiXDIyNlwwMDRcbiIgKwogICAgICAiXDAzNVRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyXDAyMmFcblwwMjNsYXllcjEiICsKICAgICAgIm9wdGlvbmFsZ3JvdXBcMDMwXDAwMSBcMDAxKFxuMkQucHJvdG9idWZfdW5pdHRlc3QuIiArCiAgICAgICJUZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPcHRpIiArCiAgICAgICJvbmFsR3JvdXBcMDMyXDIyMVwwMDNcblwwMjNMYXllcjFPcHRpb25hbEdyb3VwXDAyMnVcblwwMjNsYXkiICsKICAgICAgImVyMnJlcGVhdGVkZ3JvdXBcMDMwXDAwMiBcMDAzKFxuMlgucHJvdG9idWZfdW5pdHRlIiArCiAgICAgICJzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlci5MYXllcjFPIiArCiAgICAgICJwdGlvbmFsR3JvdXAuTGF5ZXIyUmVwZWF0ZWRHcm91cFwwMjJcMjIzXDAwMVxuXCJsYXkiICsKICAgICAgImVyMmFub3RoZXJvcHRpb25hbHJlcGVhdGVkZ3JvdXBcMDMwXDAwNCBcMDAzKFxuMmcuIiArCiAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0TmVzdGVkR3JvdXBFeHRlbnNpIiArCiAgICAgICJvbk91dGVyLkxheWVyMU9wdGlvbmFsR3JvdXAuTGF5ZXIyQW5vdGhlIiArCiAgICAgICJyT3B0aW9uYWxSZXBlYXRlZEdyb3VwXDAzMjJcblwwMjNMYXllcjJSZXBlYXRlZCIgKwogICAgICAiR3JvdXBcMDIyXDAyNVxuXHJhbm90aGVyX2ZpZWxkXDAzMFwwMDYgXDAwMShcdCpcMDA0XDAxMFwwMDNcMDIwXDAwNFwwMzI5XG5cIkxhIiArCiAgICAgICJ5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cFwwMjJcMDIzXG5cMDEzYnV0XyIgKwogICAgICAid2h5X3Rob1wwMzBcMDA1IFwwMDEoXHRcIjxcbiZUZXN0TmVzdGVkR3JvdXBFeHRlbnNpbyIgKwogICAgICAibklubmVyRXh0ZW5zaW9uXDAyMlwwMjJcblxuaW5uZXJfbmFtZVwwMzBcMDAxIFwwMDEoXHRcIlwzMjFcMDAzXG5cMDMzIiArCiAgICAgICJUZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemVcMDIyXDAxN1xuXDAwN2Zvb19vbmVcMDMwXDAwMSIgKwogICAgICAiIFwwMDEoXDAwNVwwMjJcMDE3XG5cMDA3Zm9vX3R3b1wwMzBcMDA2IFwwMDEoXDAwNVwwMjJcMDIxXG5cdGZvb190aHJlZVwwMzBcMDA3IFwwMDEoXDAwNSIgKwogICAgICAiXDAyMlwwMjBcblwwMTBmb29fZm91clwwMzBcciBcMDAxKFwwMDUqXDAwNFwwMTBcMDAyXDAyMFwwMDMqXDAwNFwwMTBcMDAzXDAyMFwwMDUqXDAwNFwwMTBcdFwwMjBcMDEzKlwwMDRcMDEwXDAxNyIgKwogICAgICAiXDAyMFwwMjAqXDAwNFwwMTBcMDIxXDAyMFwwMjIqXDAwNFwwMTBcMDIzXDAyMFwwMjQyP1xuXDAwN2Jhcl9vbmVcMDIyLi5wcm90b2J1Zl91bmkiICsKICAgICAgInR0ZXN0LlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZVwwMzBcMDAyIFwwMDEoXDAwNTIiICsKICAgICAgIj9cblwwMDdiYXJfdHdvXDAyMi4ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEV4dGVuIiArCiAgICAgICJzaW9uUmFuZ2VTZXJpYWxpemVcMDMwXDAwNCBcMDAxKFwwMDUyQVxuXHRiYXJfdGhyZWVcMDIyLi4iICsKICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnNpb25SYW5nZVNlcmkiICsKICAgICAgImFsaXplXDAzMFxuIFwwMDEoXDAwNTJAXG5cMDEwYmFyX2ZvdXJcMDIyLi5wcm90b2J1Zl91bml0dCIgKwogICAgICAiZXN0LlRlc3RFeHRlbnNpb25SYW5nZVNlcmlhbGl6ZVwwMzBcMDE3IFwwMDEoXDAwNTJAXG4iICsKICAgICAgIlwwMTBiYXJfZml2ZVwwMjIuLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RFeHRlbnMiICsKICAgICAgImlvblJhbmdlU2VyaWFsaXplXDAzMFwwMjMgXDAwMShcMDA1XCJcMjAxXDAwMVxuXDAyNVRlc3RWZXJpZnlJbiIgKwogICAgICAidDMyU2ltcGxlXDAyMlwwMzBcblwwMjBvcHRpb25hbF9pbnQzMl8xXDAzMFwwMDEgXDAwMShcMDA1XDAyMlwwMzBcblwwMjBvIiArCiAgICAgICJwdGlvbmFsX2ludDMyXzJcMDMwXDAwMiBcMDAxKFwwMDVcMDIyXDAzMVxuXDAyMW9wdGlvbmFsX2ludDMyXyIgKwogICAgICAiNjNcMDMwPyBcMDAxKFwwMDVcMDIyXDAzMVxuXDAyMW9wdGlvbmFsX2ludDMyXzY0XDAzMEAgXDAwMShcMDA1XCJcMzY1XDAwMVxuXDAxNyIgKwogICAgICAiVGVzdFZlcmlmeUludDMyXDAyMlwwMzBcblwwMjBvcHRpb25hbF9pbnQzMl8xXDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlwwMDVcMDIyXDAzMFxuXDAyMG9wdGlvbmFsX2ludDMyXzJcMDMwXDAwMiBcMDAxKFwwMDVcMDIyXDAzMVxuXDAyMW9wdGlvbmFsXyIgKwogICAgICAiaW50MzJfNjNcMDMwPyBcMDAxKFwwMDVcMDIyXDAzMVxuXDAyMW9wdGlvbmFsX2ludDMyXzY0XDAzMEAgXDAwMSgiICsKICAgICAgIlwwMDVcMDIyO1xuXDAyMm9wdGlvbmFsX2FsbF90eXBlc1wwMzBcdCBcMDAxKFwwMTMyXDAzNy5wcm90b2J1ZiIgKwogICAgICAiX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wwMjI7XG5cMDIycmVwZWF0ZWRfYWxsX3QiICsKICAgICAgInlwZXNcMDMwXG4gXDAwMyhcMDEzMlwwMzcucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5IiArCiAgICAgICJwZXNcIlwzMTJcMDAyXG5cMDI1VGVzdFZlcmlmeU1vc3RseUludDMyXDAyMlwwMzFcblwwMjFvcHRpb25hIiArCiAgICAgICJsX2ludDY0XzMwXDAzMFwwMzYgXDAwMShcMDAzXDAyMlwwMzBcblwwMjBvcHRpb25hbF9pbnQzMl8xXDAzMFwwMDEgXDAwMSIgKwogICAgICAiKFwwMDVcMDIyXDAzMFxuXDAyMG9wdGlvbmFsX2ludDMyXzJcMDMwXDAwMiBcMDAxKFwwMDVcMDIyXDAzMFxuXDAyMG9wdGlvbmFsIiArCiAgICAgICJfaW50MzJfM1wwMzBcMDAzIFwwMDEoXDAwNVwwMjJcMDMwXG5cMDIwb3B0aW9uYWxfaW50MzJfNFwwMzBcMDA0IFwwMDEoXDAwNSIgKwogICAgICAiXDAyMlwwMzFcblwwMjFvcHRpb25hbF9pbnQzMl82M1wwMzA/IFwwMDEoXDAwNVwwMjJcMDMxXG5cMDIxb3B0aW9uYWxfIiArCiAgICAgICJpbnQzMl82NFwwMzBAIFwwMDEoXDAwNVwwMjI7XG5cMDIyb3B0aW9uYWxfYWxsX3R5cGVzXDAzMFx0IFwwMDEiICsKICAgICAgIihcMDEzMlwwMzcucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzXDAyMjtcblwwMjJyIiArCiAgICAgICJlcGVhdGVkX2FsbF90eXBlc1wwMzBcbiBcMDAzKFwwMTMyXDAzNy5wcm90b2J1Zl91bml0dCIgKwogICAgICAiZXN0LlRlc3RBbGxUeXBlc1wiXDM2NVwwMDJcbiNUZXN0VmVyaWZ5TW9zdGx5SW50IiArCiAgICAgICIzMkJpZ0ZpZWxkTnVtYmVyXDAyMlwwMzFcblwwMjFvcHRpb25hbF9pbnQ2NF8zMFwwMzBcMDM2ICIgKwogICAgICAiXDAwMShcMDAzXDAyMlwwMzNcblwwMjJvcHRpb25hbF9pbnQzMl8zMDBcMDMwXDI1NFwwMDIgXDAwMShcMDA1XDAyMlwwMzBcblwwMjBvcHRpIiArCiAgICAgICJvbmFsX2ludDMyXzFcMDMwXDAwMSBcMDAxKFwwMDVcMDIyXDAzMFxuXDAyMG9wdGlvbmFsX2ludDMyXzJcMDMwXDAwMiIgKwogICAgICAiIFwwMDEoXDAwNVwwMjJcMDMwXG5cMDIwb3B0aW9uYWxfaW50MzJfM1wwMzBcMDAzIFwwMDEoXDAwNVwwMjJcMDMwXG5cMDIwb3B0aW9uIiArCiAgICAgICJhbF9pbnQzMl80XDAzMFwwMDQgXDAwMShcMDA1XDAyMlwwMzFcblwwMjFvcHRpb25hbF9pbnQzMl82M1wwMzA/ICIgKwogICAgICAiXDAwMShcMDA1XDAyMlwwMzFcblwwMjFvcHRpb25hbF9pbnQzMl82NFwwMzBAIFwwMDEoXDAwNVwwMjI7XG5cMDIyb3B0aW9uIiArCiAgICAgICJhbF9hbGxfdHlwZXNcMDMwXHQgXDAwMShcMDEzMlwwMzcucHJvdG9idWZfdW5pdHRlc3QuVCIgKwogICAgICAiZXN0QWxsVHlwZXNcMDIyO1xuXDAyMnJlcGVhdGVkX2FsbF90eXBlc1wwMzBcbiBcMDAzKFwwMTMyIiArCiAgICAgICJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlc1wiXDIwNlwwMDFcblwwMjZUZXMiICsKICAgICAgInRWZXJpZnlVaW50MzJTaW1wbGVcMDIyXDAzMVxuXDAyMW9wdGlvbmFsX3VpbnQzMl8xIiArCiAgICAgICJcMDMwXDAwMSBcMDAxKFxyXDAyMlwwMzFcblwwMjFvcHRpb25hbF91aW50MzJfMlwwMzBcMDAyIFwwMDEoXHJcMDIyXDAzMlxuXDAyMm9wdCIgKwogICAgICAiaW9uYWxfdWludDMyXzYzXDAzMD8gXDAwMShcclwwMjJcMDMyXG5cMDIyb3B0aW9uYWxfdWludDMyIiArCiAgICAgICJfNjRcMDMwQCBcMDAxKFxyXCJcMzcyXDAwMVxuXDAyMFRlc3RWZXJpZnlVaW50MzJcMDIyXDAzMVxuXDAyMW9wdGlvbiIgKwogICAgICAiYWxfdWludDMyXzFcMDMwXDAwMSBcMDAxKFxyXDAyMlwwMzFcblwwMjFvcHRpb25hbF91aW50MzJfMlwwMzBcMDAyIiArCiAgICAgICIgXDAwMShcclwwMjJcMDMyXG5cMDIyb3B0aW9uYWxfdWludDMyXzYzXDAzMD8gXDAwMShcclwwMjJcMDMyXG5cMDIyb3B0aSIgKwogICAgICAib25hbF91aW50MzJfNjRcMDMwQCBcMDAxKFxyXDAyMjtcblwwMjJvcHRpb25hbF9hbGxfdHlwIiArCiAgICAgICJlc1wwMzBcdCBcMDAxKFwwMTMyXDAzNy5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZSIgKwogICAgICAic1wwMjI7XG5cMDIycmVwZWF0ZWRfYWxsX3R5cGVzXDAzMFxuIFwwMDMoXDAxMzJcMDM3LnByb3RvYnVmIiArCiAgICAgICJfdW5pdHRlc3QuVGVzdEFsbFR5cGVzXCJcMzcyXDAwMVxuXDAyM1Rlc3RWZXJpZnlPbmUiICsKICAgICAgIlVpbnQzMlwwMjJcMDMxXG5cMDIxb3B0aW9uYWxfdWludDMyXzFcMDMwXDAwMSBcMDAxKFxyXDAyMlwwMzBcblwwMjBvcHQiICsKICAgICAgImlvbmFsX2ludDMyXzJcMDMwXDAwMiBcMDAxKFwwMDVcMDIyXDAzMVxuXDAyMW9wdGlvbmFsX2ludDMyXzYzIiArCiAgICAgICJcMDMwPyBcMDAxKFwwMDVcMDIyXDAzMVxuXDAyMW9wdGlvbmFsX2ludDMyXzY0XDAzMEAgXDAwMShcMDA1XDAyMjtcblwwMjJvcHQiICsKICAgICAgImlvbmFsX2FsbF90eXBlc1wwMzBcdCBcMDAxKFwwMTMyXDAzNy5wcm90b2J1Zl91bml0dGVzIiArCiAgICAgICJ0LlRlc3RBbGxUeXBlc1wwMjI7XG5cMDIycmVwZWF0ZWRfYWxsX3R5cGVzXDAzMFxuIFwwMDMiICsKICAgICAgIihcMDEzMlwwMzcucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzXCJcMjQxXDAwMlxuICIgKwogICAgICAiVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXJcMDIyXDAzMVxuXDAyMW9wdGkiICsKICAgICAgIm9uYWxfaW50MzJfNjVcMDMwQSBcMDAxKFwwMDVcMDIyXDAzMFxuXDAyMG9wdGlvbmFsX2ludDY0XzFcMDMwIiArCiAgICAgICJcMDAxIFwwMDEoXDAwM1wwMjJcMDMwXG5cMDIwb3B0aW9uYWxfaW50NjRfMlwwMzBcMDAyIFwwMDEoXDAwM1wwMjJcMDMxXG5cMDIxb3B0aW8iICsKICAgICAgIm5hbF9pbnQ2NF82M1wwMzA/IFwwMDEoXDAwM1wwMjJcMDMxXG5cMDIxb3B0aW9uYWxfaW50NjRfNjRcMDMwIiArCiAgICAgICJAIFwwMDEoXDAwM1wwMjI7XG5cMDIyb3B0aW9uYWxfYWxsX3R5cGVzXDAzMFx0IFwwMDEoXDAxMzJcMDM3LnByb3QiICsKICAgICAgIm9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzXDAyMjtcblwwMjJyZXBlYXRlZF9hIiArCiAgICAgICJsbF90eXBlc1wwMzBcbiBcMDAzKFwwMTMyXDAzNy5wcm90b2J1Zl91bml0dGVzdC5UZXN0QSIgKwogICAgICAibGxUeXBlc1wiXDI3NFwwMDJcblwwMzVUZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlIiArCiAgICAgICJyXDAyMlwwMzRcblwwMjNvcHRpb25hbF9pbnQzMl8xMDAwXDAzMFwzNTBcMDA3IFwwMDEoXDAwNVwwMjJcMDMxXG5cMDIxb3B0aW8iICsKICAgICAgIm5hbF9pbnQzMl82NVwwMzBBIFwwMDEoXDAwNVwwMjJcMDMwXG5cMDIwb3B0aW9uYWxfaW50MzJfMVwwMzBcMDAxIiArCiAgICAgICIgXDAwMShcMDA1XDAyMlwwMzBcblwwMjBvcHRpb25hbF9pbnQzMl8yXDAzMFwwMDIgXDAwMShcMDA1XDAyMlwwMzFcblwwMjFvcHRpb24iICsKICAgICAgImFsX2ludDMyXzYzXDAzMD8gXDAwMShcMDA1XDAyMlwwMzFcblwwMjFvcHRpb25hbF9pbnQzMl82NFwwMzBAIiArCiAgICAgICIgXDAwMShcMDA1XDAyMjtcblwwMjJvcHRpb25hbF9hbGxfdHlwZXNcMDMwXHQgXDAwMShcMDEzMlwwMzcucHJvdG8iICsKICAgICAgImJ1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXNcMDIyO1xuXDAyMnJlcGVhdGVkX2FsIiArCiAgICAgICJsX3R5cGVzXDAzMFxuIFwwMDMoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbCIgKwogICAgICAibFR5cGVzXCJcMzAzXDAwMlxuXDAzNlRlc3RWZXJpZnlVaW50MzJCaWdGaWVsZE51bWJlIiArCiAgICAgICJyXDAyMlwwMzVcblwwMjRvcHRpb25hbF91aW50MzJfMTAwMFwwMzBcMzUwXDAwNyBcMDAxKFxyXDAyMlwwMzJcblwwMjJvcHRpIiArCiAgICAgICJvbmFsX3VpbnQzMl82NVwwMzBBIFwwMDEoXHJcMDIyXDAzMVxuXDAyMW9wdGlvbmFsX3VpbnQzMl8iICsKICAgICAgIjFcMDMwXDAwMSBcMDAxKFxyXDAyMlwwMzFcblwwMjFvcHRpb25hbF91aW50MzJfMlwwMzBcMDAyIFwwMDEoXHJcMDIyXDAzMlxuXDAyMm9wIiArCiAgICAgICJ0aW9uYWxfdWludDMyXzYzXDAzMD8gXDAwMShcclwwMjJcMDMyXG5cMDIyb3B0aW9uYWxfdWludDMiICsKICAgICAgIjJfNjRcMDMwQCBcMDAxKFxyXDAyMjtcblwwMjJvcHRpb25hbF9hbGxfdHlwZXNcMDMwXHQgXDAwMShcMDEzMlwwMzciICsKICAgICAgIi5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXNcMDIyO1xuXDAyMnJlcGVhIiArCiAgICAgICJ0ZWRfYWxsX3R5cGVzXDAzMFxuIFwwMDMoXDAxMzJcMDM3LnByb3RvYnVmX3VuaXR0ZXN0LiIgKwogICAgICAiVGVzdEFsbFR5cGVzXCJcMjEwXDAwNFxuXDAzNlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlIiArCiAgICAgICJyVWludDMyXDAyMlFcblwwMTdvcHRpb25hbF9uZXN0ZWRcMDMwXDAwMSBcMDAxKFwwMTMyOC5wcm90byIgKwogICAgICAiYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbiIgKwogICAgICAidDMyLk5lc3RlZFwwMzJcMjIyXDAwM1xuXDAwNk5lc3RlZFwwMjJcMDM1XG5cMDI0b3B0aW9uYWxfdWludDMyIiArCiAgICAgICJfNTAwMFwwMzBcMjEwXCcgXDAwMShcclwwMjJcMDM1XG5cMDI0b3B0aW9uYWxfdWludDMyXzEwMDBcMDMwXDM1MFwwMDcgIiArCiAgICAgICJcMDAxKFxyXDAyMlwwMzJcblwwMjJvcHRpb25hbF91aW50MzJfNjZcMDMwQiBcMDAxKFxyXDAyMlwwMzJcblwwMjJvcHRpbyIgKwogICAgICAibmFsX3VpbnQzMl82NVwwMzBBIFwwMDEoXHJcMDIyXDAzMVxuXDAyMW9wdGlvbmFsX3VpbnQzMl8xIiArCiAgICAgICJcMDMwXDAwMSBcMDAxKFxyXDAyMlwwMzFcblwwMjFvcHRpb25hbF91aW50MzJfMlwwMzBcMDAyIFwwMDEoXHJcMDIyXDAzMlxuXDAyMm9wdCIgKwogICAgICAiaW9uYWxfdWludDMyXzYzXDAzMD8gXDAwMShcclwwMjJcMDMyXG5cMDIyb3B0aW9uYWxfdWludDMyIiArCiAgICAgICJfNjRcMDMwQCBcMDAxKFxyXDAyMlFcblwwMTdvcHRpb25hbF9uZXN0ZWRcMDMwXHQgXDAwMShcMDEzMjgucHJvIiArCiAgICAgICJ0b2J1Zl91bml0dGVzdC5UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVIiArCiAgICAgICJpbnQzMi5OZXN0ZWRcMDIyUVxuXDAxN3JlcGVhdGVkX25lc3RlZFwwMzBcbiBcMDAzKFwwMTMyOC4iICsKICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LlRlc3RWZXJpZnlCaWdGaWVsZE51bWIiICsKICAgICAgImVyVWludDMyLk5lc3RlZFwiXDMwNlwiXG5cMDE3RW51bVBhcnNlVGVzdGVyXDAyMlNcblwwMzVvIiArCiAgICAgICJwdGlvbmFsX3NlcV9zbWFsbF8wX2xvd2ZpZWxkXDAzMFwwMDEgXDAwMShcMDE2MiwucHJvIiArCiAgICAgICJ0b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwIiArCiAgICAgICJcMDIyVFxuXDAzNW9wdGlvbmFsX3NlcV9zbWFsbF8wX21pZGZpZWxkXDAzMFwzNTFcMDA3IFwwMDEoXDAxNiIgKwogICAgICAiMiwucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcSIgKwogICAgICAiU21hbGwwXDAyMlRcblwwMzRvcHRpb25hbF9zZXFfc21hbGxfMF9oaWZpZWxkXDAzMFwzMDEiICsKICAgICAgIlwyMDQ9IFwwMDEoXDAxNjIsLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3QiICsKICAgICAgImVyLlNlcVNtYWxsMFwwMjJTXG5cMDM1cmVwZWF0ZWRfc2VxX3NtYWxsXzBfbG93IiArCiAgICAgICJmaWVsZFwwMzBcMDAyIFwwMDMoXDAxNjIsLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzIiArCiAgICAgICJlVGVzdGVyLlNlcVNtYWxsMFwwMjJUXG5cMDM1cmVwZWF0ZWRfc2VxX3NtYWxsXyIgKwogICAgICAiMF9taWRmaWVsZFwwMzBcMzUyXDAwNyBcMDAzKFwwMTYyLC5wcm90b2J1Zl91bml0dGVzdC5FbiIgKwogICAgICAidW1QYXJzZVRlc3Rlci5TZXFTbWFsbDBcMDIyVFxuXDAzNHJlcGVhdGVkX3NlcV8iICsKICAgICAgInNtYWxsXzBfaGlmaWVsZFwwMzBcMzAyXDIwND0gXDAwMyhcMDE2MiwucHJvdG9idWZfdW5pdHQiICsKICAgICAgImVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwwXDAyMlVcblwwMzNwYWNrZWRfIiArCiAgICAgICJzZXFfc21hbGxfMF9sb3dmaWVsZFwwMzBcMDAzIFwwMDMoXDAxNjIsLnByb3RvYnVmX3VuIiArCiAgICAgICJpdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMEJcMDAyXDAyMFwwMDFcMDIyVlxuXDAzMyIgKwogICAgICAicGFja2VkX3NlcV9zbWFsbF8wX21pZGZpZWxkXDAzMFwzNTNcMDA3IFwwMDMoXDAxNjIsLnBybyIgKwogICAgICAidG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMCIgKwogICAgICAiQlwwMDJcMDIwXDAwMVwwMjJWXG5cMDMycGFja2VkX3NlcV9zbWFsbF8wX2hpZmllbGRcMDMwXDMwM1wyMDQ9IFwwMDMiICsKICAgICAgIihcMDE2MiwucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlMiICsKICAgICAgImVxU21hbGwwQlwwMDJcMDIwXDAwMVwwMjJTXG5cMDM1b3B0aW9uYWxfc2VxX3NtYWxsXzFfbG93IiArCiAgICAgICJmaWVsZFwwMzBcMDA0IFwwMDEoXDAxNjIsLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzIiArCiAgICAgICJlVGVzdGVyLlNlcVNtYWxsMVwwMjJUXG5cMDM1b3B0aW9uYWxfc2VxX3NtYWxsXyIgKwogICAgICAiMV9taWRmaWVsZFwwMzBcMzU0XDAwNyBcMDAxKFwwMTYyLC5wcm90b2J1Zl91bml0dGVzdC5FbiIgKwogICAgICAidW1QYXJzZVRlc3Rlci5TZXFTbWFsbDFcMDIyVFxuXDAzNG9wdGlvbmFsX3NlcV8iICsKICAgICAgInNtYWxsXzFfaGlmaWVsZFwwMzBcMzA0XDIwND0gXDAwMShcMDE2MiwucHJvdG9idWZfdW5pdHQiICsKICAgICAgImVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxXDAyMlNcblwwMzVyZXBlYXRlIiArCiAgICAgICJkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkXDAzMFwwMDUgXDAwMyhcMDE2MiwucHJvdG9idWZfIiArCiAgICAgICJ1bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxU21hbGwxXDAyMlRcblwwMzVyZSIgKwogICAgICAicGVhdGVkX3NlcV9zbWFsbF8xX21pZGZpZWxkXDAzMFwzNTVcMDA3IFwwMDMoXDAxNjIsLnBybyIgKwogICAgICAidG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcVNtYWxsMSIgKwogICAgICAiXDAyMlRcblwwMzRyZXBlYXRlZF9zZXFfc21hbGxfMV9oaWZpZWxkXDAzMFwzMDVcMjA0PSBcMDAzKFwwMTYiICsKICAgICAgIjIsLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXEiICsKICAgICAgIlNtYWxsMVwwMjJVXG5cMDMzcGFja2VkX3NlcV9zbWFsbF8xX2xvd2ZpZWxkXDAzMFwwMDYgIiArCiAgICAgICJcMDAzKFwwMTYyLC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuIiArCiAgICAgICJTZXFTbWFsbDFCXDAwMlwwMjBcMDAxXDAyMlZcblwwMzNwYWNrZWRfc2VxX3NtYWxsXzFfbWlkZiIgKwogICAgICAiaWVsZFwwMzBcMzU2XDAwNyBcMDAzKFwwMTYyLC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFycyIgKwogICAgICAiZVRlc3Rlci5TZXFTbWFsbDFCXDAwMlwwMjBcMDAxXDAyMlZcblwwMzJwYWNrZWRfc2VxX3NtYWwiICsKICAgICAgImxfMV9oaWZpZWxkXDAzMFwzMDZcMjA0PSBcMDAzKFwwMTYyLC5wcm90b2J1Zl91bml0dGVzdC4iICsKICAgICAgIkVudW1QYXJzZVRlc3Rlci5TZXFTbWFsbDFCXDAwMlwwMjBcMDAxXDAyMlBcblwwMzNvcHRpb25hIiArCiAgICAgICJsX3NlcV9sYXJnZV9sb3dmaWVsZFwwMzBcMDA3IFwwMDEoXDAxNjIrLnByb3RvYnVmX3VuIiArCiAgICAgICJpdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhcmdlXDAyMlFcblwwMzNvcHRpbyIgKwogICAgICAibmFsX3NlcV9sYXJnZV9taWRmaWVsZFwwMzBcMzU3XDAwNyBcMDAxKFwwMTYyKy5wcm90b2J1ZiIgKwogICAgICAiX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXFMYXJnZVwwMjJRXG5cMDMyb3AiICsKICAgICAgInRpb25hbF9zZXFfbGFyZ2VfaGlmaWVsZFwwMzBcMzA3XDIwND0gXDAwMShcMDE2MisucHJvdG8iICsKICAgICAgImJ1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2VcMDIyUFxuIiArCiAgICAgICJcMDMzcmVwZWF0ZWRfc2VxX2xhcmdlX2xvd2ZpZWxkXDAzMFwwMTAgXDAwMyhcMDE2MisucHJvIiArCiAgICAgICJ0b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuU2VxTGFyZ2VcMDIyIiArCiAgICAgICJRXG5cMDMzcmVwZWF0ZWRfc2VxX2xhcmdlX21pZGZpZWxkXDAzMFwzNjBcMDA3IFwwMDMoXDAxNjIrLiIgKwogICAgICAicHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcUxhciIgKwogICAgICAiZ2VcMDIyUVxuXDAzMnJlcGVhdGVkX3NlcV9sYXJnZV9oaWZpZWxkXDAzMFwzMTBcMjA0PSBcMDAzKFwwMTYiICsKICAgICAgIjIrLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5TZXEiICsKICAgICAgIkxhcmdlXDAyMlJcblwwMzFwYWNrZWRfc2VxX2xhcmdlX2xvd2ZpZWxkXDAzMFx0IFwwMDMoXDAxNiIgKwogICAgICAiMisucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLlNlcSIgKwogICAgICAiTGFyZ2VCXDAwMlwwMjBcMDAxXDAyMlNcblwwMzFwYWNrZWRfc2VxX2xhcmdlX21pZGZpZWxkXDAzMFwzNjEiICsKICAgICAgIlwwMDcgXDAwMyhcMDE2MisucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGUiICsKICAgICAgInIuU2VxTGFyZ2VCXDAwMlwwMjBcMDAxXDAyMlNcblwwMzBwYWNrZWRfc2VxX2xhcmdlX2hpZmllIiArCiAgICAgICJsZFwwMzBcMzExXDIwND0gXDAwMyhcMDE2MisucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlIiArCiAgICAgICJUZXN0ZXIuU2VxTGFyZ2VCXDAwMlwwMjBcMDAxXDAyMlFcblwwMzNvcHRpb25hbF9hcmJpdHJhciIgKwogICAgICAieV9sb3dmaWVsZFwwMzBcbiBcMDAxKFwwMTYyLC5wcm90b2J1Zl91bml0dGVzdC5FbnUiICsKICAgICAgIm1QYXJzZVRlc3Rlci5BcmJpdHJhcnlcMDIyUlxuXDAzM29wdGlvbmFsX2FyYml0IiArCiAgICAgICJyYXJ5X21pZGZpZWxkXDAzMFwzNjJcMDA3IFwwMDEoXDAxNjIsLnByb3RvYnVmX3VuaXR0ZXN0IiArCiAgICAgICIuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeVwwMjJSXG5cMDMyb3B0aW9uYWxfYSIgKwogICAgICAicmJpdHJhcnlfaGlmaWVsZFwwMzBcMzEyXDIwND0gXDAwMShcMDE2MiwucHJvdG9idWZfdW5pdCIgKwogICAgICAidGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5XDAyMlFcblwwMzNyZXBlYXQiICsKICAgICAgImVkX2FyYml0cmFyeV9sb3dmaWVsZFwwMzBcMDEzIFwwMDMoXDAxNjIsLnByb3RvYnVmX3UiICsKICAgICAgIm5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeVwwMjJSXG5cMDMzcmVwIiArCiAgICAgICJlYXRlZF9hcmJpdHJhcnlfbWlkZmllbGRcMDMwXDM2M1wwMDcgXDAwMyhcMDE2MiwucHJvdG9iIiArCiAgICAgICJ1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXIuQXJiaXRyYXJ5XDAyMlJcbiIgKwogICAgICAiXDAzMnJlcGVhdGVkX2FyYml0cmFyeV9oaWZpZWxkXDAzMFwzMTNcMjA0PSBcMDAzKFwwMTYyLC5wciIgKwogICAgICAib3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhciIgKwogICAgICAieVwwMjJTXG5cMDMxcGFja2VkX2FyYml0cmFyeV9sb3dmaWVsZFwwMzBcMDE0IFwwMDMoXDAxNjIsLnAiICsKICAgICAgInJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmEiICsKICAgICAgInJ5QlwwMDJcMDIwXDAwMVwwMjJUXG5cMDMxcGFja2VkX2FyYml0cmFyeV9taWRmaWVsZFwwMzBcMzY0XDAwNyBcMDAzIiArCiAgICAgICIoXDAxNjIsLnByb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BIiArCiAgICAgICJyYml0cmFyeUJcMDAyXDAyMFwwMDFcMDIyVFxuXDAzMHBhY2tlZF9hcmJpdHJhcnlfaGlmaWVsZCIgKwogICAgICAiXDAzMFwzMTRcMjA0PSBcMDAzKFwwMTYyLC5wcm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZSIgKwogICAgICAic3Rlci5BcmJpdHJhcnlCXDAwMlwwMjBcMDAxXDAyMlwwMjNcblwwMTNvdGhlcl9maWVsZFwwMzBjIFwwMDEoXDAwNVwiIiArCiAgICAgICJKXG5cdFNlcVNtYWxsMFwwMjJcMDI3XG5cMDIzU0VRX1NNQUxMXzBfREVGQVVMVFwwMjBcMDAwXDAyMlwwMjFcbiIgKwogICAgICAiXHJTRVFfU01BTExfMF8xXDAyMFwwMDFcMDIyXDAyMVxuXHJTRVFfU01BTExfMF8yXDAyMFwwMDJcIkpcblx0UyIgKwogICAgICAiZXFTbWFsbDFcMDIyXDAyN1xuXDAyM1NFUV9TTUFMTF8xX0RFRkFVTFRcMDIwXDAwMVwwMjJcMDIxXG5cclNFUSIgKwogICAgICAiX1NNQUxMXzFfMlwwMjBcMDAyXDAyMlwwMjFcblxyU0VRX1NNQUxMXzFfM1wwMjBcMDAzXCJcMjA0XDAwNVxuXDAxMFNlcUwiICsKICAgICAgImFyZ2VcMDIyXDAzNlxuXDAyMVNFUV9MQVJHRV9ERUZBVUxUXDAyMFwzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wwMDFcMDIyXDAxN1xuXDAxMyIgKwogICAgICAiU0VRX0xBUkdFXzBcMDIwXDAwMFwwMjJcMDE3XG5cMDEzU0VRX0xBUkdFXzFcMDIwXDAwMVwwMjJcMDE3XG5cMDEzU0VRX0xBIiArCiAgICAgICJSR0VfMlwwMjBcMDAyXDAyMlwwMTdcblwwMTNTRVFfTEFSR0VfM1wwMjBcMDAzXDAyMlwwMTdcblwwMTNTRVFfTEFSR0VfNFwwMjAiICsKICAgICAgIlwwMDRcMDIyXDAxN1xuXDAxM1NFUV9MQVJHRV81XDAyMFwwMDVcMDIyXDAxN1xuXDAxM1NFUV9MQVJHRV82XDAyMFwwMDZcMDIyXDAxN1xuXDAxM1MiICsKICAgICAgIkVRX0xBUkdFXzdcMDIwXDAwN1wwMjJcMDE3XG5cMDEzU0VRX0xBUkdFXzhcMDIwXDAxMFwwMjJcMDE3XG5cMDEzU0VRX0xBUiIgKwogICAgICAiR0VfOVwwMjBcdFwwMjJcMDIwXG5cMDE0U0VRX0xBUkdFXzEwXDAyMFxuXDAyMlwwMjBcblwwMTRTRVFfTEFSR0VfMTEiICsKICAgICAgIlwwMjBcMDEzXDAyMlwwMjBcblwwMTRTRVFfTEFSR0VfMTJcMDIwXDAxNFwwMjJcMDIwXG5cMDE0U0VRX0xBUkdFXzEzXDAyMFxyXDAyMlwwMjAiICsKICAgICAgIlxuXDAxNFNFUV9MQVJHRV8xNFwwMjBcMDE2XDAyMlwwMjBcblwwMTRTRVFfTEFSR0VfMTVcMDIwXDAxN1wwMjJcMDIwXG5cMDE0U0UiICsKICAgICAgIlFfTEFSR0VfMTZcMDIwXDAyMFwwMjJcMDIwXG5cMDE0U0VRX0xBUkdFXzE3XDAyMFwwMjFcMDIyXDAyMFxuXDAxNFNFUV9MQSIgKwogICAgICAiUkdFXzE4XDAyMFwwMjJcMDIyXDAyMFxuXDAxNFNFUV9MQVJHRV8xOVwwMjBcMDIzXDAyMlwwMjBcblwwMTRTRVFfTEFSR0VfIiArCiAgICAgICIyMFwwMjBcMDI0XDAyMlwwMjBcblwwMTRTRVFfTEFSR0VfMjFcMDIwXDAyNVwwMjJcMDIwXG5cMDE0U0VRX0xBUkdFXzIyXDAyMFwwMjYiICsKICAgICAgIlwwMjJcMDIwXG5cMDE0U0VRX0xBUkdFXzIzXDAyMFwwMjdcMDIyXDAyMFxuXDAxNFNFUV9MQVJHRV8yNFwwMjBcMDMwXDAyMlwwMjBcblwwMTQiICsKICAgICAgIlNFUV9MQVJHRV8yNVwwMjBcMDMxXDAyMlwwMjBcblwwMTRTRVFfTEFSR0VfMjZcMDIwXDAzMlwwMjJcMDIwXG5cMDE0U0VRXyIgKwogICAgICAiTEFSR0VfMjdcMDIwXDAzM1wwMjJcMDIwXG5cMDE0U0VRX0xBUkdFXzI4XDAyMFwwMzRcMDIyXDAyMFxuXDAxNFNFUV9MQVJHIiArCiAgICAgICJFXzI5XDAyMFwwMzVcMDIyXDAyMFxuXDAxNFNFUV9MQVJHRV8zMFwwMjBcMDM2XDAyMlwwMjBcblwwMTRTRVFfTEFSR0VfMzEiICsKICAgICAgIlwwMjBcMDM3XDAyMlwwMjBcblwwMTRTRVFfTEFSR0VfMzJcMDIwIFwwMjJcMDIwXG5cMDE0U0VRX0xBUkdFXzMzXDAyMCFcIlwyMzUiICsKICAgICAgIlwwMDFcblx0QXJiaXRyYXJ5XDAyMlwwMzZcblwwMjFBUkJJVFJBUllfREVGQVVMVFwwMjBcMjE1XDI3NlwzNzBcMzc3XDM3N1wzNzciICsKICAgICAgIlwzNzdcMzc3XDM3N1wwMDFcMDIyXDAzMFxuXDAxM0FSQklUUkFSWV8xXDAyMFwyMDVcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wwMDFcMDIyXDAyMFxuXDAxM0FSQklUUiIgKwogICAgICAiQVJZXzJcMDIwXDMyNVwwMDFcMDIyXDAyMVxuXDAxM0FSQklUUkFSWV8zXDAyMFwzMzVcMjAxXHJcMDIyXDAzMlxuXHJBUkJJVFJBUlkiICsKICAgICAgIl9NSU5cMDIwXDIwMFwyMDBcMjAwXDIwMFwzNzBcMzc3XDM3N1wzNzdcMzc3XDAwMVwwMjJcMDI1XG5cckFSQklUUkFSWV9NQVhcMDIwXDM3N1wzNzdcMzc3XDM3N1wwMDcqXG4iICsKICAgICAgIlwwMTBcMjAwXDIxMXpcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDIyclxuXDAyNm9wdGlvbmFsX2FyYml0cmFyeV9leHRcMDIyXCIucCIgKwogICAgICAicm90b2J1Zl91bml0dGVzdC5FbnVtUGFyc2VUZXN0ZXJcMDMwXDIwMFwyMTF6IFwwMDEoXDAxNiIgKwogICAgICAiMiwucHJvdG9idWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYiIgKwogICAgICAiaXRyYXJ5MnJcblwwMjZyZXBlYXRlZF9hcmJpdHJhcnlfZXh0XDAyMlwiLnByb3RvIiArCiAgICAgICJidWZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyXDAzMFwyMDFcMjExeiBcMDAzKFwwMTYyLC5wIiArCiAgICAgICJyb3RvYnVmX3VuaXR0ZXN0LkVudW1QYXJzZVRlc3Rlci5BcmJpdHJhIiArCiAgICAgICJyeTJ0XG5cMDI0cGFja2VkX2FyYml0cmFyeV9leHRcMDIyXCIucHJvdG9idWZfdW4iICsKICAgICAgIml0dGVzdC5FbnVtUGFyc2VUZXN0ZXJcMDMwXDIwMlwyMTF6IFwwMDMoXDAxNjIsLnByb3RvYnUiICsKICAgICAgImZfdW5pdHRlc3QuRW51bVBhcnNlVGVzdGVyLkFyYml0cmFyeUJcMDAyXDAyMFwwMDEiICsKICAgICAgIlwiXDI0M1wwMDRcblwwMTdCb29sUGFyc2VUZXN0ZXJcMDIyXDAzNlxuXDAyNm9wdGlvbmFsX2Jvb2xfbG8iICsKICAgICAgIndmaWVsZFwwMzBcMDAxIFwwMDEoXDAxMFwwMjJcMDM3XG5cMDI2b3B0aW9uYWxfYm9vbF9taWRmaWVsZFwwMzBcMzUxIiArCiAgICAgICJcMDA3IFwwMDEoXDAxMFwwMjJcMDM3XG5cMDI1b3B0aW9uYWxfYm9vbF9oaWZpZWxkXDAzMFwzMDFcMjA0PSBcMDAxKFwwMTBcMDIyXDAzNiIgKwogICAgICAiXG5cMDI2cmVwZWF0ZWRfYm9vbF9sb3dmaWVsZFwwMzBcMDAyIFwwMDMoXDAxMFwwMjJcMDM3XG5cMDI2cmVwZWF0IiArCiAgICAgICJlZF9ib29sX21pZGZpZWxkXDAzMFwzNTJcMDA3IFwwMDMoXDAxMFwwMjJcMDM3XG5cMDI1cmVwZWF0ZWRfYm9vbCIgKwogICAgICAiX2hpZmllbGRcMDMwXDMwMlwyMDQ9IFwwMDMoXDAxMFwwMjIgXG5cMDI0cGFja2VkX2Jvb2xfbG93ZmllbGQiICsKICAgICAgIlwwMzBcMDAzIFwwMDMoXDAxMEJcMDAyXDAyMFwwMDFcMDIyIVxuXDAyNHBhY2tlZF9ib29sX21pZGZpZWxkXDAzMFwzNTNcMDA3IFwwMDMoIiArCiAgICAgICJcMDEwQlwwMDJcMDIwXDAwMVwwMjIhXG5cMDIzcGFja2VkX2Jvb2xfaGlmaWVsZFwwMzBcMzAzXDIwND0gXDAwMyhcMDEwQlwwMDJcMDIwXDAwMSIgKwogICAgICAiXDAyMlwwMjNcblwwMTNvdGhlcl9maWVsZFwwMzBjIFwwMDEoXDAwNSpcblwwMTBcMjAwXDIxMXpcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDIyP1xuXDAyMW9wdCIgKwogICAgICAiaW9uYWxfYm9vbF9leHRcMDIyXCIucHJvdG9idWZfdW5pdHRlc3QuQm9vbFAiICsKICAgICAgImFyc2VUZXN0ZXJcMDMwXDIwMFwyMTF6IFwwMDEoXDAxMDI/XG5cMDIxcmVwZWF0ZWRfYm9vbF9leHRcMDIyIiArCiAgICAgICJcIi5wcm90b2J1Zl91bml0dGVzdC5Cb29sUGFyc2VUZXN0ZXJcMDMwXDIwMVwyMTF6ICIgKwogICAgICAiXDAwMyhcMDEwMkFcblwwMTdwYWNrZWRfYm9vbF9leHRcMDIyXCIucHJvdG9idWZfdW5pdHRlIiArCiAgICAgICJzdC5Cb29sUGFyc2VUZXN0ZXJcMDMwXDIwMlwyMTF6IFwwMDMoXDAxMEJcMDAyXDAyMFwwMDFcIlwyNjNcMDA0XG5cMDIwSW50MzIiICsKICAgICAgIlBhcnNlVGVzdGVyXDAyMlwwMzdcblwwMjdvcHRpb25hbF9pbnQzMl9sb3dmaWVsZFwwMzBcMDAxIiArCiAgICAgICIgXDAwMShcMDA1XDAyMiBcblwwMjdvcHRpb25hbF9pbnQzMl9taWRmaWVsZFwwMzBcMzUxXDAwNyBcMDAxKFwwMDVcMDIyICIgKwogICAgICAiXG5cMDI2b3B0aW9uYWxfaW50MzJfaGlmaWVsZFwwMzBcMzAxXDIwND0gXDAwMShcMDA1XDAyMlwwMzdcblwwMjdyZXBlIiArCiAgICAgICJhdGVkX2ludDMyX2xvd2ZpZWxkXDAzMFwwMDIgXDAwMyhcMDA1XDAyMiBcblwwMjdyZXBlYXRlZF9pbiIgKwogICAgICAidDMyX21pZGZpZWxkXDAzMFwzNTJcMDA3IFwwMDMoXDAwNVwwMjIgXG5cMDI2cmVwZWF0ZWRfaW50MzJfaGkiICsKICAgICAgImZpZWxkXDAzMFwzMDJcMjA0PSBcMDAzKFwwMDVcMDIyIVxuXDAyNXBhY2tlZF9pbnQzMl9sb3dmaWVsZFwwMzBcMDAzIiArCiAgICAgICIgXDAwMyhcMDA1QlwwMDJcMDIwXDAwMVwwMjJcIlxuXDAyNXBhY2tlZF9pbnQzMl9taWRmaWVsZFwwMzBcMzUzXDAwNyBcMDAzKFwwMDUiICsKICAgICAgIkJcMDAyXDAyMFwwMDFcMDIyXCJcblwwMjRwYWNrZWRfaW50MzJfaGlmaWVsZFwwMzBcMzAzXDIwND0gXDAwMyhcMDA1QlwwMDJcMDIwXDAwMSIgKwogICAgICAiXDAyMlwwMjNcblwwMTNvdGhlcl9maWVsZFwwMzBjIFwwMDEoXDAwNSpcblwwMTBcMjAwXDIxMXpcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDIyQVxuXDAyMm9wdCIgKwogICAgICAiaW9uYWxfaW50MzJfZXh0XDAyMiMucHJvdG9idWZfdW5pdHRlc3QuSW50MyIgKwogICAgICAiMlBhcnNlVGVzdGVyXDAzMFwyMDBcMjExeiBcMDAxKFwwMDUyQVxuXDAyMnJlcGVhdGVkX2ludDMyX2UiICsKICAgICAgInh0XDAyMiMucHJvdG9idWZfdW5pdHRlc3QuSW50MzJQYXJzZVRlc3RlclwwMzAiICsKICAgICAgIlwyMDFcMjExeiBcMDAzKFwwMDUyQ1xuXDAyMHBhY2tlZF9pbnQzMl9leHRcMDIyIy5wcm90b2J1Zl91IiArCiAgICAgICJuaXR0ZXN0LkludDMyUGFyc2VUZXN0ZXJcMDMwXDIwMlwyMTF6IFwwMDMoXDAwNUJcMDAyXDAyMFwwMDFcIlwyNjNcMDA0XG4iICsKICAgICAgIlwwMjBJbnQ2NFBhcnNlVGVzdGVyXDAyMlwwMzdcblwwMjdvcHRpb25hbF9pbnQ2NF9sb3dmIiArCiAgICAgICJpZWxkXDAzMFwwMDEgXDAwMShcMDAzXDAyMiBcblwwMjdvcHRpb25hbF9pbnQ2NF9taWRmaWVsZFwwMzBcMzUxXDAwNyIgKwogICAgICAiIFwwMDEoXDAwM1wwMjIgXG5cMDI2b3B0aW9uYWxfaW50NjRfaGlmaWVsZFwwMzBcMzAxXDIwND0gXDAwMShcMDAzXDAyMlwwMzciICsKICAgICAgIlxuXDAyN3JlcGVhdGVkX2ludDY0X2xvd2ZpZWxkXDAzMFwwMDIgXDAwMyhcMDAzXDAyMiBcblwwMjdyZXBlYSIgKwogICAgICAidGVkX2ludDY0X21pZGZpZWxkXDAzMFwzNTJcMDA3IFwwMDMoXDAwM1wwMjIgXG5cMDI2cmVwZWF0ZWRfaW4iICsKICAgICAgInQ2NF9oaWZpZWxkXDAzMFwzMDJcMjA0PSBcMDAzKFwwMDNcMDIyIVxuXDAyNXBhY2tlZF9pbnQ2NF9sb3dmIiArCiAgICAgICJpZWxkXDAzMFwwMDMgXDAwMyhcMDAzQlwwMDJcMDIwXDAwMVwwMjJcIlxuXDAyNXBhY2tlZF9pbnQ2NF9taWRmaWVsZFwwMzAiICsKICAgICAgIlwzNTNcMDA3IFwwMDMoXDAwM0JcMDAyXDAyMFwwMDFcMDIyXCJcblwwMjRwYWNrZWRfaW50NjRfaGlmaWVsZFwwMzBcMzAzXDIwND0gXDAwMyIgKwogICAgICAiKFwwMDNCXDAwMlwwMjBcMDAxXDAyMlwwMjNcblwwMTNvdGhlcl9maWVsZFwwMzBjIFwwMDEoXDAwNSpcblwwMTBcMjAwXDIxMXpcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDIyIiArCiAgICAgICJBXG5cMDIyb3B0aW9uYWxfaW50NjRfZXh0XDAyMiMucHJvdG9idWZfdW5pdHRlcyIgKwogICAgICAidC5JbnQ2NFBhcnNlVGVzdGVyXDAzMFwyMDBcMjExeiBcMDAxKFwwMDMyQVxuXDAyMnJlcGVhdGVkX2kiICsKICAgICAgIm50NjRfZXh0XDAyMiMucHJvdG9idWZfdW5pdHRlc3QuSW50NjRQYXJzZVQiICsKICAgICAgImVzdGVyXDAzMFwyMDFcMjExeiBcMDAzKFwwMDMyQ1xuXDAyMHBhY2tlZF9pbnQ2NF9leHRcMDIyIy5wcm90IiArCiAgICAgICJvYnVmX3VuaXR0ZXN0LkludDY0UGFyc2VUZXN0ZXJcMDMwXDIwMlwyMTF6IFwwMDMoXDAwM0JcMDAyIiArCiAgICAgICJcMDIwXDAwMVwiXDIxNFwwMDFcblwwMzdJbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvXDAyMlwwMTQiICsKICAgICAgIlxuXDAwNHN0cjFcMDMwXDAwMSBcMDAxKFx0XDAyMj9cblwwMDNzdWJcMDMwXDAwMiBcMDAxKFwwMTMyMi5wcm90b2J1Zl91bmkiICsKICAgICAgInR0ZXN0LklubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG9cMDIyXDAxNFxuIiArCiAgICAgICJcMDA0c3RyMlwwMzBcMDAzIFwwMDEoXHRcMDIyXDAxNFxuXDAwNHN0cjNcMDMwXDAwNCBcMDAxKFwwMTRcIlwzNzFcMDAyXG5cMDIxU3RyaW5nUGFycyIgKwogICAgICAiZVRlc3RlclwwMjIgXG5cMDMwb3B0aW9uYWxfc3RyaW5nX2xvd2ZpZWxkXDAzMFwwMDEgXDAwMSgiICsKICAgICAgIlx0XDAyMiFcblwwMzBvcHRpb25hbF9zdHJpbmdfbWlkZmllbGRcMDMwXDM1MVwwMDcgXDAwMShcdFwwMjIhXG5cMDI3IiArCiAgICAgICJvcHRpb25hbF9zdHJpbmdfaGlmaWVsZFwwMzBcMzAxXDIwND0gXDAwMShcdFwwMjIgXG5cMDMwcmVwZWEiICsKICAgICAgInRlZF9zdHJpbmdfbG93ZmllbGRcMDMwXDAwMiBcMDAzKFx0XDAyMiFcblwwMzByZXBlYXRlZF9zdCIgKwogICAgICAicmluZ19taWRmaWVsZFwwMzBcMzUyXDAwNyBcMDAzKFx0XDAyMiFcblwwMjdyZXBlYXRlZF9zdHJpbmdfIiArCiAgICAgICJoaWZpZWxkXDAzMFwzMDJcMjA0PSBcMDAzKFx0KlxuXDAxMFwyMDBcMjExelwwMjBcMjAwXDIwMFwyMDBcMjAwXDAwMjJDXG5cMDIzb3B0aW9uYWxfIiArCiAgICAgICJzdHJpbmdfZXh0XDAyMiQucHJvdG9idWZfdW5pdHRlc3QuU3RyaW5nUGFyIiArCiAgICAgICJzZVRlc3RlclwwMzBcMjAwXDIxMXogXDAwMShcdDJDXG5cMDIzcmVwZWF0ZWRfc3RyaW5nX2V4dFwwMjIiICsKICAgICAgIiQucHJvdG9idWZfdW5pdHRlc3QuU3RyaW5nUGFyc2VUZXN0ZXJcMDMwXDIwMVwyMTEiICsKICAgICAgInogXDAwMyhcdFwiM1xuXHJCYWRGaWVsZE5hbWVzXDAyMlwwMjVcblxyT3B0aW9uYWxJbnQzMlwwMzAiICsKICAgICAgIlwwMDEgXDAwMShcMDA1XDAyMlwwMTNcblwwMDNmb3JcMDMwXDAwMiBcMDAxKFwwMDVcInVcblwwMzJUZXN0TmVzdGVkTWVzc2FnZVIiICsKICAgICAgImVkYWN0aW9uXDAyMilcbiFvcHRpb25hbF91bnJlZGFjdGVkX25lc3RlZF9zIiArCiAgICAgICJ0cmluZ1wwMzBcMDAxIFwwMDEoXHRcMDIyLFxuXDAzN29wdGlvbmFsX3JlZGFjdGVkX25lc3RlZF8iICsKICAgICAgInN0cmluZ1wwMzBcMDAyIFwwMDEoXHRCXDAwM1wyMDBcMDAxXDAwMVwiXDI1MVwwMDZcblwwMTZSZWRhY3RlZEZpZWxkc1wwMjIlXG5cMDMwIiArCiAgICAgICJvcHRpb25hbF9yZWRhY3RlZF9zdHJpbmdcMDMwXDAwMSBcMDAxKFx0QlwwMDNcMjAwXDAwMVwwMDFcMDIyXCJcblwwMzJvIiArCiAgICAgICJwdGlvbmFsX3VucmVkYWN0ZWRfc3RyaW5nXDAzMFwwMDIgXDAwMShcdFwwMjIlXG5cMDMwcmVwZWEiICsKICAgICAgInRlZF9yZWRhY3RlZF9zdHJpbmdcMDMwXDAwMyBcMDAzKFx0QlwwMDNcMjAwXDAwMVwwMDFcMDIyXCJcblwwMzJyZXBlYXQiICsKICAgICAgImVkX3VucmVkYWN0ZWRfc3RyaW5nXDAzMFwwMDQgXDAwMyhcdFwwMjJVXG5cMDMxb3B0aW9uYWxfciIgKwogICAgICAiZWRhY3RlZF9tZXNzYWdlXDAzMFwwMDUgXDAwMShcMDEzMi0ucHJvdG9idWZfdW5pdHRlcyIgKwogICAgICAidC5UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbkJcMDAzXDIwMFwwMDFcMDAxXDAyMlJcblwwMzNvcHQiICsKICAgICAgImlvbmFsX3VucmVkYWN0ZWRfbWVzc2FnZVwwMzBcMDA2IFwwMDEoXDAxMzItLnByb3RvYnUiICsKICAgICAgImZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25cMDIyVVxuIiArCiAgICAgICJcMDMxcmVwZWF0ZWRfcmVkYWN0ZWRfbWVzc2FnZVwwMzBcMDA3IFwwMDMoXDAxMzItLnByb3RvIiArCiAgICAgICJidWZfdW5pdHRlc3QuVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25CIiArCiAgICAgICJcMDAzXDIwMFwwMDFcMDAxXDAyMlJcblwwMzNyZXBlYXRlZF91bnJlZGFjdGVkX21lc3NhZ2VcMDMwXDAxMCBcMDAzKCIgKwogICAgICAiXDAxMzItLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlUiIgKwogICAgICAiZWRhY3Rpb25cMDIyWlxuXDAyM21hcF9yZWRhY3RlZF9zdHJpbmdcMDMwXHQgXDAwMyhcMDEzMjguIiArCiAgICAgICJwcm90b2J1Zl91bml0dGVzdC5SZWRhY3RlZEZpZWxkcy5NYXBSZWRhIiArCiAgICAgICJjdGVkU3RyaW5nRW50cnlCXDAwM1wyMDBcMDAxXDAwMVwwMjJZXG5cMDI1bWFwX3VucmVkYWN0ZWRfcyIgKwogICAgICAidHJpbmdcMDMwXG4gXDAwMyhcMDEzMjoucHJvdG9idWZfdW5pdHRlc3QuUmVkYWN0ZWQiICsKICAgICAgIkZpZWxkcy5NYXBVbnJlZGFjdGVkU3RyaW5nRW50cnlcMDMyOFxuXDAyNk1hcFJlIiArCiAgICAgICJkYWN0ZWRTdHJpbmdFbnRyeVwwMjJcMDEzXG5cMDAza2V5XDAzMFwwMDEgXDAwMShcdFwwMjJcclxuXDAwNXZhbHVlXDAzMCIgKwogICAgICAiXDAwMiBcMDAxKFx0OlwwMDI4XDAwMVwwMzI6XG5cMDMwTWFwVW5yZWRhY3RlZFN0cmluZ0VudHJ5XDAyMlwwMTNcbiIgKwogICAgICAiXDAwM2tleVwwMzBcMDAxIFwwMDEoXHRcMDIyXHJcblwwMDV2YWx1ZVwwMzBcMDAyIFwwMDEoXHQ6XDAwMjhcMDAxXCJbXG5cMDEwVGVzdENvciIgKwogICAgICAiZFwwMjJcMDM3XG5cMDIzb3B0aW9uYWxfYnl0ZXNfY29yZFwwMzBcMDAxIFwwMDEoXDAxNEJcMDAyXDAxMFwwMDFcMDIyLlxuXDAzM29wIiArCiAgICAgICJ0aW9uYWxfYnl0ZXNfY29yZF9kZWZhdWx0XDAzMFwwMDIgXDAwMShcMDE0OlwwMDVoZWxsb0JcMDAyIiArCiAgICAgICJcMDEwXDAwMVwiXDIzNlwwMDFcblwwMzBUZXN0UGFja2VkRW51bVNtYWxsUmFuZ2VcMDIySFxuXDAwNHZhbHNcMDMwIiwKICAgICAgIlwwMDEgXDAwMyhcMDE2MjYucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEVudW0iICsKICAgICAgIlNtYWxsUmFuZ2UuTmVzdGVkRW51bUJcMDAyXDAyMFwwMDFcIjhcblxuTmVzdGVkRW51bVwwMjIiICsKICAgICAgIlwwMTdcblwwMTNVTlNQRUNJRklFRFwwMjBcMDAwXDAyMlwwMDdcblwwMDNGT09cMDIwXDAwMVwwMjJcMDA3XG5cMDAzQkFSXDAyMFwwMDJcMDIyXDAwN1xuXDAwM0JBIiArCiAgICAgICJaXDAyMFwwMDNcIlwyMzFcMDA0XG5cMDIxRW51bXNGb3JCZW5jaG1hcmtcIlwyMTRcMDAxXG5cMDA0RmxhdFwwMjJcMDA2XG5cMDAyQTAiICsKICAgICAgIlwwMjBcMDAwXDAyMlwwMDZcblwwMDJBMVwwMjBcMDAxXDAyMlwwMDZcblwwMDJBMlwwMjBcMDAyXDAyMlwwMDZcblwwMDJBM1wwMjBcMDAzXDAyMlwwMDZcblwwMDJBNFwwMjBcMDA0XDAyMlwwMDZcblwwMDJBNSIgKwogICAgICAiXDAyMFwwMDVcMDIyXDAwNlxuXDAwMkE2XDAyMFwwMDZcMDIyXDAwNlxuXDAwMkE3XDAyMFwwMDdcMDIyXDAwNlxuXDAwMkE4XDAyMFwwMTBcMDIyXDAwNlxuXDAwMkE5XDAyMFx0XDAyMlwwMDdcblwwMDNBMSIgKwogICAgICAiMFwwMjBcblwwMjJcMDA3XG5cMDAzQTExXDAyMFwwMTNcMDIyXDAwN1xuXDAwM0ExMlwwMjBcMDE0XDAyMlwwMDdcblwwMDNBMTNcMDIwXHJcMDIyXDAwN1xuXDAwM0ExNFwwMjBcMDE2XDAyMiIgKwogICAgICAiXDAwN1xuXDAwM0ExNVwwMjBcMDE3XCJcMjIzXDAwMVxuXG5BbG1vc3RGbGF0XDAyMlwwMDZcblwwMDJCMFwwMjBcMDAwXDAyMlwwMDZcblwwMDJCMVwwMjBcMDAxXDAyMiIgKwogICAgICAiXDAwNlxuXDAwMkIyXDAyMFwwMDJcMDIyXDAwNlxuXDAwMkIzXDAyMFwwMDNcMDIyXDAwNlxuXDAwMkI1XDAyMFwwMDVcMDIyXDAwNlxuXDAwMkI2XDAyMFwwMDZcMDIyXDAwNlxuXDAwMkI3XDAyMFwwMDdcMDIyIiArCiAgICAgICJcMDA2XG5cMDAyQjhcMDIwXDAxMFwwMjJcMDA2XG5cMDAyQjlcMDIwXHRcMDIyXDAwN1xuXDAwM0IxMVwwMjBcMDEzXDAyMlwwMDdcblwwMDNCMTJcMDIwXDAxNFwwMjJcMDA3XG5cMDAzQjEzIiArCiAgICAgICJcMDIwXHJcMDIyXDAwN1xuXDAwM0IxNFwwMjBcMDE2XDAyMlwwMDdcblwwMDNCMTVcMDIwXDAxN1wwMjJcMDA3XG5cMDAzQjE3XDAyMFwwMjFcMDIyXDAwN1xuXDAwM0IxOVwwMjBcMDIzXCJcMzM2IiArCiAgICAgICJcMDAxXG5cMDA2U3BhcnNlXDAyMlx0XG5cMDA0QzUzNlwwMjBcMjMwXDAwNFwwMjJcblxuXDAwNUM4Mzg3XDAyMFwzMDNBXDAyMlxuXG5cMDA1Qzk2NyIgKwogICAgICAiM1wwMjBcMzExS1wwMjJcMDEzXG5cMDA2QzEwMjg1XDAyMFwyNTVQXDAyMlwwMTNcblwwMDZDMTMzMThcMDIwXDIwNmhcMDIyXDAxM1xuXDAwNkMxNTk2MyIgKwogICAgICAiXDAyMFwzMzN8XDAyMlwwMTRcblwwMDZDMTY0MzlcMDIwXDI2N1wyMDBcMDAxXDAyMlwwMTRcblwwMDZDMTgxOTdcMDIwXDIyNVwyMTZcMDAxXDAyMlwwMTRcblwwMDZDMTk0MyIgKwogICAgICAiMFwwMjBcMzQ2XDIyN1wwMDFcMDIyXDAxNFxuXDAwNkMyMDM2MVwwMjBcMjExXDIzN1wwMDFcMDIyXDAxNFxuXDAwNkMyMDcwNlwwMjBcMzQyXDI0MVwwMDFcMDIyXDAxNFxuXDAwNkMyMSIgKwogICAgICAiMDUwXDAyMFwyNzJcMjQ0XDAwMVwwMjJcMDE0XG5cMDA2QzIxOTA2XDAyMFwyMjJcMjUzXDAwMVwwMjJcMDE0XG5cMDA2QzI3MjY1XDAyMFwyMDFcMzI1XDAwMVwwMjJcMDE0XG5cMDA2QyIgKwogICAgICAiMzAxMDlcMDIwXDIzNVwzNTNcMDAxXDAyMlwwMTRcblwwMDZDMzE2NzBcMDIwXDI2NlwzNjdcMDAxXCJcMjM1XDAwN1xuJFRlc3RNZXNzYWdlVyIgKwogICAgICAiaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzXDAyMlwwMzFcblwwMjFyZXBlYXRlZF9zdHIiICsKICAgICAgImluZ18xXDAzMFwwMDEgXDAwMyhcdFwwMjJcMDMxXG5cMDIxcmVwZWF0ZWRfc3RyaW5nXzJcMDMwXDAwMiBcMDAzKFx0XDAyMlwwMzEiICsKICAgICAgIlxuXDAyMXJlcGVhdGVkX3N0cmluZ18zXDAzMFwwMDMgXDAwMyhcdFwwMjJcMDMxXG5cMDIxcmVwZWF0ZWRfc3QiICsKICAgICAgInJpbmdfNFwwMzBcMDA0IFwwMDMoXHRcMDIyXDAzMVxuXDAyMXJlcGVhdGVkX3N0cmluZ181XDAzMFwwMDUgXDAwMyhcdFwwMjIiICsKICAgICAgIlwwMzFcblwwMjFyZXBlYXRlZF9zdHJpbmdfNlwwMzBcMDA2IFwwMDMoXHRcMDIyXDAzMVxuXDAyMXJlcGVhdGVkX3MiICsKICAgICAgInRyaW5nXzdcMDMwXDAwNyBcMDAzKFx0XDAyMlwwMzFcblwwMjFyZXBlYXRlZF9zdHJpbmdfOFwwMzBcMDEwIFwwMDMoXHQiICsKICAgICAgIlwwMjJcMDMxXG5cMDIxcmVwZWF0ZWRfc3RyaW5nXzlcMDMwXHQgXDAwMyhcdFwwMjJcMDMyXG5cMDIycmVwZWF0ZWRfIiArCiAgICAgICJzdHJpbmdfMTBcMDMwXG4gXDAwMyhcdFwwMjJcMDMyXG5cMDIycmVwZWF0ZWRfc3RyaW5nXzExXDAzMFwwMTMgIiArCiAgICAgICJcMDAzKFx0XDAyMlwwMzJcblwwMjJyZXBlYXRlZF9zdHJpbmdfMTJcMDMwXDAxNCBcMDAzKFx0XDAyMlwwMzJcblwwMjJyZXBlYSIgKwogICAgICAidGVkX3N0cmluZ18xM1wwMzBcciBcMDAzKFx0XDAyMlwwMzJcblwwMjJyZXBlYXRlZF9zdHJpbmdfMSIgKwogICAgICAiNFwwMzBcMDE2IFwwMDMoXHRcMDIyXDAzMlxuXDAyMnJlcGVhdGVkX3N0cmluZ18xNVwwMzBcMDE3IFwwMDMoXHRcMDIyXDAzMlxuXDAyMnIiICsKICAgICAgImVwZWF0ZWRfc3RyaW5nXzE2XDAzMFwwMjAgXDAwMyhcdFwwMjJcMDMyXG5cMDIycmVwZWF0ZWRfc3RyaSIgKwogICAgICAibmdfMTdcMDMwXDAyMSBcMDAzKFx0XDAyMlwwMzJcblwwMjJyZXBlYXRlZF9zdHJpbmdfMThcMDMwXDAyMiBcMDAzKFx0XDAyMiIgKwogICAgICAiXDAzMlxuXDAyMnJlcGVhdGVkX3N0cmluZ18xOVwwMzBcMDIzIFwwMDMoXHRcMDIyXDAzMlxuXDAyMnJlcGVhdGVkXyIgKwogICAgICAic3RyaW5nXzIwXDAzMFwwMjQgXDAwMyhcdFwwMjJcMDMyXG5cMDIycmVwZWF0ZWRfc3RyaW5nXzIxXDAzMFwwMjUgIiArCiAgICAgICJcMDAzKFx0XDAyMlwwMzJcblwwMjJyZXBlYXRlZF9zdHJpbmdfMjJcMDMwXDAyNiBcMDAzKFx0XDAyMlwwMzJcblwwMjJyZXBlYSIgKwogICAgICAidGVkX3N0cmluZ18yM1wwMzBcMDI3IFwwMDMoXHRcMDIyXDAzMlxuXDAyMnJlcGVhdGVkX3N0cmluZ18yIiArCiAgICAgICI0XDAzMFwwMzAgXDAwMyhcdFwwMjJcMDMyXG5cMDIycmVwZWF0ZWRfc3RyaW5nXzI1XDAzMFwwMzEgXDAwMyhcdFwwMjJcMDMyXG5cMDIyciIgKwogICAgICAiZXBlYXRlZF9zdHJpbmdfMjZcMDMwXDAzMiBcMDAzKFx0XDAyMlwwMzJcblwwMjJyZXBlYXRlZF9zdHJpIiArCiAgICAgICJuZ18yN1wwMzBcMDMzIFwwMDMoXHRcMDIyXDAzMlxuXDAyMnJlcGVhdGVkX3N0cmluZ18yOFwwMzBcMDM0IFwwMDMoXHRcMDIyIiArCiAgICAgICJcMDMyXG5cMDIycmVwZWF0ZWRfc3RyaW5nXzI5XDAzMFwwMzUgXDAwMyhcdFwwMjJcMDMyXG5cMDIycmVwZWF0ZWRfIiArCiAgICAgICJzdHJpbmdfMzBcMDMwXDAzNiBcMDAzKFx0XDAyMlwwMzJcblwwMjJyZXBlYXRlZF9zdHJpbmdfMzFcMDMwXDAzNyAiICsKICAgICAgIlwwMDMoXHRcMDIyXDAzMlxuXDAyMnJlcGVhdGVkX3N0cmluZ18zMlwwMzAgIFwwMDMoXHQqUVxuXDAxM0ZvcmVpIiArCiAgICAgICJnbkVudW1cMDIyXDAxN1xuXDAxM0ZPUkVJR05fRk9PXDAyMFwwMDRcMDIyXDAxN1xuXDAxM0ZPUkVJR05fQkFSXDAyMFwwMDUiICsKICAgICAgIlwwMjJcMDE3XG5cMDEzRk9SRUlHTl9CQVpcMDIwXDAwNlwwMjJcMDE3XG5cMDEzRk9SRUlHTl9CQVhcMDIwICpBXG5cMDI2VGUiICsKICAgICAgInN0UmVzZXJ2ZWRFbnVtRmllbGRzXDAyMlwwMTNcblwwMDdVTktOT1dOXDAyMFwwMDBcIlwwMDRcMDEwXDAwMlwwMjBcMDAyXCIiICsKICAgICAgIlwwMDRcMDEwXDAxN1wwMjBcMDE3XCJcMDA0XDAxMFx0XDAyMFwwMTMqXDAwM2JhcipcMDAzYmF6KktcblwwMjRUZXN0RW51bVdpdGhEdXAiICsKICAgICAgIlZhbHVlXDAyMlwwMTBcblwwMDRGT08xXDAyMFwwMDFcMDIyXDAxMFxuXDAwNEJBUjFcMDIwXDAwMlwwMjJcMDA3XG5cMDAzQkFaXDAyMFwwMDNcMDIyXDAxMFxuXDAwNEZPIiArCiAgICAgICJPMlwwMjBcMDAxXDAyMlwwMTBcblwwMDRCQVIyXDAyMFwwMDJcMDMyXDAwMlwwMjBcMDAxKlwyMTFcMDAxXG5cMDE2VGVzdFNwYXJzZUVudW1cMDIyXDAxNFxuIiArCiAgICAgICJcMDEwU1BBUlNFX0FcMDIwe1wwMjJcMDE2XG5cMDEwU1BBUlNFX0JcMDIwXDI0NlwzNDdcMDAzXDAyMlwwMTdcblwwMTBTUEFSU0VfQ1wwMjAiICsKICAgICAgIlwyNjJcMjYxXDIwMFwwMDZcMDIyXDAyNVxuXDAxMFNQQVJTRV9EXDAyMFwzNjFcMzc3XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDM3N1wwMDFcMDIyXDAyNVxuXDAxMFNQQVJTRV9FXDAyMCIgKwogICAgICAiXDI2NFwzMzZcMzc0XDM3N1wzNzdcMzc3XDM3N1wzNzdcMzc3XDAwMVwwMjJcMDE0XG5cMDEwU1BBUlNFX0ZcMDIwXDAwMFwwMjJcMDE0XG5cMDEwU1BBUlNFX0dcMDIwXDAwMipcMjEzIiArCiAgICAgICJcMDE3XG5cclZlcnlMYXJnZUVudW1cMDIyXDAyNlxuXDAyMkVOVU1fTEFCRUxfREVGQVVMVFwwMjBcMDAwIiArCiAgICAgICJcMDIyXDAyMFxuXDAxNEVOVU1fTEFCRUxfMVwwMjBcMDAxXDAyMlwwMjBcblwwMTRFTlVNX0xBQkVMXzJcMDIwXDAwMlwwMjJcMDIwXG5cMDE0IiArCiAgICAgICJFTlVNX0xBQkVMXzNcMDIwXDAwM1wwMjJcMDIwXG5cMDE0RU5VTV9MQUJFTF80XDAyMFwwMDRcMDIyXDAyMFxuXDAxNEVOVU0iICsKICAgICAgIl9MQUJFTF81XDAyMFwwMDVcMDIyXDAyMFxuXDAxNEVOVU1fTEFCRUxfNlwwMjBcMDA2XDAyMlwwMjBcblwwMTRFTlVNX0xBQiIgKwogICAgICAiRUxfN1wwMjBcMDA3XDAyMlwwMjBcblwwMTRFTlVNX0xBQkVMXzhcMDIwXDAxMFwwMjJcMDIwXG5cMDE0RU5VTV9MQUJFTF85IiArCiAgICAgICJcMDIwXHRcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzEwXDAyMFxuXDAyMlwwMjFcblxyRU5VTV9MQUJFTF8xMVwwMjBcMDEzIiArCiAgICAgICJcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzEyXDAyMFwwMTRcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzEzXDAyMFxyXDAyMlwwMjEiICsKICAgICAgIlxuXHJFTlVNX0xBQkVMXzE0XDAyMFwwMTZcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzE1XDAyMFwwMTdcMDIyXDAyMVxuXHIiICsKICAgICAgIkVOVU1fTEFCRUxfMTZcMDIwXDAyMFwwMjJcMDIxXG5cckVOVU1fTEFCRUxfMTdcMDIwXDAyMVwwMjJcMDIxXG5cckVOIiArCiAgICAgICJVTV9MQUJFTF8xOFwwMjBcMDIyXDAyMlwwMjFcblxyRU5VTV9MQUJFTF8xOVwwMjBcMDIzXDAyMlwwMjFcblxyRU5VTSIgKwogICAgICAiX0xBQkVMXzIwXDAyMFwwMjRcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzIxXDAyMFwwMjVcMDIyXDAyMVxuXHJFTlVNX0wiICsKICAgICAgIkFCRUxfMjJcMDIwXDAyNlwwMjJcMDIxXG5cckVOVU1fTEFCRUxfMjNcMDIwXDAyN1wwMjJcMDIxXG5cckVOVU1fTEFCIiArCiAgICAgICJFTF8yNFwwMjBcMDMwXDAyMlwwMjFcblxyRU5VTV9MQUJFTF8yNVwwMjBcMDMxXDAyMlwwMjFcblxyRU5VTV9MQUJFTCIgKwogICAgICAiXzI2XDAyMFwwMzJcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzI3XDAyMFwwMzNcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzIiICsKICAgICAgIjhcMDIwXDAzNFwwMjJcMDIxXG5cckVOVU1fTEFCRUxfMjlcMDIwXDAzNVwwMjJcMDIxXG5cckVOVU1fTEFCRUxfMzBcMDIwIiArCiAgICAgICJcMDM2XDAyMlwwMjFcblxyRU5VTV9MQUJFTF8zMVwwMjBcMDM3XDAyMlwwMjFcblxyRU5VTV9MQUJFTF8zMlwwMjAgXDAyMiIgKwogICAgICAiXDAyMVxuXHJFTlVNX0xBQkVMXzMzXDAyMCFcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzM0XDAyMFwiXDAyMlwwMjFcbiIgKwogICAgICAiXHJFTlVNX0xBQkVMXzM1XDAyMCNcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzM2XDAyMCRcMDIyXDAyMVxuXHJFIiArCiAgICAgICJOVU1fTEFCRUxfMzdcMDIwJVwwMjJcMDIxXG5cckVOVU1fTEFCRUxfMzhcMDIwJlwwMjJcMDIxXG5cckVOVSIgKwogICAgICAiTV9MQUJFTF8zOVwwMjBcJ1wwMjJcMDIxXG5cckVOVU1fTEFCRUxfNDBcMDIwKFwwMjJcMDIxXG5cckVOVU1fIiArCiAgICAgICJMQUJFTF80MVwwMjApXDAyMlwwMjFcblxyRU5VTV9MQUJFTF80MlwwMjAqXDAyMlwwMjFcblxyRU5VTV9MQSIgKwogICAgICAiQkVMXzQzXDAyMCtcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzQ0XDAyMCxcMDIyXDAyMVxuXHJFTlVNX0xBQkUiICsKICAgICAgIkxfNDVcMDIwLVwwMjJcMDIxXG5cckVOVU1fTEFCRUxfNDZcMDIwLlwwMjJcMDIxXG5cckVOVU1fTEFCRUxfIiArCiAgICAgICI0N1wwMjAvXDAyMlwwMjFcblxyRU5VTV9MQUJFTF80OFwwMjAwXDAyMlwwMjFcblxyRU5VTV9MQUJFTF80OSIgKwogICAgICAiXDAyMDFcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzUwXDAyMDJcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzUxXDAyMDMiICsKICAgICAgIlwwMjJcMDIxXG5cckVOVU1fTEFCRUxfNTJcMDIwNFwwMjJcMDIxXG5cckVOVU1fTEFCRUxfNTNcMDIwNVwwMjJcMDIxIiArCiAgICAgICJcblxyRU5VTV9MQUJFTF81NFwwMjA2XDAyMlwwMjFcblxyRU5VTV9MQUJFTF81NVwwMjA3XDAyMlwwMjFcblxyIiArCiAgICAgICJFTlVNX0xBQkVMXzU2XDAyMDhcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzU3XDAyMDlcMDIyXDAyMVxuXHJFTiIgKwogICAgICAiVU1fTEFCRUxfNThcMDIwOlwwMjJcMDIxXG5cckVOVU1fTEFCRUxfNTlcMDIwO1wwMjJcMDIxXG5cckVOVU0iICsKICAgICAgIl9MQUJFTF82MFwwMjA8XDAyMlwwMjFcblxyRU5VTV9MQUJFTF82MVwwMjA9XDAyMlwwMjFcblxyRU5VTV9MIiArCiAgICAgICJBQkVMXzYyXDAyMD5cMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzYzXDAyMD9cMDIyXDAyMVxuXHJFTlVNX0xBQiIgKwogICAgICAiRUxfNjRcMDIwQFwwMjJcMDIxXG5cckVOVU1fTEFCRUxfNjVcMDIwQVwwMjJcMDIxXG5cckVOVU1fTEFCRUwiICsKICAgICAgIl82NlwwMjBCXDAyMlwwMjFcblxyRU5VTV9MQUJFTF82N1wwMjBDXDAyMlwwMjFcblxyRU5VTV9MQUJFTF82IiArCiAgICAgICI4XDAyMERcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzY5XDAyMEVcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzcwXDAyMCIgKwogICAgICAiRlwwMjJcMDIxXG5cckVOVU1fTEFCRUxfNzFcMDIwR1wwMjJcMDIxXG5cckVOVU1fTEFCRUxfNzJcMDIwSFwwMjIiICsKICAgICAgIlwwMjFcblxyRU5VTV9MQUJFTF83M1wwMjBJXDAyMlwwMjFcblxyRU5VTV9MQUJFTF83NFwwMjBKXDAyMlwwMjFcbiIgKwogICAgICAiXHJFTlVNX0xBQkVMXzc1XDAyMEtcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzc2XDAyMExcMDIyXDAyMVxuXHJFIiArCiAgICAgICJOVU1fTEFCRUxfNzdcMDIwTVwwMjJcMDIxXG5cckVOVU1fTEFCRUxfNzhcMDIwTlwwMjJcMDIxXG5cckVOVSIgKwogICAgICAiTV9MQUJFTF83OVwwMjBPXDAyMlwwMjFcblxyRU5VTV9MQUJFTF84MFwwMjBQXDAyMlwwMjFcblxyRU5VTV8iICsKICAgICAgIkxBQkVMXzgxXDAyMFFcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzgyXDAyMFJcMDIyXDAyMVxuXHJFTlVNX0xBIiArCiAgICAgICJCRUxfODNcMDIwU1wwMjJcMDIxXG5cckVOVU1fTEFCRUxfODRcMDIwVFwwMjJcMDIxXG5cckVOVU1fTEFCRSIgKwogICAgICAiTF84NVwwMjBVXDAyMlwwMjFcblxyRU5VTV9MQUJFTF84NlwwMjBWXDAyMlwwMjFcblxyRU5VTV9MQUJFTF8iICsKICAgICAgIjg3XDAyMFdcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzg4XDAyMFhcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzg5IiArCiAgICAgICJcMDIwWVwwMjJcMDIxXG5cckVOVU1fTEFCRUxfOTBcMDIwWlwwMjJcMDIxXG5cckVOVU1fTEFCRUxfOTFcMDIwWyIgKwogICAgICAiXDAyMlwwMjFcblxyRU5VTV9MQUJFTF85MlwwMjBcXFwwMjJcMDIxXG5cckVOVU1fTEFCRUxfOTNcMDIwXVwwMjJcMDIxIiArCiAgICAgICJcblxyRU5VTV9MQUJFTF85NFwwMjBeXDAyMlwwMjFcblxyRU5VTV9MQUJFTF85NVwwMjBfXDAyMlwwMjFcblxyIiArCiAgICAgICJFTlVNX0xBQkVMXzk2XDAyMGBcMDIyXDAyMVxuXHJFTlVNX0xBQkVMXzk3XDAyMGFcMDIyXDAyMVxuXHJFTiIgKwogICAgICAiVU1fTEFCRUxfOThcMDIwYlwwMjJcMDIxXG5cckVOVU1fTEFCRUxfOTlcMDIwY1wwMjJcMDIyXG5cMDE2RU5VTSIgKwogICAgICAiX0xBQkVMXzEwMFwwMjBkMlwyMzFcMDAxXG5cMDEzVGVzdFNlcnZpY2VcMDIyRFxuXDAwM0Zvb1wwMjJcMDM1LnByIiArCiAgICAgICJvdG9idWZfdW5pdHRlc3QuRm9vUmVxdWVzdFwwMzJcMDM2LnByb3RvYnVmX3VuIiArCiAgICAgICJpdHRlc3QuRm9vUmVzcG9uc2VcMDIyRFxuXDAwM0JhclwwMjJcMDM1LnByb3RvYnVmX3VuaSIgKwogICAgICAidHRlc3QuQmFyUmVxdWVzdFwwMzJcMDM2LnByb3RvYnVmX3VuaXR0ZXN0LkJhciIgKwogICAgICAiUmVzcG9uc2U6RlxuXDAzMG9wdGlvbmFsX2ludDMyX2V4dGVuc2lvblwwMjIkLnAiICsKICAgICAgInJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnNcMDMwXDAwMSBcMDAxKFwwMDUiICsKICAgICAgIjpGXG5cMDMwb3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfIiArCiAgICAgICJ1bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzBcMDAyIFwwMDEoXDAwMzpHXG5cMDMxb3B0aSIgKwogICAgICAib25hbF91aW50MzJfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlcyIgKwogICAgICAidC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzBcMDAzIFwwMDEoXHI6R1xuXDAzMW9wdGlvbmFsX3VpIiArCiAgICAgICJudDY0X2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBIiArCiAgICAgICJsbEV4dGVuc2lvbnNcMDMwXDAwNCBcMDAxKFwwMDQ6R1xuXDAzMW9wdGlvbmFsX3NpbnQzMl9leCIgKwogICAgICAidGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbiIgKwogICAgICAic2lvbnNcMDMwXDAwNSBcMDAxKFwwMjE6R1xuXDAzMW9wdGlvbmFsX3NpbnQ2NF9leHRlbnNpb24iICsKICAgICAgIlwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zXDAzMFwwMDYiICsKICAgICAgIiBcMDAxKFwwMjI6SFxuXDAzMm9wdGlvbmFsX2ZpeGVkMzJfZXh0ZW5zaW9uXDAyMiQucHJvIiArCiAgICAgICJ0b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzBcMDA3IFwwMDEoXDAwNzpIIiArCiAgICAgICJcblwwMzJvcHRpb25hbF9maXhlZDY0X2V4dGVuc2lvblwwMjIkLnByb3RvYnVmXyIgKwogICAgICAidW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnNcMDMwXDAxMCBcMDAxKFwwMDY6SVxuXDAzM29wdGkiICsKICAgICAgIm9uYWxfc2ZpeGVkMzJfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHQiICsKICAgICAgImVzdC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzBcdCBcMDAxKFwwMTc6SVxuXDAzM29wdGlvbmFsXyIgKwogICAgICAic2ZpeGVkNjRfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVCIgKwogICAgICAiZXN0QWxsRXh0ZW5zaW9uc1wwMzBcbiBcMDAxKFwwMjA6RlxuXDAzMG9wdGlvbmFsX2Zsb2F0IiArCiAgICAgICJfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4IiArCiAgICAgICJ0ZW5zaW9uc1wwMzBcMDEzIFwwMDEoXDAwMjpHXG5cMDMxb3B0aW9uYWxfZG91YmxlX2V4dGVucyIgKwogICAgICAiaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbiIgKwogICAgICAic1wwMzBcMDE0IFwwMDEoXDAwMTpFXG5cMDI3b3B0aW9uYWxfYm9vbF9leHRlbnNpb25cMDIyJC5wcm8iICsKICAgICAgInRvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zXDAzMFxyIFwwMDEoXDAxMDpHIiArCiAgICAgICJcblwwMzFvcHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdSIgKwogICAgICAibml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzBcMDE2IFwwMDEoXHQ6RlxuXDAzMG9wdGlvIiArCiAgICAgICJuYWxfYnl0ZXNfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuIiArCiAgICAgICJUZXN0QWxsRXh0ZW5zaW9uc1wwMzBcMDE3IFwwMDEoXDAxNDpxXG5cMDI3b3B0aW9uYWxncm91cCIgKwogICAgICAiX2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeCIgKwogICAgICAidGVuc2lvbnNcMDMwXDAyMCBcMDAxKFxuMioucHJvdG9idWZfdW5pdHRlc3QuT3B0aW8iICsKICAgICAgIm5hbEdyb3VwX2V4dGVuc2lvbjp+XG4hb3B0aW9uYWxfbmVzdGVkX21lIiArCiAgICAgICJzc2FnZV9leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0IiArCiAgICAgICJBbGxFeHRlbnNpb25zXDAzMFwwMjIgXDAwMShcMDEzMi0ucHJvdG9idWZfdW5pdHRlc3QuIiArCiAgICAgICJUZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZTpzXG5cIm9wdGlvbmFsX2YiICsKICAgICAgIm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXQiICsKICAgICAgInRlc3QuVGVzdEFsbEV4dGVuc2lvbnNcMDMwXDAyMyBcMDAxKFwwMTMyIS5wcm90b2J1Zl8iICsKICAgICAgInVuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlOnhcbiFvcHRpb25hbF9pbXBvIiArCiAgICAgICJydF9tZXNzYWdlX2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0IiArCiAgICAgICIuVGVzdEFsbEV4dGVuc2lvbnNcMDMwXDAyNCBcMDAxKFwwMTMyXCcucHJvdG9idWZfdW5pdCIgKwogICAgICAidGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZTp4XG5cMDM2b3B0aW9uYWxfbmUiICsKICAgICAgInN0ZWRfZW51bV9leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91bml0dGVzdC4iICsKICAgICAgIlRlc3RBbGxFeHRlbnNpb25zXDAzMFwwMjUgXDAwMShcMDE2MioucHJvdG9idWZfdW5pdHQiICsKICAgICAgImVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bTptXG5cMDM3b3B0aW9uYWxfIiArCiAgICAgICJmb3JlaWduX2VudW1fZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlIiArCiAgICAgICJzdC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzBcMDI2IFwwMDEoXDAxNjJcMDM2LnByb3RvYnVmX3VuIiArCiAgICAgICJpdHRlc3QuRm9yZWlnbkVudW06clxuXDAzNm9wdGlvbmFsX2ltcG9ydF9lbiIgKwogICAgICAidW1fZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbCIgKwogICAgICAiRXh0ZW5zaW9uc1wwMzBcMDI3IFwwMDEoXDAxNjIkLnByb3RvYnVmX3VuaXR0ZXN0X2ltcCIgKwogICAgICAib3J0LkltcG9ydEVudW06UVxuXDAzN29wdGlvbmFsX3N0cmluZ19waWVjZV8iICsKICAgICAgImV4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHQiICsKICAgICAgImVuc2lvbnNcMDMwXDAzMCBcMDAxKFx0QlwwMDJcMDEwXDAwMjpFXG5cMDI3b3B0aW9uYWxfY29yZF9leHRlbiIgKwogICAgICAic2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpbyIgKwogICAgICAibnNcMDMwXDAzMSBcMDAxKFx0OlwyMDVcMDAxXG4ob3B0aW9uYWxfcHVibGljX2ltcG9ydF9tZXNzIiArCiAgICAgICJhZ2VfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsIiArCiAgICAgICJsRXh0ZW5zaW9uc1wwMzBcMDMyIFwwMDEoXDAxMzItLnByb3RvYnVmX3VuaXR0ZXN0X2ltIiArCiAgICAgICJwb3J0LlB1YmxpY0ltcG9ydE1lc3NhZ2U6XDIwMFwwMDFcblwwMzdvcHRpb25hbF9sYSIgKwogICAgICAienlfbWVzc2FnZV9leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91bml0dGVzdCIgKwogICAgICAiLlRlc3RBbGxFeHRlbnNpb25zXDAzMFwwMzMgXDAwMShcMDEzMi0ucHJvdG9idWZfdW5pdCIgKwogICAgICAidGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZUJcMDAyKFwwMDE6XDIxM1wwMDFcbioiICsKICAgICAgIm9wdGlvbmFsX3VudmVyaWZpZWRfbGF6eV9tZXNzYWdlX2V4dGVuc2kiICsKICAgICAgIm9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMiICsKICAgICAgIlwwMzBcMDM0IFwwMDEoXDAxMzItLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy4iICsKICAgICAgIk5lc3RlZE1lc3NhZ2VCXDAwMnhcMDAxOkZcblwwMzByZXBlYXRlZF9pbnQzMl9leHRlIiArCiAgICAgICJuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpIiArCiAgICAgICJvbnNcMDMwXDAzNyBcMDAzKFwwMDU6RlxuXDAzMHJlcGVhdGVkX2ludDY0X2V4dGVuc2lvblwwMjIkLiIgKwogICAgICAicHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnNcMDMwICBcMDAzKCIgKwogICAgICAiXDAwMzpHXG5cMDMxcmVwZWF0ZWRfdWludDMyX2V4dGVuc2lvblwwMjIkLnByb3RvYnUiICsKICAgICAgImZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnNcMDMwISBcMDAzKFxyOkdcblwwMzFyZSIgKwogICAgICAicGVhdGVkX3VpbnQ2NF9leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91bml0dCIgKwogICAgICAiZXN0LlRlc3RBbGxFeHRlbnNpb25zXDAzMFwiIFwwMDMoXDAwNDpHXG5cMDMxcmVwZWF0ZWRfIiArCiAgICAgICJzaW50MzJfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVGVzIiArCiAgICAgICJ0QWxsRXh0ZW5zaW9uc1wwMzAjIFwwMDMoXDAyMTpHXG5cMDMxcmVwZWF0ZWRfc2ludDY0XyIgKwogICAgICAiZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dCIgKwogICAgICAiZW5zaW9uc1wwMzAkIFwwMDMoXDAyMjpIXG5cMDMycmVwZWF0ZWRfZml4ZWQzMl9leHRlbnMiICsKICAgICAgImlvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb24iICsKICAgICAgInNcMDMwJSBcMDAzKFwwMDc6SFxuXDAzMnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uXDAyMiQuIiArCiAgICAgICJwcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzAmIFwwMDMoIiArCiAgICAgICJcMDA2OklcblwwMzNyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNpb25cMDIyJC5wcm90byIgKwogICAgICAiYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zXDAzMFwnIFwwMDMoXDAxNzpJXG5cMDMzIiArCiAgICAgICJyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91IiArCiAgICAgICJuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zXDAzMCggXDAwMyhcMDIwOkZcblwwMzByZXBlYSIgKwogICAgICAidGVkX2Zsb2F0X2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LiIgKwogICAgICAiVGVzdEFsbEV4dGVuc2lvbnNcMDMwKSBcMDAzKFwwMDI6R1xuXDAzMXJlcGVhdGVkX2RvdWIiICsKICAgICAgImxlX2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGwiICsKICAgICAgIkV4dGVuc2lvbnNcMDMwKiBcMDAzKFwwMDE6RVxuXDAyN3JlcGVhdGVkX2Jvb2xfZXh0ZW5zIiArCiAgICAgICJpb25cMDIyJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9uIiArCiAgICAgICJzXDAzMCsgXDAwMyhcMDEwOkdcblwwMzFyZXBlYXRlZF9zdHJpbmdfZXh0ZW5zaW9uXDAyMiQucCIgKwogICAgICAicm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzAsIFwwMDMoXHQiICsKICAgICAgIjpGXG5cMDMwcmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfIiArCiAgICAgICJ1bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzAtIFwwMDMoXDAxNDpxXG5cMDI3cmVwZSIgKwogICAgICAiYXRlZGdyb3VwX2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LiIgKwogICAgICAiVGVzdEFsbEV4dGVuc2lvbnNcMDMwLiBcMDAzKFxuMioucHJvdG9idWZfdW5pdHQiICsKICAgICAgImVzdC5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbjp+XG4hcmVwZWF0ZWRfIiArCiAgICAgICJuZXN0ZWRfbWVzc2FnZV9leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91bml0IiArCiAgICAgICJ0ZXN0LlRlc3RBbGxFeHRlbnNpb25zXDAzMDAgXDAwMyhcMDEzMi0ucHJvdG9idWZfIiArCiAgICAgICJ1bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZTpzXG5cInIiICsKICAgICAgImVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvblwwMjIkLnByb3QiICsKICAgICAgIm9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnNcMDMwMSBcMDAzKFwwMTMyIS4iICsKICAgICAgInByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlOnhcbiFyZXBlIiArCiAgICAgICJhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvblwwMjIkLnByb3RvYnVmIiArCiAgICAgICJfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnNcMDMwMiBcMDAzKFwwMTMyXCcucHJvdCIgKwogICAgICAib2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZTp4XG5cMDM2cmUiICsKICAgICAgInBlYXRlZF9uZXN0ZWRfZW51bV9leHRlbnNpb25cMDIyJC5wcm90b2J1Zl8iICsKICAgICAgInVuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zXDAzMDMgXDAwMyhcMDE2MioucHJvdG8iICsKICAgICAgImJ1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bTptXG5cMDM3IiArCiAgICAgICJyZXBlYXRlZF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uXDAyMiQucHJvdG9iIiArCiAgICAgICJ1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzA0IFwwMDMoXDAxNjJcMDM2LnByIiArCiAgICAgICJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW06clxuXDAzNnJlcGVhdGVkXyIgKwogICAgICAiaW1wb3J0X2VudW1fZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlcyIgKwogICAgICAidC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzA1IFwwMDMoXDAxNjIkLnByb3RvYnVmX3VuaSIgKwogICAgICAidHRlc3RfaW1wb3J0LkltcG9ydEVudW06UVxuXDAzN3JlcGVhdGVkX3N0cmkiICsKICAgICAgIm5nX3BpZWNlX2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlQiICsKICAgICAgImVzdEFsbEV4dGVuc2lvbnNcMDMwNiBcMDAzKFx0QlwwMDJcMDEwXDAwMjpFXG5cMDI3cmVwZWF0ZWRfYyIgKwogICAgICAib3JkX2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbCIgKwogICAgICAibEV4dGVuc2lvbnNcMDMwNyBcMDAzKFx0OlwyMDBcMDAxXG5cMDM3cmVwZWF0ZWRfbGF6eV9tZXNzIiArCiAgICAgICJhZ2VfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsIiArCiAgICAgICJsRXh0ZW5zaW9uc1wwMzA5IFwwMDMoXDAxMzItLnByb3RvYnVmX3VuaXR0ZXN0LlRlIiArCiAgICAgICJzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VCXDAwMihcMDAxOklcblwwMjdkZWZhdWx0XyIgKwogICAgICAiaW50MzJfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdCIgKwogICAgICAiQWxsRXh0ZW5zaW9uc1wwMzA9IFwwMDEoXDAwNTpcMDAyNDE6SVxuXDAyN2RlZmF1bHRfaW50NjQiICsKICAgICAgIl9leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXgiICsKICAgICAgInRlbnNpb25zXDAzMD4gXDAwMShcMDAzOlwwMDI0MjpKXG5cMDMwZGVmYXVsdF91aW50MzJfZXh0IiArCiAgICAgICJlbnNpb25cMDIyJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zIiArCiAgICAgICJpb25zXDAzMD8gXDAwMShccjpcMDAyNDM6SlxuXDAzMGRlZmF1bHRfdWludDY0X2V4dGVuc2kiICsKICAgICAgIm9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMiICsKICAgICAgIlwwMzBAIFwwMDEoXDAwNDpcMDAyNDQ6S1xuXDAzMGRlZmF1bHRfc2ludDMyX2V4dGVuc2lvblwwMjIkIiArCiAgICAgICIucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnNcMDMwQSBcMDAxIiArCiAgICAgICIoXDAyMTpcMDAzLTQ1OkpcblwwMzBkZWZhdWx0X3NpbnQ2NF9leHRlbnNpb25cMDIyJC5wciIgKwogICAgICAib3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zXDAzMEIgXDAwMShcMDIyOiIgKwogICAgICAiXDAwMjQ2OktcblwwMzFkZWZhdWx0X2ZpeGVkMzJfZXh0ZW5zaW9uXDAyMiQucHJvdG8iICsKICAgICAgImJ1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzBDIFwwMDEoXDAwNzpcMDAyNDciICsKICAgICAgIjpLXG5cMDMxZGVmYXVsdF9maXhlZDY0X2V4dGVuc2lvblwwMjIkLnByb3RvYnVmIiArCiAgICAgICJfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnNcMDMwRCBcMDAxKFwwMDY6XDAwMjQ4OkxcbiIgKwogICAgICAiXDAzMmRlZmF1bHRfc2ZpeGVkMzJfZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdSIgKwogICAgICAibml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzBFIFwwMDEoXDAxNzpcMDAyNDk6TVxuXDAzMmQiICsKICAgICAgImVmYXVsdF9zZml4ZWQ2NF9leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91bmkiICsKICAgICAgInR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zXDAzMEYgXDAwMShcMDIwOlwwMDMtNTA6S1xuXDAyN2RlIiArCiAgICAgICJmYXVsdF9mbG9hdF9leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91bml0dGVzIiArCiAgICAgICJ0LlRlc3RBbGxFeHRlbnNpb25zXDAzMEcgXDAwMShcMDAyOlwwMDQ1MS41Ok1cblwwMzBkZWZhdSIgKwogICAgICAibHRfZG91YmxlX2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LiIgKwogICAgICAiVGVzdEFsbEV4dGVuc2lvbnNcMDMwSCBcMDAxKFwwMDE6XDAwNTUyMDAwOkpcblwwMjZkZWZhdWwiICsKICAgICAgInRfYm9vbF9leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91bml0dGVzdC5UZXMiICsKICAgICAgInRBbGxFeHRlbnNpb25zXDAzMEkgXDAwMShcMDEwOlwwMDR0cnVlOk1cblwwMzBkZWZhdWx0X3N0IiArCiAgICAgICJyaW5nX2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBIiArCiAgICAgICJsbEV4dGVuc2lvbnNcMDMwSiBcMDAxKFx0OlwwMDVoZWxsbzpMXG5cMDI3ZGVmYXVsdF9ieXQiICsKICAgICAgImVzX2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGwiICsKICAgICAgIkV4dGVuc2lvbnNcMDMwSyBcMDAxKFwwMTQ6XDAwNXdvcmxkOnxcblwwMzVkZWZhdWx0X25lc3RlIiArCiAgICAgICJkX2VudW1fZXh0ZW5zaW9uXDAyMiQucHJvdG9idWZfdW5pdHRlc3QuVGVzIiArCiAgICAgICJ0QWxsRXh0ZW5zaW9uc1wwMzBRIFwwMDEoXDAxNjIqLnByb3RvYnVmX3VuaXR0ZXN0IiArCiAgICAgICIuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW06XDAwM0JBUjp5XG5cMDM2ZGVmYXVsdCIgKwogICAgICAiX2ZvcmVpZ25fZW51bV9leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91bml0dCIgKwogICAgICAiZXN0LlRlc3RBbGxFeHRlbnNpb25zXDAzMFIgXDAwMShcMDE2MlwwMzYucHJvdG9idWZfdSIgKwogICAgICAibml0dGVzdC5Gb3JlaWduRW51bTpcMDEzRk9SRUlHTl9CQVI6fVxuXDAzNWRlZmEiICsKICAgICAgInVsdF9pbXBvcnRfZW51bV9leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91bmkiICsKICAgICAgInR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zXDAzMFMgXDAwMShcMDE2MiQucHJvdG9idWYiICsKICAgICAgIl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bTpcbklNUE9SVF9CQVI6IiArCiAgICAgICJVXG5cMDM2ZGVmYXVsdF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uXDAyMiQucHJvdCIgKwogICAgICAib2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9uc1wwMzBUIFwwMDEoXHQ6XDAwM2EiICsKICAgICAgImJjQlwwMDJcMDEwXDAwMjpJXG5cMDI2ZGVmYXVsdF9jb3JkX2V4dGVuc2lvblwwMjIkLnByb3RvIiArCiAgICAgICJidWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnNcMDMwVSBcMDAxKFx0OlwwMDMxMiIgKwogICAgICAiMzpEXG5cMDI2b25lb2ZfdWludDMyX2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3UiICsKICAgICAgIm5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnNcMDMwbyBcMDAxKFxyOntcblwwMzZvbmVvZiIgKwogICAgICAiX25lc3RlZF9tZXNzYWdlX2V4dGVuc2lvblwwMjIkLnByb3RvYnVmX3VuaSIgKwogICAgICAidHRlc3QuVGVzdEFsbEV4dGVuc2lvbnNcMDMwcCBcMDAxKFwwMTMyLS5wcm90b2J1ZiIgKwogICAgICAiX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlOkRcblwwMjYiICsKICAgICAgIm9uZW9mX3N0cmluZ19leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91bml0dGUiICsKICAgICAgInN0LlRlc3RBbGxFeHRlbnNpb25zXDAzMHEgXDAwMShcdDpDXG5cMDI1b25lb2ZfYnl0ZSIgKwogICAgICAic19leHRlbnNpb25cMDIyJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRSIgKwogICAgICAieHRlbnNpb25zXDAzMHIgXDAwMShcMDE0OkJcblwwMjNteV9leHRlbnNpb25fc3RyaW5nXDAyMiUiICsKICAgICAgIi5wcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3NcMDMwMiAiICsKICAgICAgIlwwMDEoXHQ6P1xuXDAyMG15X2V4dGVuc2lvbl9pbnRcMDIyJS5wcm90b2J1Zl91bml0dCIgKwogICAgICAiZXN0LlRlc3RGaWVsZE9yZGVyaW5nc1wwMzBcMDA1IFwwMDEoXDAwNTpLXG5cMDI2cGFja2VkX2kiICsKICAgICAgIm50MzJfZXh0ZW5zaW9uXDAyMlwnLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQIiArCiAgICAgICJhY2tlZEV4dGVuc2lvbnNcMDMwWiBcMDAzKFwwMDVCXDAwMlwwMjBcMDAxOktcblwwMjZwYWNrZWRfaW50NiIgKwogICAgICAiNF9leHRlbnNpb25cMDIyXCcucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2siICsKICAgICAgImVkRXh0ZW5zaW9uc1wwMzBbIFwwMDMoXDAwM0JcMDAyXDAyMFwwMDE6TFxuXDAyN3BhY2tlZF91aW50MzJfIiArCiAgICAgICJleHRlbnNpb25cMDIyXCcucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZCIgKwogICAgICAiRXh0ZW5zaW9uc1wwMzBcXCBcMDAzKFxyQlwwMDJcMDIwXDAwMTpMXG5cMDI3cGFja2VkX3VpbnQ2NF9leCIgKwogICAgICAidGVuc2lvblwwMjJcJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXgiICsKICAgICAgInRlbnNpb25zXDAzMF0gXDAwMyhcMDA0QlwwMDJcMDIwXDAwMTpMXG5cMDI3cGFja2VkX3NpbnQzMl9leHRlIiArCiAgICAgICJuc2lvblwwMjJcJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZSIgKwogICAgICAibnNpb25zXDAzMF4gXDAwMyhcMDIxQlwwMDJcMDIwXDAwMTpMXG5cMDI3cGFja2VkX3NpbnQ2NF9leHRlbnMiICsKICAgICAgImlvblwwMjJcJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zIiArCiAgICAgICJpb25zXDAzMF8gXDAwMyhcMDIyQlwwMDJcMDIwXDAwMTpNXG5cMDMwcGFja2VkX2ZpeGVkMzJfZXh0ZW5zaSIgKwogICAgICAib25cMDIyXCcucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2kiICsKICAgICAgIm9uc1wwMzBgIFwwMDMoXDAwN0JcMDAyXDAyMFwwMDE6TVxuXDAzMHBhY2tlZF9maXhlZDY0X2V4dGVuc2lvIiArCiAgICAgICJuXDAyMlwnLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNpbyIgKwogICAgICAibnNcMDMwYSBcMDAzKFwwMDZCXDAwMlwwMjBcMDAxOk5cblwwMzFwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW8iICsKICAgICAgIm5cMDIyXCcucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvIiArCiAgICAgICJuc1wwMzBiIFwwMDMoXDAxN0JcMDAyXDAyMFwwMDE6TlxuXDAzMXBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpbyIgKwogICAgICAiblwwMjJcJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW8iICsKICAgICAgIm5zXDAzMGMgXDAwMyhcMDIwQlwwMDJcMDIwXDAwMTpLXG5cMDI2cGFja2VkX2Zsb2F0X2V4dGVuc2lvblwwMjJcJyIgKwogICAgICAiLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNpb25zXDAzMCIgKwogICAgICAiZCBcMDAzKFwwMDJCXDAwMlwwMjBcMDAxOkxcblwwMjdwYWNrZWRfZG91YmxlX2V4dGVuc2lvblwwMjJcJy5wIiArCiAgICAgICJyb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNpb25zXDAzMGUgIiArCiAgICAgICJcMDAzKFwwMDFCXDAwMlwwMjBcMDAxOkpcblwwMjVwYWNrZWRfYm9vbF9leHRlbnNpb25cMDIyXCcucHJvdG8iICsKICAgICAgImJ1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9uc1wwMzBmIFwwMDMoXDAxMEIiICsKICAgICAgIlwwMDJcMDIwXDAwMTpqXG5cMDI1cGFja2VkX2VudW1fZXh0ZW5zaW9uXDAyMlwnLnByb3RvYnVmXyIgKwogICAgICAidW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvbnNcMDMwZyBcMDAzKFwwMTYyXDAzNi5wciIgKwogICAgICAib3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtQlwwMDJcMDIwXDAwMTpPXG5cMDMwdW5wYWMiICsKICAgICAgImtlZF9pbnQzMl9leHRlbnNpb25cMDIyKS5wcm90b2J1Zl91bml0dGVzdC4iICsKICAgICAgIlRlc3RVbnBhY2tlZEV4dGVuc2lvbnNcMDMwWiBcMDAzKFwwMDVCXDAwMlwwMjBcMDAwOk9cblwwMzB1bnBhIiArCiAgICAgICJja2VkX2ludDY0X2V4dGVuc2lvblwwMjIpLnByb3RvYnVmX3VuaXR0ZXN0IiArCiAgICAgICIuVGVzdFVucGFja2VkRXh0ZW5zaW9uc1wwMzBbIFwwMDMoXDAwM0JcMDAyXDAyMFwwMDA6UFxuXDAzMXVucCIgKwogICAgICAiYWNrZWRfdWludDMyX2V4dGVuc2lvblwwMjIpLnByb3RvYnVmX3VuaXR0ZSIgKwogICAgICAic3QuVGVzdFVucGFja2VkRXh0ZW5zaW9uc1wwMzBcXCBcMDAzKFxyQlwwMDJcMDIwXDAwMDpQXG5cMDMxdSIgKwogICAgICAibnBhY2tlZF91aW50NjRfZXh0ZW5zaW9uXDAyMikucHJvdG9idWZfdW5pdCIgKwogICAgICAidGVzdC5UZXN0VW5wYWNrZWRFeHRlbnNpb25zXDAzMF0gXDAwMyhcMDA0QlwwMDJcMDIwXDAwMDpQXG4iICsKICAgICAgIlwwMzF1bnBhY2tlZF9zaW50MzJfZXh0ZW5zaW9uXDAyMikucHJvdG9idWZfdW4iICsKICAgICAgIml0dGVzdC5UZXN0VW5wYWNrZWRFeHRlbnNpb25zXDAzMF4gXDAwMyhcMDIxQlwwMDJcMDIwXDAwMDoiICsKICAgICAgIlBcblwwMzF1bnBhY2tlZF9zaW50NjRfZXh0ZW5zaW9uXDAyMikucHJvdG9idWZfIiArCiAgICAgICJ1bml0dGVzdC5UZXN0VW5wYWNrZWRFeHRlbnNpb25zXDAzMF8gXDAwMyhcMDIyQlwwMDJcMDIwIiArCiAgICAgICJcMDAwOlFcblwwMzJ1bnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvblwwMjIpLnByb3RvYiIgKwogICAgICAidWZfdW5pdHRlc3QuVGVzdFVucGFja2VkRXh0ZW5zaW9uc1wwMzBgIFwwMDMoXDAwNyIgKwogICAgICAiQlwwMDJcMDIwXDAwMDpRXG5cMDMydW5wYWNrZWRfZml4ZWQ2NF9leHRlbnNpb25cMDIyKS5wcm8iICsKICAgICAgInRvYnVmX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZEV4dGVuc2lvbnNcMDMwYSAiICsKICAgICAgIlwwMDMoXDAwNkJcMDAyXDAyMFwwMDA6UlxuXDAzM3VucGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvblwwMjIpIiArCiAgICAgICIucHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkRXh0ZW5zaW9uIiArCiAgICAgICJzXDAzMGIgXDAwMyhcMDE3QlwwMDJcMDIwXDAwMDpSXG5cMDMzdW5wYWNrZWRfc2ZpeGVkNjRfZXh0ZW5zaSIgKwogICAgICAib25cMDIyKS5wcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNrZWRFeHRlbiIgKwogICAgICAic2lvbnNcMDMwYyBcMDAzKFwwMjBCXDAwMlwwMjBcMDAwOk9cblwwMzB1bnBhY2tlZF9mbG9hdF9leHRlbnMiICsKICAgICAgImlvblwwMjIpLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZEV4dGUiICsKICAgICAgIm5zaW9uc1wwMzBkIFwwMDMoXDAwMkJcMDAyXDAyMFwwMDA6UFxuXDAzMXVucGFja2VkX2RvdWJsZV9leHRlIiArCiAgICAgICJuc2lvblwwMjIpLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZEV4IiArCiAgICAgICJ0ZW5zaW9uc1wwMzBlIFwwMDMoXDAwMUJcMDAyXDAyMFwwMDA6TlxuXDAyN3VucGFja2VkX2Jvb2xfZXh0ZSIgKwogICAgICAibnNpb25cMDIyKS5wcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNrZWRFeCIgKwogICAgICAidGVuc2lvbnNcMDMwZiBcMDAzKFwwMTBCXDAwMlwwMjBcMDAwOm5cblwwMjd1bnBhY2tlZF9lbnVtX2V4dGUiICsKICAgICAgIm5zaW9uXDAyMikucHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkRXgiICsKICAgICAgInRlbnNpb25zXDAzMGcgXDAwMyhcMDE2MlwwMzYucHJvdG9idWZfdW5pdHRlc3QuRm9yZWkiICsKICAgICAgImduRW51bUJcMDAyXDAyMFwwMDA6ZFxuXDAxNnRlc3RfYWxsX3R5cGVzXDAyMlwnLnByb3RvYnVmXyIgKwogICAgICAidW5pdHRlc3QuVGVzdEh1Z2VGaWVsZE51bWJlcnNcMDMwXDM0MFwyNTJcMzc3XDM3N1wwMDEgXDAwMShcMDEzMiIgKwogICAgICAiXDAzNy5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXM6WlxuJXRlc3QiICsKICAgICAgIl9leHRlbnNpb25faW5zaWRlX3RhYmxlX2V4dGVuc2lvblwwMjIrLnByb3QiICsKICAgICAgIm9idWZfdW5pdHRlc3QuVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlXDAzMFwwMDUiICsKICAgICAgIiBcMDAxKFwwMDU6XDI0MlwwMDFcblwwMDVpbm5lclwwMjJYLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3ROIiArCiAgICAgICJlc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXIuTGF5ZXIxT3B0aW9uYWxHIiArCiAgICAgICJyb3VwLkxheWVyMlJlcGVhdGVkR3JvdXBcMDMwXDAwMyBcMDAxKFwwMTMyOS5wcm90b2J1IiArCiAgICAgICJmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyIiArCiAgICAgICJFeHRlbnNpb25CXDAzNUJcclVuaXR0ZXN0UHJvdG9IXDAwMVwyMDBcMDAxXDAwMVwyMTBcMDAxXDAwMVwyMjBcMDAxXDAwMVwzNzBcMDAxXDAwMSIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0LlVuaXR0ZXN0SW1wb3J0LmdldERlc2NyaXB0b3IoKSwKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiT3B0aW9uYWxJbnQzMiIsICJPcHRpb25hbEludDY0IiwgIk9wdGlvbmFsVWludDMyIiwgIk9wdGlvbmFsVWludDY0IiwgIk9wdGlvbmFsU2ludDMyIiwgIk9wdGlvbmFsU2ludDY0IiwgIk9wdGlvbmFsRml4ZWQzMiIsICJPcHRpb25hbEZpeGVkNjQiLCAiT3B0aW9uYWxTZml4ZWQzMiIsICJPcHRpb25hbFNmaXhlZDY0IiwgIk9wdGlvbmFsRmxvYXQiLCAiT3B0aW9uYWxEb3VibGUiLCAiT3B0aW9uYWxCb29sIiwgIk9wdGlvbmFsU3RyaW5nIiwgIk9wdGlvbmFsQnl0ZXMiLCAiT3B0aW9uYWxHcm91cCIsICJPcHRpb25hbE5lc3RlZE1lc3NhZ2UiLCAiT3B0aW9uYWxGb3JlaWduTWVzc2FnZSIsICJPcHRpb25hbEltcG9ydE1lc3NhZ2UiLCAiT3B0aW9uYWxOZXN0ZWRFbnVtIiwgIk9wdGlvbmFsRm9yZWlnbkVudW0iLCAiT3B0aW9uYWxJbXBvcnRFbnVtIiwgIk9wdGlvbmFsU3RyaW5nUGllY2UiLCAiT3B0aW9uYWxDb3JkIiwgIk9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZSIsICJPcHRpb25hbExhenlNZXNzYWdlIiwgIk9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlIiwgIlJlcGVhdGVkSW50MzIiLCAiUmVwZWF0ZWRJbnQ2NCIsICJSZXBlYXRlZFVpbnQzMiIsICJSZXBlYXRlZFVpbnQ2NCIsICJSZXBlYXRlZFNpbnQzMiIsICJSZXBlYXRlZFNpbnQ2NCIsICJSZXBlYXRlZEZpeGVkMzIiLCAiUmVwZWF0ZWRGaXhlZDY0IiwgIlJlcGVhdGVkU2ZpeGVkMzIiLCAiUmVwZWF0ZWRTZml4ZWQ2NCIsICJSZXBlYXRlZEZsb2F0IiwgIlJlcGVhdGVkRG91YmxlIiwgIlJlcGVhdGVkQm9vbCIsICJSZXBlYXRlZFN0cmluZyIsICJSZXBlYXRlZEJ5dGVzIiwgIlJlcGVhdGVkR3JvdXAiLCAiUmVwZWF0ZWROZXN0ZWRNZXNzYWdlIiwgIlJlcGVhdGVkRm9yZWlnbk1lc3NhZ2UiLCAiUmVwZWF0ZWRJbXBvcnRNZXNzYWdlIiwgIlJlcGVhdGVkTmVzdGVkRW51bSIsICJSZXBlYXRlZEZvcmVpZ25FbnVtIiwgIlJlcGVhdGVkSW1wb3J0RW51bSIsICJSZXBlYXRlZFN0cmluZ1BpZWNlIiwgIlJlcGVhdGVkQ29yZCIsICJSZXBlYXRlZExhenlNZXNzYWdlIiwgIkRlZmF1bHRJbnQzMiIsICJEZWZhdWx0SW50NjQiLCAiRGVmYXVsdFVpbnQzMiIsICJEZWZhdWx0VWludDY0IiwgIkRlZmF1bHRTaW50MzIiLCAiRGVmYXVsdFNpbnQ2NCIsICJEZWZhdWx0Rml4ZWQzMiIsICJEZWZhdWx0Rml4ZWQ2NCIsICJEZWZhdWx0U2ZpeGVkMzIiLCAiRGVmYXVsdFNmaXhlZDY0IiwgIkRlZmF1bHRGbG9hdCIsICJEZWZhdWx0RG91YmxlIiwgIkRlZmF1bHRCb29sIiwgIkRlZmF1bHRTdHJpbmciLCAiRGVmYXVsdEJ5dGVzIiwgIkRlZmF1bHROZXN0ZWRFbnVtIiwgIkRlZmF1bHRGb3JlaWduRW51bSIsICJEZWZhdWx0SW1wb3J0RW51bSIsICJEZWZhdWx0U3RyaW5nUGllY2UiLCAiRGVmYXVsdENvcmQiLCAiT25lb2ZVaW50MzIiLCAiT25lb2ZOZXN0ZWRNZXNzYWdlIiwgIk9uZW9mU3RyaW5nIiwgIk9uZW9mQnl0ZXMiLCAiT25lb2ZDb3JkIiwgIk9uZW9mU3RyaW5nUGllY2UiLCAiT25lb2ZMYXp5TmVzdGVkTWVzc2FnZSIsICJPbmVvZkZpZWxkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQmIiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfT3B0aW9uYWxHcm91cF9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19PcHRpb25hbEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RBbGxUeXBlc19PcHRpb25hbEdyb3VwX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJBIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEFsbFR5cGVzX1JlcGVhdGVkR3JvdXBfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfUmVwZWF0ZWRHcm91cF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsVHlwZXNfUmVwZWF0ZWRHcm91cF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X05lc3RlZFRlc3RBbGxUeXBlc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9OZXN0ZWRUZXN0QWxsVHlwZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTmVzdGVkVGVzdEFsbFR5cGVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJDaGlsZCIsICJQYXlsb2FkIiwgIlJlcGVhdGVkQ2hpbGQiLCAiTGF6eUNoaWxkIiwgIkVhZ2VyQ2hpbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RGVwcmVjYXRlZEZpZWxkc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RGVwcmVjYXRlZEZpZWxkc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RGVwcmVjYXRlZEZpZWxkc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRGVwcmVjYXRlZEludDMyIiwgIkRlcHJlY2F0ZWRSZXBlYXRlZFN0cmluZyIsICJEZXByZWNhdGVkTWVzc2FnZSIsICJEZXByZWNhdGVkSW50MzJJbk9uZW9mIiwgIk5lc3RlZCIsICJPbmVvZkZpZWxkcyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REZXByZWNhdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RGVwcmVjYXRlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdERlcHJlY2F0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ZvcmVpZ25NZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJDIiwgIkQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVzZXJ2ZWRGaWVsZHNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlc2VydmVkRmllbGRzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXNlcnZlZEZpZWxkc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsRXh0ZW5zaW9uc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0QWxsRXh0ZW5zaW9uc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PcHRpb25hbEdyb3VwX2V4dGVuc2lvbl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PcHRpb25hbEdyb3VwX2V4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PcHRpb25hbEdyb3VwX2V4dGVuc2lvbl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJBIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1peGVkRmllbGRzQW5kRXh0ZW5zaW9uc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWl4ZWRGaWVsZHNBbmRFeHRlbnNpb25zX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNaXhlZEZpZWxkc0FuZEV4dGVuc2lvbnNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkEiLCAiQiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RHcm91cF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RHcm91cF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiT3B0aW9uYWxHcm91cCIsICJPcHRpb25hbEZvcmVpZ25FbnVtIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEdyb3VwX09wdGlvbmFsR3JvdXBfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0R3JvdXBfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0R3JvdXBfT3B0aW9uYWxHcm91cF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0R3JvdXBfT3B0aW9uYWxHcm91cF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQSIsICJaeiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RHcm91cEV4dGVuc2lvbl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEdyb3VwRXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RHcm91cEV4dGVuc2lvbl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkRXh0ZW5zaW9uX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkRXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRFeHRlbnNpb25fZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEV4dGVuc2lvbl9PcHRpb25hbEdyb3VwX2V4dGVuc2lvbl9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRFeHRlbnNpb25fZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkRXh0ZW5zaW9uX09wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRFeHRlbnNpb25fT3B0aW9uYWxHcm91cF9leHRlbnNpb25fZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkEiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25fZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMTMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDaGlsZEV4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25fZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkEiLCAiQiIsICJPcHRpb25hbEV4dGVuc2lvbiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDaGlsZEV4dGVuc2lvbkRhdGFfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMTQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDaGlsZEV4dGVuc2lvbkRhdGFfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uRGF0YV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQSIsICJCIiwgIk9wdGlvbmFsRXh0ZW5zaW9uIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uRGF0YV9OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25EYXRhX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uRGF0YV9OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uRGF0YV9OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkR5bmFtaWMiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2hpbGRFeHRlbnNpb25EYXRhX05lc3RlZFRlc3RBbGxFeHRlbnNpb25zRGF0YV9OZXN0ZWREeW5hbWljRXh0ZW5zaW9uc19kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDaGlsZEV4dGVuc2lvbkRhdGFfTmVzdGVkVGVzdEFsbEV4dGVuc2lvbnNEYXRhX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uRGF0YV9OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFfTmVzdGVkRHluYW1pY0V4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdENoaWxkRXh0ZW5zaW9uRGF0YV9OZXN0ZWRUZXN0QWxsRXh0ZW5zaW9uc0RhdGFfTmVzdGVkRHluYW1pY0V4dGVuc2lvbnNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkEiLCAiQiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQSIsICJDaGlsZCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGFfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMTYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRDaGlsZEV4dGVuc2lvbkRhdGFfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZENoaWxkRXh0ZW5zaW9uRGF0YV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQSIsICJDaGlsZCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEVudW1fZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMTcpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEVudW1fZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkRW51bV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUmVxdWlyZWRFbnVtIiwgIkEiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRFbnVtTm9NYXNrX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDE4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRFbnVtTm9NYXNrX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZEVudW1Ob01hc2tfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlJlcXVpcmVkRW51bSIsICJBIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkRW51bU11bHRpX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDE5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRFbnVtTXVsdGlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkRW51bU11bHRpX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJSZXF1aXJlZEVudW00IiwgIkEzIiwgIlJlcXVpcmVkRW51bTIiLCAiUmVxdWlyZWRFbnVtMSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE5vTWFza011bHRpX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDIwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWROb01hc2tNdWx0aV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWROb01hc2tNdWx0aV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUmVxdWlyZWRGaXhlZDMyODAiLCAiUmVxdWlyZWRGaXhlZDMyNzAiLCAiUmVxdWlyZWRFbnVtNjQiLCAiUmVxdWlyZWRFbnVtNCIsICJBMyIsICJSZXF1aXJlZEVudW0yIiwgIlJlcXVpcmVkRW51bTEiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMjEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkEiLCAiRHVtbXkyIiwgIkIiLCAiRHVtbXk0IiwgIkR1bW15NSIsICJEdW1teTYiLCAiRHVtbXk3IiwgIkR1bW15OCIsICJEdW1teTkiLCAiRHVtbXkxMCIsICJEdW1teTExIiwgIkR1bW15MTIiLCAiRHVtbXkxMyIsICJEdW1teTE0IiwgIkR1bW15MTUiLCAiRHVtbXkxNiIsICJEdW1teTE3IiwgIkR1bW15MTgiLCAiRHVtbXkxOSIsICJEdW1teTIwIiwgIkR1bW15MjEiLCAiRHVtbXkyMiIsICJEdW1teTIzIiwgIkR1bW15MjQiLCAiRHVtbXkyNSIsICJEdW1teTI2IiwgIkR1bW15MjciLCAiRHVtbXkyOCIsICJEdW1teTI5IiwgIkR1bW15MzAiLCAiRHVtbXkzMSIsICJEdW1teTMyIiwgIkMiLCAiT3B0aW9uYWxGb3JlaWduIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkRm9yZWlnbl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgyMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkRm9yZWlnbl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRGb3JlaWduX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbE1lc3NhZ2UiLCAiUmVwZWF0ZWRNZXNzYWdlIiwgIkR1bW15IiwgIk9wdGlvbmFsTGF6eU1lc3NhZ2UiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDIzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsTWVzc2FnZSIsICJSZXBlYXRlZE1lc3NhZ2UiLCAiUmVxdWlyZWRNZXNzYWdlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgyNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZFJlcXVpcmVkRm9yZWlnbl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkUmVxdWlyZWRGb3JlaWduX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJDaGlsZCIsICJQYXlsb2FkIiwgIkR1bW15IiwgIlJlcXVpcmVkRW51bSIsICJSZXF1aXJlZEVudW1Ob01hc2siLCAiUmVxdWlyZWRFbnVtTXVsdGkiLCAiUmVxdWlyZWROb01hc2siLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Rm9yZWlnbk5lc3RlZF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgyNSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZvcmVpZ25OZXN0ZWRfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZvcmVpZ25OZXN0ZWRfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkZvcmVpZ25OZXN0ZWQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDI2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFbXB0eU1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDI3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRlbnNpb25zX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDI4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkJiIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9OZXN0ZWROZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBpY2tsZU5lc3RlZE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQaWNrbGVOZXN0ZWRNZXNzYWdlX05lc3RlZE1lc3NhZ2VfTmVzdGVkTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGlja2xlTmVzdGVkTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX05lc3RlZE5lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkNjIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDI5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5nZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11bHRpcGxlRXh0ZW5zaW9uUmFuZ2VzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZWFsbHlMYXJnZVRhZ051bWJlcl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgzMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlYWxseUxhcmdlVGFnTnVtYmVyX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZWFsbHlMYXJnZVRhZ051bWJlcl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQSIsICJCYiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZWN1cnNpdmVNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDMxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVjdXJzaXZlTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVjdXJzaXZlTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQSIsICJJIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMzIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25BX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25BX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJCYiIsICJTdWJHcm91cCIsICJTdWJHcm91cFIiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQV9TdWJNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQV9TdWJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25BX1N1Yk1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkIiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQV9TdWJHcm91cF9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25BX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfU3ViR3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfU3ViR3JvdXBfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlN1Yk1lc3NhZ2UiLCAiTm90SW5UaGlzU2NjIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfU3ViR3JvdXBSX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TXV0dWFsUmVjdXJzaW9uQV9TdWJHcm91cFJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkFfU3ViR3JvdXBSX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJQYXlsb2FkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE11dHVhbFJlY3Vyc2lvbkJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMzMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25CX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNdXR1YWxSZWN1cnNpb25CX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJBIiwgIk9wdGlvbmFsSW50MzIiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgzNCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdElzSW5pdGlhbGl6ZWRfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdElzSW5pdGlhbGl6ZWRfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlN1Yk1lc3NhZ2UiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9TdWJNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdElzSW5pdGlhbGl6ZWRfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9TdWJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJc0luaXRpYWxpemVkX1N1Yk1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlN1Ykdyb3VwIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdElzSW5pdGlhbGl6ZWRfU3ViTWVzc2FnZV9TdWJHcm91cF9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJc0luaXRpYWxpemVkX1N1Yk1lc3NhZ2VfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SXNJbml0aWFsaXplZF9TdWJNZXNzYWdlX1N1Ykdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RJc0luaXRpYWxpemVkX1N1Yk1lc3NhZ2VfU3ViR3JvdXBfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkkiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMzUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REdXBGaWVsZE51bWJlcl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkEiLCAiRm9vIiwgIkJhciIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REdXBGaWVsZE51bWJlcl9Gb29fZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfRm9vX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REdXBGaWVsZE51bWJlcl9Gb29fZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkEiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfQmFyX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER1cEZpZWxkTnVtYmVyX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER1cEZpZWxkTnVtYmVyX0Jhcl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHVwRmllbGROdW1iZXJfQmFyX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJBIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVhZ2VyTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgzNik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVhZ2VyTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJTdWJNZXNzYWdlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdExhenlNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDM3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TGF6eU1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdExhenlNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJTdWJNZXNzYWdlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdExhenlNZXNzYWdlUmVwZWF0ZWRfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMzgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RMYXp5TWVzc2FnZVJlcGVhdGVkX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RMYXp5TWVzc2FnZVJlcGVhdGVkX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJSZXBlYXRlZE1lc3NhZ2UiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNYXliZUxhenlfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMzkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFYWdlck1heWJlTGF6eV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNYXliZUxhenlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk1lc3NhZ2VGb28iLCAiTWVzc2FnZUJhciIsICJNZXNzYWdlQmF6IiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEVhZ2VyTWF5YmVMYXp5X05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNYXliZUxhenlfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNYXliZUxhenlfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RWFnZXJNYXliZUxhenlfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUGFja2VkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDQwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZE1lc3NhZ2VIYXNCaXRzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbE5lc3RlZE1lc3NhZ2UiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkTWVzc2FnZUhhc0JpdHNfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRNZXNzYWdlSGFzQml0c19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRNZXNzYWdlSGFzQml0c19OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRNZXNzYWdlSGFzQml0c19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJOZXN0ZWRtZXNzYWdlUmVwZWF0ZWRJbnQzMiIsICJOZXN0ZWRtZXNzYWdlUmVwZWF0ZWRGb3JlaWdubWVzc2FnZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDYW1lbENhc2VGaWVsZE5hbWVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDQxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2FtZWxDYXNlRmllbGROYW1lc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q2FtZWxDYXNlRmllbGROYW1lc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUHJpbWl0aXZlRmllbGQiLCAiU3RyaW5nRmllbGQiLCAiRW51bUZpZWxkIiwgIk1lc3NhZ2VGaWVsZCIsICJTdHJpbmdQaWVjZUZpZWxkIiwgIkNvcmRGaWVsZCIsICJSZXBlYXRlZFByaW1pdGl2ZUZpZWxkIiwgIlJlcGVhdGVkU3RyaW5nRmllbGQiLCAiUmVwZWF0ZWRFbnVtRmllbGQiLCAiUmVwZWF0ZWRNZXNzYWdlRmllbGQiLCAiUmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkIiwgIlJlcGVhdGVkQ29yZEZpZWxkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZpZWxkT3JkZXJpbmdzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDQyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RmllbGRPcmRlcmluZ3NfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZpZWxkT3JkZXJpbmdzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJNeVN0cmluZyIsICJNeUludCIsICJNeUZsb2F0IiwgIk9wdGlvbmFsTmVzdGVkTWVzc2FnZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RGaWVsZE9yZGVyaW5nc19OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZpZWxkT3JkZXJpbmdzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZpZWxkT3JkZXJpbmdzX05lc3RlZE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEZpZWxkT3JkZXJpbmdzX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9vIiwgIkJiIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczFfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25PcmRlcmluZ3MxX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25PcmRlcmluZ3MxX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJNeVN0cmluZyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25PcmRlcmluZ3MyX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDQ0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiTXlTdHJpbmciLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzMl9UZXN0RXh0ZW5zaW9uT3JkZXJpbmdzM19kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25PcmRlcmluZ3MyX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczJfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczJfVGVzdEV4dGVuc2lvbk9yZGVyaW5nczNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk15U3RyaW5nIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDQ1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0cmVtZURlZmF1bHRWYWx1ZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dHJlbWVEZWZhdWx0VmFsdWVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJFc2NhcGVkQnl0ZXMiLCAiTGFyZ2VVaW50MzIiLCAiTGFyZ2VVaW50NjQiLCAiU21hbGxJbnQzMiIsICJTbWFsbEludDY0IiwgIlJlYWxseVNtYWxsSW50MzIiLCAiUmVhbGx5U21hbGxJbnQ2NCIsICJVdGY4U3RyaW5nIiwgIlplcm9GbG9hdCIsICJPbmVGbG9hdCIsICJTbWFsbEZsb2F0IiwgIk5lZ2F0aXZlT25lRmxvYXQiLCAiTmVnYXRpdmVGbG9hdCIsICJMYXJnZUZsb2F0IiwgIlNtYWxsTmVnYXRpdmVGbG9hdCIsICJJbmZEb3VibGUiLCAiTmVnSW5mRG91YmxlIiwgIk5hbkRvdWJsZSIsICJJbmZGbG9hdCIsICJOZWdJbmZGbG9hdCIsICJOYW5GbG9hdCIsICJDcHBUcmlncmFwaCIsICJTdHJpbmdXaXRoWmVybyIsICJCeXRlc1dpdGhaZXJvIiwgIlN0cmluZ1BpZWNlV2l0aFplcm8iLCAiQ29yZFdpdGhaZXJvIiwgIlJlcGxhY2VtZW50U3RyaW5nIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU3BhcnNlRW51bU1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNDYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NwYXJzZUVudW1NZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1NwYXJzZUVudW1NZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJTcGFyc2VFbnVtIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT25lU3RyaW5nX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDQ3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PbmVTdHJpbmdfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT25lU3RyaW5nX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJEYXRhIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTW9yZVN0cmluZ19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg0OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTW9yZVN0cmluZ19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Nb3JlU3RyaW5nX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJEYXRhIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT25lQnl0ZXNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNDkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09uZUJ5dGVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09uZUJ5dGVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJEYXRhIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTW9yZUJ5dGVzX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDUwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Nb3JlQnl0ZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTW9yZUJ5dGVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJEYXRhIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFueU9wdGlvbmFsU3RyaW5nX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDUxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9NYW55T3B0aW9uYWxTdHJpbmdfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfTWFueU9wdGlvbmFsU3RyaW5nX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJTdHIxIiwgIlN0cjIiLCAiU3RyMyIsICJTdHI0IiwgIlN0cjUiLCAiU3RyNiIsICJTdHI3IiwgIlN0cjgiLCAiU3RyOSIsICJTdHIxMCIsICJTdHIxMSIsICJTdHIxMiIsICJTdHIxMyIsICJTdHIxNCIsICJTdHIxNSIsICJTdHIxNiIsICJTdHIxNyIsICJTdHIxOCIsICJTdHIxOSIsICJTdHIyMCIsICJTdHIyMSIsICJTdHIyMiIsICJTdHIyMyIsICJTdHIyNCIsICJTdHIyNSIsICJTdHIyNiIsICJTdHIyNyIsICJTdHIyOCIsICJTdHIyOSIsICJTdHIzMCIsICJTdHIzMSIsICJTdHIzMiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDMyTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg1Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfSW50MzJNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDMyTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRGF0YSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1VpbnQzMk1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNTMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1VpbnQzMk1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVWludDMyTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRGF0YSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDY0TWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg1NCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfSW50NjRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDY0TWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRGF0YSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1VpbnQ2NE1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNTUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1VpbnQ2NE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVWludDY0TWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRGF0YSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Jvb2xNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDU2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Cb29sTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Cb29sTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRGF0YSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg1Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRm9vSW50IiwgIkZvb1N0cmluZyIsICJGb29NZXNzYWdlIiwgIkZvb0dyb3VwIiwgIkZvbyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZl9Gb29Hcm91cF9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZl9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZl9Gb29Hcm91cF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2ZfRm9vR3JvdXBfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkEiLCAiQiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNTgpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRm9vSW50IiwgIkZvb1N0cmluZyIsICJGb29NZXNzYWdlIiwgIkZvb0dyb3VwIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mQmFja3dhcmRzQ29tcGF0aWJsZV9Gb29Hcm91cF9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGVfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2ZCYWNrd2FyZHNDb21wYXRpYmxlX0Zvb0dyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGVfRm9vR3JvdXBfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkEiLCAiQiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZjJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNTkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZjJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mMl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRm9vSW50IiwgIkZvb1N0cmluZyIsICJGb29Db3JkIiwgIkZvb1N0cmluZ1BpZWNlIiwgIkZvb0J5dGVzIiwgIkZvb0VudW0iLCAiRm9vTWVzc2FnZSIsICJGb29Hcm91cCIsICJGb29MYXp5TWVzc2FnZSIsICJGb29CeXRlc0NvcmQiLCAiQmFySW50IiwgIkJhclN0cmluZyIsICJCYXJDb3JkIiwgIkJhclN0cmluZ1BpZWNlIiwgIkJhckJ5dGVzIiwgIkJhckVudW0iLCAiQmFyU3RyaW5nV2l0aEVtcHR5RGVmYXVsdCIsICJCYXJDb3JkV2l0aEVtcHR5RGVmYXVsdCIsICJCYXJTdHJpbmdQaWVjZVdpdGhFbXB0eURlZmF1bHQiLCAiQmFyQnl0ZXNXaXRoRW1wdHlEZWZhdWx0IiwgIkJhekludCIsICJCYXpTdHJpbmciLCAiRm9vIiwgIkJhciIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZjJfRm9vR3JvdXBfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2YyX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mMl9Gb29Hcm91cF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2YyX0Zvb0dyb3VwX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJBIiwgIkIiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2YyX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0T25lb2YyX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE9uZW9mMl9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RPbmVvZjJfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiTW9vSW50IiwgIkNvcmdlSW50IiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkT25lb2ZfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNjApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE9uZW9mX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE9uZW9mX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGb29JbnQiLCAiRm9vU3RyaW5nIiwgIkZvb01lc3NhZ2UiLCAiRm9vTGF6eU1lc3NhZ2UiLCAiRm9vIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkT25lb2ZfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RSZXF1aXJlZE9uZW9mX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcXVpcmVkT25lb2ZfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVxdWlyZWRPbmVvZl9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJSZXF1aXJlZERvdWJsZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg2MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYWNrZWRUeXBlc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUGFja2VkSW50MzIiLCAiUGFja2VkSW50NjQiLCAiUGFja2VkVWludDMyIiwgIlBhY2tlZFVpbnQ2NCIsICJQYWNrZWRTaW50MzIiLCAiUGFja2VkU2ludDY0IiwgIlBhY2tlZEZpeGVkMzIiLCAiUGFja2VkRml4ZWQ2NCIsICJQYWNrZWRTZml4ZWQzMiIsICJQYWNrZWRTZml4ZWQ2NCIsICJQYWNrZWRGbG9hdCIsICJQYWNrZWREb3VibGUiLCAiUGFja2VkQm9vbCIsICJQYWNrZWRFbnVtIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFVucGFja2VkVHlwZXNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNjIpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZFR5cGVzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJVbnBhY2tlZEludDMyIiwgIlVucGFja2VkSW50NjQiLCAiVW5wYWNrZWRVaW50MzIiLCAiVW5wYWNrZWRVaW50NjQiLCAiVW5wYWNrZWRTaW50MzIiLCAiVW5wYWNrZWRTaW50NjQiLCAiVW5wYWNrZWRGaXhlZDMyIiwgIlVucGFja2VkRml4ZWQ2NCIsICJVbnBhY2tlZFNmaXhlZDMyIiwgIlVucGFja2VkU2ZpeGVkNjQiLCAiVW5wYWNrZWRGbG9hdCIsICJVbnBhY2tlZERvdWJsZSIsICJVbnBhY2tlZEJvb2wiLCAiVW5wYWNrZWRFbnVtIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhY2tlZEV4dGVuc2lvbnNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNjMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYWNrZWRFeHRlbnNpb25zX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYWNrZWRFeHRlbnNpb25zX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZEV4dGVuc2lvbnNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNjQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RVbnBhY2tlZEV4dGVuc2lvbnNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFVucGFja2VkRXh0ZW5zaW9uc19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHluYW1pY0V4dGVuc2lvbnNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNjUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REeW5hbWljRXh0ZW5zaW9uc19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RHluYW1pY0V4dGVuc2lvbnNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlNjYWxhckV4dGVuc2lvbiIsICJFbnVtRXh0ZW5zaW9uIiwgIkR5bmFtaWNFbnVtRXh0ZW5zaW9uIiwgIk1lc3NhZ2VFeHRlbnNpb24iLCAiRHluYW1pY01lc3NhZ2VFeHRlbnNpb24iLCAiUmVwZWF0ZWRFeHRlbnNpb24iLCAiUGFja2VkRXh0ZW5zaW9uIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER5bmFtaWNFeHRlbnNpb25zX0R5bmFtaWNNZXNzYWdlVHlwZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REeW5hbWljRXh0ZW5zaW9uc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3REeW5hbWljRXh0ZW5zaW9uc19EeW5hbWljTWVzc2FnZVR5cGVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdER5bmFtaWNFeHRlbnNpb25zX0R5bmFtaWNNZXNzYWdlVHlwZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRHluYW1pY0ZpZWxkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcGVhdGVkU3RyaW5nX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDY2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVwZWF0ZWRTdHJpbmdfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcGVhdGVkU3RyaW5nX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJSZXBlYXRlZFN0cmluZzEiLCAiUmVwZWF0ZWRTdHJpbmcyIiwgIlJlcGVhdGVkQnl0ZXMxMSIsICJSZXBlYXRlZEJ5dGVzMTIiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UmVwZWF0ZWRTY2FsYXJEaWZmZXJlbnRUYWdTaXplc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg2Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVyZW50VGFnU2l6ZXNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlJlcGVhdGVkRml4ZWQzMiIsICJSZXBlYXRlZEludDMyIiwgIlJlcGVhdGVkRml4ZWQ2NCIsICJSZXBlYXRlZEludDY0IiwgIlJlcGVhdGVkRmxvYXQiLCAiUmVwZWF0ZWRVaW50NjQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDY4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlJlcXVpcmVkQWxsVHlwZXMiLCAiT3B0aW9uYWxBbGxUeXBlcyIsICJSZXBlYXRlZEFsbFR5cGVzIiwgIk9wdGlvbmFsR3JvdXAiLCAiUmVwZWF0ZWRHcm91cCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9SZXBlYXRlZEZpZWxkc0dlbmVyYXRvcl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX1JlcGVhdGVkRmllbGRzR2VuZXJhdG9yX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZDEiLCAiRmllbGQyIiwgIkZpZWxkMyIsICJHcm91cDEiLCAiR3JvdXAyIiwgIkV4dDEiLCAiRXh0MiIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfR3JvdXAxX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9SZXBlYXRlZEZpZWxkc0dlbmVyYXRvcl9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfR3JvdXAxX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfR3JvdXAxX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZDEiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX1JlcGVhdGVkRmllbGRzR2VuZXJhdG9yX0dyb3VwMl9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3JfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX1JlcGVhdGVkRmllbGRzR2VuZXJhdG9yX0dyb3VwMl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX1JlcGVhdGVkRmllbGRzR2VuZXJhdG9yX0dyb3VwMl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRmllbGQxIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9PcHRpb25hbEdyb3VwX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfT3B0aW9uYWxHcm91cF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX09wdGlvbmFsR3JvdXBfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsR3JvdXBBbGxUeXBlcyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfUmVwZWF0ZWRHcm91cF9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RQYXJzaW5nTWVyZ2VfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFyc2luZ01lcmdlX1JlcGVhdGVkR3JvdXBfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhcnNpbmdNZXJnZV9SZXBlYXRlZEdyb3VwX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJSZXBlYXRlZEdyb3VwQWxsVHlwZXMiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVyZ2VFeGNlcHRpb25fZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNjkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXJnZUV4Y2VwdGlvbl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVyZ2VFeGNlcHRpb25fZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkFsbEV4dGVuc2lvbnMiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNzApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q29tbWVudEluamVjdGlvbk1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkEiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNpemVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNzEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RNZXNzYWdlU2l6ZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVNpemVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk0xIiwgIk0yIiwgIk0zIiwgIk00IiwgIk01IiwgIk02IiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRm9vUmVxdWVzdF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg3Mik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRm9vUmVxdWVzdF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29SZXF1ZXN0X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Zvb1Jlc3BvbnNlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDczKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29SZXNwb25zZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29SZXNwb25zZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29DbGllbnRNZXNzYWdlX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDc0KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29DbGllbnRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Zvb0NsaWVudE1lc3NhZ2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRm9vU2VydmVyTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg3NSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRm9vU2VydmVyTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Gb29TZXJ2ZXJNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0JhclJlcXVlc3RfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNzYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0JhclJlcXVlc3RfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQmFyUmVxdWVzdF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9CYXJSZXNwb25zZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg3Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQmFyUmVzcG9uc2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfQmFyUmVzcG9uc2VfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEpzb25OYW1lX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDc4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SnNvbk5hbWVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEpzb25OYW1lX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGaWVsZE5hbWUxIiwgIkZpZWxkTmFtZTIiLCAiRmllbGROYW1lMyIsICJGaWVsZE5hbWU0IiwgIkZJRUxETkFNRTUiLCAiRmllbGROYW1lNiIsICJGaWVsZG5hbWU3IiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEh1Z2VGaWVsZE51bWJlcnNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoNzkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RIdWdlRmllbGROdW1iZXJzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RIdWdlRmllbGROdW1iZXJzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbEludDMyIiwgIkZpeGVkMzIiLCAiUmVwZWF0ZWRJbnQzMiIsICJQYWNrZWRJbnQzMiIsICJPcHRpb25hbEVudW0iLCAiT3B0aW9uYWxTdHJpbmciLCAiT3B0aW9uYWxCeXRlcyIsICJPcHRpb25hbE1lc3NhZ2UiLCAiT3B0aW9uYWxHcm91cCIsICJTdHJpbmdTdHJpbmdNYXAiLCAiT25lb2ZVaW50MzIiLCAiT25lb2ZUZXN0QWxsVHlwZXMiLCAiT25lb2ZTdHJpbmciLCAiT25lb2ZCeXRlcyIsICJPbmVvZkZpZWxkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEh1Z2VGaWVsZE51bWJlcnNfT3B0aW9uYWxHcm91cF9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RIdWdlRmllbGROdW1iZXJzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEh1Z2VGaWVsZE51bWJlcnNfT3B0aW9uYWxHcm91cF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SHVnZUZpZWxkTnVtYmVyc19PcHRpb25hbEdyb3VwX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJHcm91cEEiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0SHVnZUZpZWxkTnVtYmVyc19TdHJpbmdTdHJpbmdNYXBFbnRyeV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RIdWdlRmllbGROdW1iZXJzX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEh1Z2VGaWVsZE51bWJlcnNfU3RyaW5nU3RyaW5nTWFwRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEh1Z2VGaWVsZE51bWJlcnNfU3RyaW5nU3RyaW5nTWFwRW50cnlfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIktleSIsICJWYWx1ZSIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25JbnNpZGVUYWJsZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg4MCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvbkluc2lkZVRhYmxlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RFeHRlbnNpb25JbnNpZGVUYWJsZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRmllbGQxIiwgIkZpZWxkMiIsICJGaWVsZDMiLCAiRmllbGQ0IiwgIkZpZWxkNiIsICJGaWVsZDciLCAiRmllbGQ4IiwgIkZpZWxkOSIsICJGaWVsZDEwIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoODEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJMYXllcjFPcHRpb25hbEdyb3VwIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcl9MYXllcjFPcHRpb25hbEdyb3VwX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJMYXllcjJSZXBlYXRlZEdyb3VwIiwgIkxheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXAiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcl9MYXllcjFPcHRpb25hbEdyb3VwX0xheWVyMlJlcGVhdGVkR3JvdXBfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcl9MYXllcjFPcHRpb25hbEdyb3VwX2Rlc2NyaXB0b3IuZ2V0TmVzdGVkVHlwZXMoKS5nZXQoMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9MYXllcjJSZXBlYXRlZEdyb3VwX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyX0xheWVyMU9wdGlvbmFsR3JvdXBfTGF5ZXIyUmVwZWF0ZWRHcm91cF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiQW5vdGhlckZpZWxkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9MYXllcjJBbm90aGVyT3B0aW9uYWxSZXBlYXRlZEdyb3VwX2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZEdyb3VwRXh0ZW5zaW9uT3V0ZXJfTGF5ZXIxT3B0aW9uYWxHcm91cF9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDEpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbk91dGVyX0xheWVyMU9wdGlvbmFsR3JvdXBfTGF5ZXIyQW5vdGhlck9wdGlvbmFsUmVwZWF0ZWRHcm91cF9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25PdXRlcl9MYXllcjFPcHRpb25hbEdyb3VwX0xheWVyMkFub3RoZXJPcHRpb25hbFJlcGVhdGVkR3JvdXBfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIkJ1dFdoeVRobyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3ROZXN0ZWRHcm91cEV4dGVuc2lvbklubmVyRXh0ZW5zaW9uX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDgyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkR3JvdXBFeHRlbnNpb25Jbm5lckV4dGVuc2lvbl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiSW5uZXJOYW1lIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDgzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0RXh0ZW5zaW9uUmFuZ2VTZXJpYWxpemVfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdEV4dGVuc2lvblJhbmdlU2VyaWFsaXplX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJGb29PbmUiLCAiRm9vVHdvIiwgIkZvb1RocmVlIiwgIkZvb0ZvdXIiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJTaW1wbGVfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoODQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlJbnQzMlNpbXBsZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJTaW1wbGVfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsSW50MzIxIiwgIk9wdGlvbmFsSW50MzIyIiwgIk9wdGlvbmFsSW50MzI2MyIsICJPcHRpb25hbEludDMyNjQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoODUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlJbnQzMl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsSW50MzIxIiwgIk9wdGlvbmFsSW50MzIyIiwgIk9wdGlvbmFsSW50MzI2MyIsICJPcHRpb25hbEludDMyNjQiLCAiT3B0aW9uYWxBbGxUeXBlcyIsICJSZXBlYXRlZEFsbFR5cGVzIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU1vc3RseUludDMyX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDg2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5TW9zdGx5SW50MzJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU1vc3RseUludDMyX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbEludDY0MzAiLCAiT3B0aW9uYWxJbnQzMjEiLCAiT3B0aW9uYWxJbnQzMjIiLCAiT3B0aW9uYWxJbnQzMjMiLCAiT3B0aW9uYWxJbnQzMjQiLCAiT3B0aW9uYWxJbnQzMjYzIiwgIk9wdGlvbmFsSW50MzI2NCIsICJPcHRpb25hbEFsbFR5cGVzIiwgIlJlcGVhdGVkQWxsVHlwZXMiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5TW9zdGx5SW50MzJCaWdGaWVsZE51bWJlcl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg4Nyk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU1vc3RseUludDMyQmlnRmllbGROdW1iZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsSW50NjQzMCIsICJPcHRpb25hbEludDMyMzAwIiwgIk9wdGlvbmFsSW50MzIxIiwgIk9wdGlvbmFsSW50MzIyIiwgIk9wdGlvbmFsSW50MzIzIiwgIk9wdGlvbmFsSW50MzI0IiwgIk9wdGlvbmFsSW50MzI2MyIsICJPcHRpb25hbEludDMyNjQiLCAiT3B0aW9uYWxBbGxUeXBlcyIsICJSZXBlYXRlZEFsbFR5cGVzIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeVVpbnQzMlNpbXBsZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg4OCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeVVpbnQzMlNpbXBsZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5VWludDMyU2ltcGxlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbFVpbnQzMjEiLCAiT3B0aW9uYWxVaW50MzIyIiwgIk9wdGlvbmFsVWludDMyNjMiLCAiT3B0aW9uYWxVaW50MzI2NCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlVaW50MzJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoODkpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlVaW50MzJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeVVpbnQzMl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiT3B0aW9uYWxVaW50MzIxIiwgIk9wdGlvbmFsVWludDMyMiIsICJPcHRpb25hbFVpbnQzMjYzIiwgIk9wdGlvbmFsVWludDMyNjQiLCAiT3B0aW9uYWxBbGxUeXBlcyIsICJSZXBlYXRlZEFsbFR5cGVzIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU9uZVVpbnQzMl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg5MCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU9uZVVpbnQzMl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5T25lVWludDMyX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbFVpbnQzMjEiLCAiT3B0aW9uYWxJbnQzMjIiLCAiT3B0aW9uYWxJbnQzMjYzIiwgIk9wdGlvbmFsSW50MzI2NCIsICJPcHRpb25hbEFsbFR5cGVzIiwgIlJlcGVhdGVkQWxsVHlwZXMiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5T25lSW50MzJCaWdGaWVsZE51bWJlcl9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCg5MSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeU9uZUludDMyQmlnRmllbGROdW1iZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsSW50MzI2NSIsICJPcHRpb25hbEludDY0MSIsICJPcHRpb25hbEludDY0MiIsICJPcHRpb25hbEludDY0NjMiLCAiT3B0aW9uYWxJbnQ2NDY0IiwgIk9wdGlvbmFsQWxsVHlwZXMiLCAiUmVwZWF0ZWRBbGxUeXBlcyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlJbnQzMkJpZ0ZpZWxkTnVtYmVyX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDkyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5SW50MzJCaWdGaWVsZE51bWJlcl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiT3B0aW9uYWxJbnQzMjEwMDAiLCAiT3B0aW9uYWxJbnQzMjY1IiwgIk9wdGlvbmFsSW50MzIxIiwgIk9wdGlvbmFsSW50MzIyIiwgIk9wdGlvbmFsSW50MzI2MyIsICJPcHRpb25hbEludDMyNjQiLCAiT3B0aW9uYWxBbGxUeXBlcyIsICJSZXBlYXRlZEFsbFR5cGVzIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDkzKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5VWludDMyQmlnRmllbGROdW1iZXJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeVVpbnQzMkJpZ0ZpZWxkTnVtYmVyX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbFVpbnQzMjEwMDAiLCAiT3B0aW9uYWxVaW50MzI2NSIsICJPcHRpb25hbFVpbnQzMjEiLCAiT3B0aW9uYWxVaW50MzIyIiwgIk9wdGlvbmFsVWludDMyNjMiLCAiT3B0aW9uYWxVaW50MzI2NCIsICJPcHRpb25hbEFsbFR5cGVzIiwgIlJlcGVhdGVkQWxsVHlwZXMiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoOTQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0VmVyaWZ5QmlnRmllbGROdW1iZXJVaW50MzJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsTmVzdGVkIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyX05lc3RlZF9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMl9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RWZXJpZnlCaWdGaWVsZE51bWJlclVpbnQzMl9OZXN0ZWRfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFZlcmlmeUJpZ0ZpZWxkTnVtYmVyVWludDMyX05lc3RlZF9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiT3B0aW9uYWxVaW50MzI1MDAwIiwgIk9wdGlvbmFsVWludDMyMTAwMCIsICJPcHRpb25hbFVpbnQzMjY2IiwgIk9wdGlvbmFsVWludDMyNjUiLCAiT3B0aW9uYWxVaW50MzIxIiwgIk9wdGlvbmFsVWludDMyMiIsICJPcHRpb25hbFVpbnQzMjYzIiwgIk9wdGlvbmFsVWludDMyNjQiLCAiT3B0aW9uYWxOZXN0ZWQiLCAiUmVwZWF0ZWROZXN0ZWQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FbnVtUGFyc2VUZXN0ZXJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoOTUpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0VudW1QYXJzZVRlc3Rlcl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FbnVtUGFyc2VUZXN0ZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsU2VxU21hbGwwTG93ZmllbGQiLCAiT3B0aW9uYWxTZXFTbWFsbDBNaWRmaWVsZCIsICJPcHRpb25hbFNlcVNtYWxsMEhpZmllbGQiLCAiUmVwZWF0ZWRTZXFTbWFsbDBMb3dmaWVsZCIsICJSZXBlYXRlZFNlcVNtYWxsME1pZGZpZWxkIiwgIlJlcGVhdGVkU2VxU21hbGwwSGlmaWVsZCIsICJQYWNrZWRTZXFTbWFsbDBMb3dmaWVsZCIsICJQYWNrZWRTZXFTbWFsbDBNaWRmaWVsZCIsICJQYWNrZWRTZXFTbWFsbDBIaWZpZWxkIiwgIk9wdGlvbmFsU2VxU21hbGwxTG93ZmllbGQiLCAiT3B0aW9uYWxTZXFTbWFsbDFNaWRmaWVsZCIsICJPcHRpb25hbFNlcVNtYWxsMUhpZmllbGQiLCAiUmVwZWF0ZWRTZXFTbWFsbDFMb3dmaWVsZCIsICJSZXBlYXRlZFNlcVNtYWxsMU1pZGZpZWxkIiwgIlJlcGVhdGVkU2VxU21hbGwxSGlmaWVsZCIsICJQYWNrZWRTZXFTbWFsbDFMb3dmaWVsZCIsICJQYWNrZWRTZXFTbWFsbDFNaWRmaWVsZCIsICJQYWNrZWRTZXFTbWFsbDFIaWZpZWxkIiwgIk9wdGlvbmFsU2VxTGFyZ2VMb3dmaWVsZCIsICJPcHRpb25hbFNlcUxhcmdlTWlkZmllbGQiLCAiT3B0aW9uYWxTZXFMYXJnZUhpZmllbGQiLCAiUmVwZWF0ZWRTZXFMYXJnZUxvd2ZpZWxkIiwgIlJlcGVhdGVkU2VxTGFyZ2VNaWRmaWVsZCIsICJSZXBlYXRlZFNlcUxhcmdlSGlmaWVsZCIsICJQYWNrZWRTZXFMYXJnZUxvd2ZpZWxkIiwgIlBhY2tlZFNlcUxhcmdlTWlkZmllbGQiLCAiUGFja2VkU2VxTGFyZ2VIaWZpZWxkIiwgIk9wdGlvbmFsQXJiaXRyYXJ5TG93ZmllbGQiLCAiT3B0aW9uYWxBcmJpdHJhcnlNaWRmaWVsZCIsICJPcHRpb25hbEFyYml0cmFyeUhpZmllbGQiLCAiUmVwZWF0ZWRBcmJpdHJhcnlMb3dmaWVsZCIsICJSZXBlYXRlZEFyYml0cmFyeU1pZGZpZWxkIiwgIlJlcGVhdGVkQXJiaXRyYXJ5SGlmaWVsZCIsICJQYWNrZWRBcmJpdHJhcnlMb3dmaWVsZCIsICJQYWNrZWRBcmJpdHJhcnlNaWRmaWVsZCIsICJQYWNrZWRBcmJpdHJhcnlIaWZpZWxkIiwgIk90aGVyRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Cb29sUGFyc2VUZXN0ZXJfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoOTYpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0Jvb2xQYXJzZVRlc3Rlcl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Cb29sUGFyc2VUZXN0ZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsQm9vbExvd2ZpZWxkIiwgIk9wdGlvbmFsQm9vbE1pZGZpZWxkIiwgIk9wdGlvbmFsQm9vbEhpZmllbGQiLCAiUmVwZWF0ZWRCb29sTG93ZmllbGQiLCAiUmVwZWF0ZWRCb29sTWlkZmllbGQiLCAiUmVwZWF0ZWRCb29sSGlmaWVsZCIsICJQYWNrZWRCb29sTG93ZmllbGQiLCAiUGFja2VkQm9vbE1pZGZpZWxkIiwgIlBhY2tlZEJvb2xIaWZpZWxkIiwgIk90aGVyRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbnQzMlBhcnNlVGVzdGVyX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDk3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbnQzMlBhcnNlVGVzdGVyX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDMyUGFyc2VUZXN0ZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsSW50MzJMb3dmaWVsZCIsICJPcHRpb25hbEludDMyTWlkZmllbGQiLCAiT3B0aW9uYWxJbnQzMkhpZmllbGQiLCAiUmVwZWF0ZWRJbnQzMkxvd2ZpZWxkIiwgIlJlcGVhdGVkSW50MzJNaWRmaWVsZCIsICJSZXBlYXRlZEludDMySGlmaWVsZCIsICJQYWNrZWRJbnQzMkxvd2ZpZWxkIiwgIlBhY2tlZEludDMyTWlkZmllbGQiLCAiUGFja2VkSW50MzJIaWZpZWxkIiwgIk90aGVyRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbnQ2NFBhcnNlVGVzdGVyX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDk4KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbnQ2NFBhcnNlVGVzdGVyX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0ludDY0UGFyc2VUZXN0ZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsSW50NjRMb3dmaWVsZCIsICJPcHRpb25hbEludDY0TWlkZmllbGQiLCAiT3B0aW9uYWxJbnQ2NEhpZmllbGQiLCAiUmVwZWF0ZWRJbnQ2NExvd2ZpZWxkIiwgIlJlcGVhdGVkSW50NjRNaWRmaWVsZCIsICJSZXBlYXRlZEludDY0SGlmaWVsZCIsICJQYWNrZWRJbnQ2NExvd2ZpZWxkIiwgIlBhY2tlZEludDY0TWlkZmllbGQiLCAiUGFja2VkSW50NjRIaWZpZWxkIiwgIk90aGVyRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDk5KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9JbmxpbmVkU3RyaW5nSWR4UmVncmVzc2lvblByb3RvX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0lubGluZWRTdHJpbmdJZHhSZWdyZXNzaW9uUHJvdG9fZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIlN0cjEiLCAiU3ViIiwgIlN0cjIiLCAiU3RyMyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1N0cmluZ1BhcnNlVGVzdGVyX2Rlc2NyaXB0b3IgPQogICAgICBnZXREZXNjcmlwdG9yKCkuZ2V0TWVzc2FnZVR5cGVzKCkuZ2V0KDEwMCk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU3RyaW5nUGFyc2VUZXN0ZXJfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfU3RyaW5nUGFyc2VUZXN0ZXJfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsU3RyaW5nTG93ZmllbGQiLCAiT3B0aW9uYWxTdHJpbmdNaWRmaWVsZCIsICJPcHRpb25hbFN0cmluZ0hpZmllbGQiLCAiUmVwZWF0ZWRTdHJpbmdMb3dmaWVsZCIsICJSZXBlYXRlZFN0cmluZ01pZGZpZWxkIiwgIlJlcGVhdGVkU3RyaW5nSGlmaWVsZCIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0JhZEZpZWxkTmFtZXNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMTAxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9CYWRGaWVsZE5hbWVzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0JhZEZpZWxkTmFtZXNfZGVzY3JpcHRvciwKICAgICAgICBuZXcgamF2YS5sYW5nLlN0cmluZ1tdIHsgIk9wdGlvbmFsSW50MzIiLCAiRm9yIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE5lc3RlZE1lc3NhZ2VSZWRhY3Rpb25fZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMTAyKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbl9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TmVzdGVkTWVzc2FnZVJlZGFjdGlvbl9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiT3B0aW9uYWxVbnJlZGFjdGVkTmVzdGVkU3RyaW5nIiwgIk9wdGlvbmFsUmVkYWN0ZWROZXN0ZWRTdHJpbmciLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SZWRhY3RlZEZpZWxkc19kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxMDMpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlZGFjdGVkRmllbGRzX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlZGFjdGVkRmllbGRzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbFJlZGFjdGVkU3RyaW5nIiwgIk9wdGlvbmFsVW5yZWRhY3RlZFN0cmluZyIsICJSZXBlYXRlZFJlZGFjdGVkU3RyaW5nIiwgIlJlcGVhdGVkVW5yZWRhY3RlZFN0cmluZyIsICJPcHRpb25hbFJlZGFjdGVkTWVzc2FnZSIsICJPcHRpb25hbFVucmVkYWN0ZWRNZXNzYWdlIiwgIlJlcGVhdGVkUmVkYWN0ZWRNZXNzYWdlIiwgIlJlcGVhdGVkVW5yZWRhY3RlZE1lc3NhZ2UiLCAiTWFwUmVkYWN0ZWRTdHJpbmciLCAiTWFwVW5yZWRhY3RlZFN0cmluZyIsIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlZGFjdGVkRmllbGRzX01hcFJlZGFjdGVkU3RyaW5nRW50cnlfZGVzY3JpcHRvciA9CiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SZWRhY3RlZEZpZWxkc19kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1JlZGFjdGVkRmllbGRzX01hcFJlZGFjdGVkU3RyaW5nRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmVkYWN0ZWRGaWVsZHNfTWFwUmVkYWN0ZWRTdHJpbmdFbnRyeV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiS2V5IiwgIlZhbHVlIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmVkYWN0ZWRGaWVsZHNfTWFwVW5yZWRhY3RlZFN0cmluZ0VudHJ5X2Rlc2NyaXB0b3IgPQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmVkYWN0ZWRGaWVsZHNfZGVzY3JpcHRvci5nZXROZXN0ZWRUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9SZWRhY3RlZEZpZWxkc19NYXBVbnJlZGFjdGVkU3RyaW5nRW50cnlfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfUmVkYWN0ZWRGaWVsZHNfTWFwVW5yZWRhY3RlZFN0cmluZ0VudHJ5X2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJLZXkiLCAiVmFsdWUiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0Q29yZF9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxMDQpOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDb3JkX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1Rlc3RDb3JkX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJPcHRpb25hbEJ5dGVzQ29yZCIsICJPcHRpb25hbEJ5dGVzQ29yZERlZmF1bHQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMTA1KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0UGFja2VkRW51bVNtYWxsUmFuZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdFBhY2tlZEVudW1TbWFsbFJhbmdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJWYWxzIiwgfSk7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRW51bXNGb3JCZW5jaG1hcmtfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMTA2KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FbnVtc0ZvckJlbmNobWFya19maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FbnVtc0ZvckJlbmNobWFya19kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHNfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMTA3KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9UZXN0TWVzc2FnZVdpdGhNYW55UmVwZWF0ZWRQdHJGaWVsZHNfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVGVzdE1lc3NhZ2VXaXRoTWFueVJlcGVhdGVkUHRyRmllbGRzX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJSZXBlYXRlZFN0cmluZzEiLCAiUmVwZWF0ZWRTdHJpbmcyIiwgIlJlcGVhdGVkU3RyaW5nMyIsICJSZXBlYXRlZFN0cmluZzQiLCAiUmVwZWF0ZWRTdHJpbmc1IiwgIlJlcGVhdGVkU3RyaW5nNiIsICJSZXBlYXRlZFN0cmluZzciLCAiUmVwZWF0ZWRTdHJpbmc4IiwgIlJlcGVhdGVkU3RyaW5nOSIsICJSZXBlYXRlZFN0cmluZzEwIiwgIlJlcGVhdGVkU3RyaW5nMTEiLCAiUmVwZWF0ZWRTdHJpbmcxMiIsICJSZXBlYXRlZFN0cmluZzEzIiwgIlJlcGVhdGVkU3RyaW5nMTQiLCAiUmVwZWF0ZWRTdHJpbmcxNSIsICJSZXBlYXRlZFN0cmluZzE2IiwgIlJlcGVhdGVkU3RyaW5nMTciLCAiUmVwZWF0ZWRTdHJpbmcxOCIsICJSZXBlYXRlZFN0cmluZzE5IiwgIlJlcGVhdGVkU3RyaW5nMjAiLCAiUmVwZWF0ZWRTdHJpbmcyMSIsICJSZXBlYXRlZFN0cmluZzIyIiwgIlJlcGVhdGVkU3RyaW5nMjMiLCAiUmVwZWF0ZWRTdHJpbmcyNCIsICJSZXBlYXRlZFN0cmluZzI1IiwgIlJlcGVhdGVkU3RyaW5nMjYiLCAiUmVwZWF0ZWRTdHJpbmcyNyIsICJSZXBlYXRlZFN0cmluZzI4IiwgIlJlcGVhdGVkU3RyaW5nMjkiLCAiUmVwZWF0ZWRTdHJpbmczMCIsICJSZXBlYXRlZFN0cmluZzMxIiwgIlJlcGVhdGVkU3RyaW5nMzIiLCB9KTsKICAgIG9wdGlvbmFsSW50MzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgwKSk7CiAgICBvcHRpb25hbEludDY0RXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMSkpOwogICAgb3B0aW9uYWxVaW50MzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgyKSk7CiAgICBvcHRpb25hbFVpbnQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDMpKTsKICAgIG9wdGlvbmFsU2ludDMyRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNCkpOwogICAgb3B0aW9uYWxTaW50NjRFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg1KSk7CiAgICBvcHRpb25hbEZpeGVkMzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg2KSk7CiAgICBvcHRpb25hbEZpeGVkNjRFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg3KSk7CiAgICBvcHRpb25hbFNmaXhlZDMyRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoOCkpOwogICAgb3B0aW9uYWxTZml4ZWQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDkpKTsKICAgIG9wdGlvbmFsRmxvYXRFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxMCkpOwogICAgb3B0aW9uYWxEb3VibGVFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxMSkpOwogICAgb3B0aW9uYWxCb29sRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTIpKTsKICAgIG9wdGlvbmFsU3RyaW5nRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTMpKTsKICAgIG9wdGlvbmFsQnl0ZXNFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxNCkpOwogICAgb3B0aW9uYWxHcm91cEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDE1KSk7CiAgICBvcHRpb25hbE5lc3RlZE1lc3NhZ2VFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxNikpOwogICAgb3B0aW9uYWxGb3JlaWduTWVzc2FnZUV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDE3KSk7CiAgICBvcHRpb25hbEltcG9ydE1lc3NhZ2VFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxOCkpOwogICAgb3B0aW9uYWxOZXN0ZWRFbnVtRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTkpKTsKICAgIG9wdGlvbmFsRm9yZWlnbkVudW1FeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgyMCkpOwogICAgb3B0aW9uYWxJbXBvcnRFbnVtRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjEpKTsKICAgIG9wdGlvbmFsU3RyaW5nUGllY2VFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgyMikpOwogICAgb3B0aW9uYWxDb3JkRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjMpKTsKICAgIG9wdGlvbmFsUHVibGljSW1wb3J0TWVzc2FnZUV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDI0KSk7CiAgICBvcHRpb25hbExhenlNZXNzYWdlRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjUpKTsKICAgIG9wdGlvbmFsVW52ZXJpZmllZExhenlNZXNzYWdlRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMjYpKTsKICAgIHJlcGVhdGVkSW50MzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgyNykpOwogICAgcmVwZWF0ZWRJbnQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDI4KSk7CiAgICByZXBlYXRlZFVpbnQzMkV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDI5KSk7CiAgICByZXBlYXRlZFVpbnQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDMwKSk7CiAgICByZXBlYXRlZFNpbnQzMkV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDMxKSk7CiAgICByZXBlYXRlZFNpbnQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDMyKSk7CiAgICByZXBlYXRlZEZpeGVkMzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzMykpOwogICAgcmVwZWF0ZWRGaXhlZDY0RXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMzQpKTsKICAgIHJlcGVhdGVkU2ZpeGVkMzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgzNSkpOwogICAgcmVwZWF0ZWRTZml4ZWQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDM2KSk7CiAgICByZXBlYXRlZEZsb2F0RXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMzcpKTsKICAgIHJlcGVhdGVkRG91YmxlRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMzgpKTsKICAgIHJlcGVhdGVkQm9vbEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDM5KSk7CiAgICByZXBlYXRlZFN0cmluZ0V4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQwKSk7CiAgICByZXBlYXRlZEJ5dGVzRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNDEpKTsKICAgIHJlcGVhdGVkR3JvdXBFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg0MikpOwogICAgcmVwZWF0ZWROZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNDMpKTsKICAgIHJlcGVhdGVkRm9yZWlnbk1lc3NhZ2VFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg0NCkpOwogICAgcmVwZWF0ZWRJbXBvcnRNZXNzYWdlRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNDUpKTsKICAgIHJlcGVhdGVkTmVzdGVkRW51bUV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQ2KSk7CiAgICByZXBlYXRlZEZvcmVpZ25FbnVtRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNDcpKTsKICAgIHJlcGVhdGVkSW1wb3J0RW51bUV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQ4KSk7CiAgICByZXBlYXRlZFN0cmluZ1BpZWNlRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNDkpKTsKICAgIHJlcGVhdGVkQ29yZEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDUwKSk7CiAgICByZXBlYXRlZExhenlNZXNzYWdlRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNTEpKTsKICAgIGRlZmF1bHRJbnQzMkV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDUyKSk7CiAgICBkZWZhdWx0SW50NjRFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg1MykpOwogICAgZGVmYXVsdFVpbnQzMkV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDU0KSk7CiAgICBkZWZhdWx0VWludDY0RXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNTUpKTsKICAgIGRlZmF1bHRTaW50MzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg1NikpOwogICAgZGVmYXVsdFNpbnQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDU3KSk7CiAgICBkZWZhdWx0Rml4ZWQzMkV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDU4KSk7CiAgICBkZWZhdWx0Rml4ZWQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDU5KSk7CiAgICBkZWZhdWx0U2ZpeGVkMzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg2MCkpOwogICAgZGVmYXVsdFNmaXhlZDY0RXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNjEpKTsKICAgIGRlZmF1bHRGbG9hdEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDYyKSk7CiAgICBkZWZhdWx0RG91YmxlRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNjMpKTsKICAgIGRlZmF1bHRCb29sRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNjQpKTsKICAgIGRlZmF1bHRTdHJpbmdFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg2NSkpOwogICAgZGVmYXVsdEJ5dGVzRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNjYpKTsKICAgIGRlZmF1bHROZXN0ZWRFbnVtRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNjcpKTsKICAgIGRlZmF1bHRGb3JlaWduRW51bUV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDY4KSk7CiAgICBkZWZhdWx0SW1wb3J0RW51bUV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDY5KSk7CiAgICBkZWZhdWx0U3RyaW5nUGllY2VFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg3MCkpOwogICAgZGVmYXVsdENvcmRFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg3MSkpOwogICAgb25lb2ZVaW50MzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg3MikpOwogICAgb25lb2ZOZXN0ZWRNZXNzYWdlRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNzMpKTsKICAgIG9uZW9mU3RyaW5nRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNzQpKTsKICAgIG9uZW9mQnl0ZXNFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg3NSkpOwogICAgbXlFeHRlbnNpb25TdHJpbmcuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg3NikpOwogICAgbXlFeHRlbnNpb25JbnQuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg3NykpOwogICAgcGFja2VkSW50MzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg3OCkpOwogICAgcGFja2VkSW50NjRFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg3OSkpOwogICAgcGFja2VkVWludDMyRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoODApKTsKICAgIHBhY2tlZFVpbnQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDgxKSk7CiAgICBwYWNrZWRTaW50MzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg4MikpOwogICAgcGFja2VkU2ludDY0RXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoODMpKTsKICAgIHBhY2tlZEZpeGVkMzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg4NCkpOwogICAgcGFja2VkRml4ZWQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDg1KSk7CiAgICBwYWNrZWRTZml4ZWQzMkV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDg2KSk7CiAgICBwYWNrZWRTZml4ZWQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDg3KSk7CiAgICBwYWNrZWRGbG9hdEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDg4KSk7CiAgICBwYWNrZWREb3VibGVFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg4OSkpOwogICAgcGFja2VkQm9vbEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDkwKSk7CiAgICBwYWNrZWRFbnVtRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoOTEpKTsKICAgIHVucGFja2VkSW50MzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg5MikpOwogICAgdW5wYWNrZWRJbnQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDkzKSk7CiAgICB1bnBhY2tlZFVpbnQzMkV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDk0KSk7CiAgICB1bnBhY2tlZFVpbnQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDk1KSk7CiAgICB1bnBhY2tlZFNpbnQzMkV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDk2KSk7CiAgICB1bnBhY2tlZFNpbnQ2NEV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDk3KSk7CiAgICB1bnBhY2tlZEZpeGVkMzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg5OCkpOwogICAgdW5wYWNrZWRGaXhlZDY0RXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoOTkpKTsKICAgIHVucGFja2VkU2ZpeGVkMzJFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxMDApKTsKICAgIHVucGFja2VkU2ZpeGVkNjRFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxMDEpKTsKICAgIHVucGFja2VkRmxvYXRFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxMDIpKTsKICAgIHVucGFja2VkRG91YmxlRXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTAzKSk7CiAgICB1bnBhY2tlZEJvb2xFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxMDQpKTsKICAgIHVucGFja2VkRW51bUV4dGVuc2lvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDEwNSkpOwogICAgdGVzdEFsbFR5cGVzLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTA2KSk7CiAgICB0ZXN0RXh0ZW5zaW9uSW5zaWRlVGFibGVFeHRlbnNpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxMDcpKTsKICAgIGlubmVyLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTA4KSk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3QuVW5pdHRlc3RJbXBvcnQuZ2V0RGVzY3JpcHRvcigpOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEAeeGE5l+nAQBfpwEAKAAAAHByb3RvYnVmX3VuaXR0ZXN0L1VuaXR0ZXN0UmV0ZW50aW9uLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9yZXRlbnRpb24ucHJvdG8KCi8vIFByb3RvYnVmIEphdmEgVmVyc2lvbjogMy4yNS40LWRldgpwYWNrYWdlIHByb3RvYnVmX3VuaXR0ZXN0OwoKcHVibGljIGZpbmFsIGNsYXNzIFVuaXR0ZXN0UmV0ZW50aW9uIHsKICBwcml2YXRlIFVuaXR0ZXN0UmV0ZW50aW9uKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLnBsYWluT3B0aW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5ydW50aW1lUmV0ZW50aW9uT3B0aW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5zb3VyY2VSZXRlbnRpb25PcHRpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLmZpbGVPcHRpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLnJlcGVhdGVkT3B0aW9ucyk7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uZXh0ZW5zaW9uUmFuZ2VPcHRpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLm1lc3NhZ2VPcHRpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLmZpZWxkT3B0aW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5vbmVvZk9wdGlvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uZW51bU9wdGlvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uZW51bUVudHJ5T3B0aW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5zZXJ2aWNlT3B0aW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5tZXRob2RPcHRpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLmkpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5zKTsKICB9CgogIHB1YmxpYyBzdGF0aWMgdm9pZCByZWdpc3RlckFsbEV4dGVuc2lvbnMoCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnkgcmVnaXN0cnkpIHsKICAgIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgICAoY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUpIHJlZ2lzdHJ5KTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgZW51bSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVG9wTGV2ZWxFbnVtfQogICAqLwogIHB1YmxpYyBlbnVtIFRvcExldmVsRW51bQogICAgICBpbXBsZW1lbnRzIGNvbS5nb29nbGUucHJvdG9idWYuUHJvdG9jb2xNZXNzYWdlRW51bSB7CiAgICAvKioKICAgICAqIDxjb2RlPlRPUF9MRVZFTF9VTktOT1dOID0gMCBbKC5wcm90b2J1Zl91bml0dGVzdC5lbnVtX2VudHJ5X29wdGlvbikgPSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBUT1BfTEVWRUxfVU5LTk9XTigwKSwKICAgIDsKCiAgICAvKioKICAgICAqIDxjb2RlPlRPUF9MRVZFTF9VTktOT1dOID0gMCBbKC5wcm90b2J1Zl91bml0dGVzdC5lbnVtX2VudHJ5X29wdGlvbikgPSB7IC4uLiB9PC9jb2RlPgogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBUT1BfTEVWRUxfVU5LTk9XTl9WQUxVRSA9IDA7CgoKICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICByZXR1cm4gdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBzdGF0aWMgVG9wTGV2ZWxFbnVtIHZhbHVlT2YoaW50IHZhbHVlKSB7CiAgICAgIHJldHVybiBmb3JOdW1iZXIodmFsdWUpOwogICAgfQoKICAgIC8qKgogICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1lcmljIHdpcmUgdmFsdWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgZW51bSBlbnRyeS4KICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgVG9wTGV2ZWxFbnVtIGZvck51bWJlcihpbnQgdmFsdWUpIHsKICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgIGNhc2UgMDogcmV0dXJuIFRPUF9MRVZFTF9VTktOT1dOOwogICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICB9CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFRvcExldmVsRW51bT4KICAgICAgICBpbnRlcm5hbEdldFZhbHVlTWFwKCkgewogICAgICByZXR1cm4gaW50ZXJuYWxWYWx1ZU1hcDsKICAgIH0KICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8CiAgICAgICAgVG9wTGV2ZWxFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFRvcExldmVsRW51bT4oKSB7CiAgICAgICAgICAgIHB1YmxpYyBUb3BMZXZlbEVudW0gZmluZFZhbHVlQnlOdW1iZXIoaW50IG51bWJlcikgewogICAgICAgICAgICAgIHJldHVybiBUb3BMZXZlbEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgIH0KICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUb3BMZXZlbEVudW1bXSBWQUxVRVMgPSB2YWx1ZXMoKTsKCiAgICBwdWJsaWMgc3RhdGljIFRvcExldmVsRW51bSB2YWx1ZU9mKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgIGlmIChkZXNjLmdldFR5cGUoKSAhPSBnZXREZXNjcmlwdG9yKCkpIHsKICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigKICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICB9CiAgICAgIHJldHVybiBWQUxVRVNbZGVzYy5nZXRJbmRleCgpXTsKICAgIH0KCiAgICBwcml2YXRlIGZpbmFsIGludCB2YWx1ZTsKCiAgICBwcml2YXRlIFRvcExldmVsRW51bShpbnQgdmFsdWUpIHsKICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRvcExldmVsRW51bSkKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgT3B0aW9uc01lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuT3B0aW9uc01lc3NhZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9yQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBwbGFpbl9maWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwbGFpbkZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNQbGFpbkZpZWxkKCk7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHBsYWluX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBwbGFpbkZpZWxkLgogICAgICovCiAgICBpbnQgZ2V0UGxhaW5GaWVsZCgpOwoKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgcnVudGltZV9yZXRlbnRpb25fZmllbGQgPSAyIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBydW50aW1lUmV0ZW50aW9uRmllbGQgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc1J1bnRpbWVSZXRlbnRpb25GaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBydW50aW1lX3JldGVudGlvbl9maWVsZCA9IDIgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBydW50aW1lUmV0ZW50aW9uRmllbGQuCiAgICAgKi8KICAgIGludCBnZXRSdW50aW1lUmV0ZW50aW9uRmllbGQoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHNvdXJjZV9yZXRlbnRpb25fZmllbGQgPSAzIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fU09VUkNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHNvdXJjZVJldGVudGlvbkZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgYm9vbGVhbiBoYXNTb3VyY2VSZXRlbnRpb25GaWVsZCgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBzb3VyY2VfcmV0ZW50aW9uX2ZpZWxkID0gMyBbcmV0ZW50aW9uID0gUkVURU5USU9OX1NPVVJDRV07PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgc291cmNlUmV0ZW50aW9uRmllbGQuCiAgICAgKi8KICAgIGludCBnZXRTb3VyY2VSZXRlbnRpb25GaWVsZCgpOwogIH0KICAvKioKICAgKiA8cHJlPgogICAqIFJldGVudGlvbiBhdHRyaWJ1dGVzIHNldCBvbiBmaWVsZHMgbmVzdGVkIHdpdGhpbiBhIG1lc3NhZ2UKICAgKiA8L3ByZT4KICAgKgogICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0Lk9wdGlvbnNNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgT3B0aW9uc01lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMyBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuT3B0aW9uc01lc3NhZ2UpCiAgICAgIE9wdGlvbnNNZXNzYWdlT3JCdWlsZGVyIHsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgIC8vIFVzZSBPcHRpb25zTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBPcHRpb25zTWVzc2FnZShjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyPD8+IGJ1aWxkZXIpIHsKICAgICAgc3VwZXIoYnVpbGRlcik7CiAgICB9CiAgICBwcml2YXRlIE9wdGlvbnNNZXNzYWdlKCkgewogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIEBTdXBwcmVzc1dhcm5pbmdzKHsidW51c2VkIn0pCiAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICBVbnVzZWRQcml2YXRlUGFyYW1ldGVyIHVudXNlZCkgewogICAgICByZXR1cm4gbmV3IE9wdGlvbnNNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09wdGlvbnNNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09wdGlvbnNNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQTEFJTl9GSUVMRF9GSUVMRF9OVU1CRVIgPSAxOwogICAgcHJpdmF0ZSBpbnQgcGxhaW5GaWVsZF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBwbGFpbl9maWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwbGFpbkZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzUGxhaW5GaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBwbGFpbl9maWVsZCA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgcGxhaW5GaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRQbGFpbkZpZWxkKCkgewogICAgICByZXR1cm4gcGxhaW5GaWVsZF87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUlVOVElNRV9SRVRFTlRJT05fRklFTERfRklFTERfTlVNQkVSID0gMjsKICAgIHByaXZhdGUgaW50IHJ1bnRpbWVSZXRlbnRpb25GaWVsZF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBydW50aW1lX3JldGVudGlvbl9maWVsZCA9IDIgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHJ1bnRpbWVSZXRlbnRpb25GaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1J1bnRpbWVSZXRlbnRpb25GaWVsZCgpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDIpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBydW50aW1lX3JldGVudGlvbl9maWVsZCA9IDIgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBydW50aW1lUmV0ZW50aW9uRmllbGQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgZ2V0UnVudGltZVJldGVudGlvbkZpZWxkKCkgewogICAgICByZXR1cm4gcnVudGltZVJldGVudGlvbkZpZWxkXzsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTT1VSQ0VfUkVURU5USU9OX0ZJRUxEX0ZJRUxEX05VTUJFUiA9IDM7CiAgICBwcml2YXRlIGludCBzb3VyY2VSZXRlbnRpb25GaWVsZF8gPSAwOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBzb3VyY2VfcmV0ZW50aW9uX2ZpZWxkID0gMyBbcmV0ZW50aW9uID0gUkVURU5USU9OX1NPVVJDRV07PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBzb3VyY2VSZXRlbnRpb25GaWVsZCBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc1NvdXJjZVJldGVudGlvbkZpZWxkKCkgewogICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHNvdXJjZV9yZXRlbnRpb25fZmllbGQgPSAzIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fU09VUkNFXTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBzb3VyY2VSZXRlbnRpb25GaWVsZC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTb3VyY2VSZXRlbnRpb25GaWVsZCgpIHsKICAgICAgcmV0dXJuIHNvdXJjZVJldGVudGlvbkZpZWxkXzsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBtZW1vaXplZElzSW5pdGlhbGl6ZWQgPSAxOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIHBsYWluRmllbGRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigyLCBydW50aW1lUmV0ZW50aW9uRmllbGRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQzMigzLCBzb3VyY2VSZXRlbnRpb25GaWVsZF8pOwogICAgICB9CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIHBsYWluRmllbGRfKTsKICAgICAgfQogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDIsIHJ1bnRpbWVSZXRlbnRpb25GaWVsZF8pOwogICAgICB9CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDA0KSAhPSAwKSkgewogICAgICAgIHNpemUgKz0gY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbQogICAgICAgICAgLmNvbXB1dGVJbnQzMlNpemUoMywgc291cmNlUmV0ZW50aW9uRmllbGRfKTsKICAgICAgfQogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UpIG9iajsKCiAgICAgIGlmIChoYXNQbGFpbkZpZWxkKCkgIT0gb3RoZXIuaGFzUGxhaW5GaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNQbGFpbkZpZWxkKCkpIHsKICAgICAgICBpZiAoZ2V0UGxhaW5GaWVsZCgpCiAgICAgICAgICAgICE9IG90aGVyLmdldFBsYWluRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmIChoYXNSdW50aW1lUmV0ZW50aW9uRmllbGQoKSAhPSBvdGhlci5oYXNSdW50aW1lUmV0ZW50aW9uRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzUnVudGltZVJldGVudGlvbkZpZWxkKCkpIHsKICAgICAgICBpZiAoZ2V0UnVudGltZVJldGVudGlvbkZpZWxkKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0UnVudGltZVJldGVudGlvbkZpZWxkKCkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoaGFzU291cmNlUmV0ZW50aW9uRmllbGQoKSAhPSBvdGhlci5oYXNTb3VyY2VSZXRlbnRpb25GaWVsZCgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNTb3VyY2VSZXRlbnRpb25GaWVsZCgpKSB7CiAgICAgICAgaWYgKGdldFNvdXJjZVJldGVudGlvbkZpZWxkKCkKICAgICAgICAgICAgIT0gb3RoZXIuZ2V0U291cmNlUmV0ZW50aW9uRmllbGQoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc1BsYWluRmllbGQoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIFBMQUlOX0ZJRUxEX0ZJRUxEX05VTUJFUjsKICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBnZXRQbGFpbkZpZWxkKCk7CiAgICAgIH0KICAgICAgaWYgKGhhc1J1bnRpbWVSZXRlbnRpb25GaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgUlVOVElNRV9SRVRFTlRJT05fRklFTERfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldFJ1bnRpbWVSZXRlbnRpb25GaWVsZCgpOwogICAgICB9CiAgICAgIGlmIChoYXNTb3VyY2VSZXRlbnRpb25GaWVsZCgpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgU09VUkNFX1JFVEVOVElPTl9GSUVMRF9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgZ2V0U291cmNlUmV0ZW50aW9uRmllbGQoKTsKICAgICAgfQogICAgICBoYXNoID0gKDI5ICogaGFzaCkgKyBnZXRVbmtub3duRmllbGRzKCkuaGFzaENvZGUoKTsKICAgICAgbWVtb2l6ZWRIYXNoQ29kZSA9IGhhc2g7CiAgICAgIHJldHVybiBoYXNoOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkJ5dGVTdHJpbmcgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgYnl0ZVtdIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcigpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIEJ1aWxkZXIgbmV3QnVpbGRlcihwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiA8cHJlPgogICAgICogUmV0ZW50aW9uIGF0dHJpYnV0ZXMgc2V0IG9uIGZpZWxkcyBuZXN0ZWQgd2l0aGluIGEgbWVzc2FnZQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuT3B0aW9uc01lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlcjxCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5PcHRpb25zTWVzc2FnZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZU9yQnVpbGRlciB7CiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT3B0aW9uc01lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09wdGlvbnNNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBwbGFpbkZpZWxkXyA9IDA7CiAgICAgICAgcnVudGltZVJldGVudGlvbkZpZWxkXyA9IDA7CiAgICAgICAgc291cmNlUmV0ZW50aW9uRmllbGRfID0gMDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X09wdGlvbnNNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZUZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICBpZiAoIXJlc3VsdC5pc0luaXRpYWxpemVkKCkpIHsKICAgICAgICAgIHRocm93IG5ld1VuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uKHJlc3VsdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlIGJ1aWxkUGFydGlhbCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UodGhpcyk7CiAgICAgICAgaWYgKGJpdEZpZWxkMF8gIT0gMCkgeyBidWlsZFBhcnRpYWwwKHJlc3VsdCk7IH0KICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHJpdmF0ZSB2b2lkIGJ1aWxkUGFydGlhbDAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UgcmVzdWx0KSB7CiAgICAgICAgaW50IGZyb21fYml0RmllbGQwXyA9IGJpdEZpZWxkMF87CiAgICAgICAgaW50IHRvX2JpdEZpZWxkMF8gPSAwOwogICAgICAgIGlmICgoKGZyb21fYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApKSB7CiAgICAgICAgICByZXN1bHQucGxhaW5GaWVsZF8gPSBwbGFpbkZpZWxkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMikgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5ydW50aW1lUmV0ZW50aW9uRmllbGRfID0gcnVudGltZVJldGVudGlvbkZpZWxkXzsKICAgICAgICAgIHRvX2JpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMjsKICAgICAgICB9CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5zb3VyY2VSZXRlbnRpb25GaWVsZF8gPSBzb3VyY2VSZXRlbnRpb25GaWVsZF87CiAgICAgICAgICB0b19iaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgfQogICAgICAgIHJlc3VsdC5iaXRGaWVsZDBfIHw9IHRvX2JpdEZpZWxkMF87CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2Upb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNQbGFpbkZpZWxkKCkpIHsKICAgICAgICAgIHNldFBsYWluRmllbGQob3RoZXIuZ2V0UGxhaW5GaWVsZCgpKTsKICAgICAgICB9CiAgICAgICAgaWYgKG90aGVyLmhhc1J1bnRpbWVSZXRlbnRpb25GaWVsZCgpKSB7CiAgICAgICAgICBzZXRSdW50aW1lUmV0ZW50aW9uRmllbGQob3RoZXIuZ2V0UnVudGltZVJldGVudGlvbkZpZWxkKCkpOwogICAgICAgIH0KICAgICAgICBpZiAob3RoZXIuaGFzU291cmNlUmV0ZW50aW9uRmllbGQoKSkgewogICAgICAgICAgc2V0U291cmNlUmV0ZW50aW9uRmllbGQob3RoZXIuZ2V0U291cmNlUmV0ZW50aW9uRmllbGQoKSk7CiAgICAgICAgfQogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgcGxhaW5GaWVsZF8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgY2FzZSAxNjogewogICAgICAgICAgICAgICAgcnVudGltZVJldGVudGlvbkZpZWxkXyA9IGlucHV0LnJlYWRJbnQzMigpOwogICAgICAgICAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBjYXNlIDE2CiAgICAgICAgICAgICAgY2FzZSAyNDogewogICAgICAgICAgICAgICAgc291cmNlUmV0ZW50aW9uRmllbGRfID0gaW5wdXQucmVhZEludDMyKCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMjQKICAgICAgICAgICAgICBkZWZhdWx0OiB7CiAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsgLy8gd2FzIGFuIGVuZGdyb3VwIHRhZwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfSAvLyBkZWZhdWx0OgogICAgICAgICAgICB9IC8vIHN3aXRjaCAodGFnKQogICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS51bndyYXBJT0V4Y2VwdGlvbigpOwogICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICB9IC8vIGZpbmFsbHkKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBwcml2YXRlIGludCBiaXRGaWVsZDBfOwoKICAgICAgcHJpdmF0ZSBpbnQgcGxhaW5GaWVsZF8gOwogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgcGxhaW5fZmllbGQgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBwbGFpbkZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUGxhaW5GaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHBsYWluX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHBsYWluRmllbGQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0UGxhaW5GaWVsZCgpIHsKICAgICAgICByZXR1cm4gcGxhaW5GaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHBsYWluX2ZpZWxkID0gMTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGxhaW5GaWVsZCB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFBsYWluRmllbGQoaW50IHZhbHVlKSB7CgogICAgICAgIHBsYWluRmllbGRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBwbGFpbl9maWVsZCA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclBsYWluRmllbGQoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIHBsYWluRmllbGRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgcnVudGltZVJldGVudGlvbkZpZWxkXyA7CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBydW50aW1lX3JldGVudGlvbl9maWVsZCA9IDIgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgcnVudGltZVJldGVudGlvbkZpZWxkIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzUnVudGltZVJldGVudGlvbkZpZWxkKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAyKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgcnVudGltZV9yZXRlbnRpb25fZmllbGQgPSAyIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fUlVOVElNRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBydW50aW1lUmV0ZW50aW9uRmllbGQuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0UnVudGltZVJldGVudGlvbkZpZWxkKCkgewogICAgICAgIHJldHVybiBydW50aW1lUmV0ZW50aW9uRmllbGRfOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBydW50aW1lX3JldGVudGlvbl9maWVsZCA9IDIgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgcnVudGltZVJldGVudGlvbkZpZWxkIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UnVudGltZVJldGVudGlvbkZpZWxkKGludCB2YWx1ZSkgewoKICAgICAgICBydW50aW1lUmV0ZW50aW9uRmllbGRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDAyOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBydW50aW1lX3JldGVudGlvbl9maWVsZCA9IDIgW3JldGVudGlvbiA9IFJFVEVOVElPTl9SVU5USU1FXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyUnVudGltZVJldGVudGlvbkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDAyKTsKICAgICAgICBydW50aW1lUmV0ZW50aW9uRmllbGRfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBpbnQgc291cmNlUmV0ZW50aW9uRmllbGRfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHNvdXJjZV9yZXRlbnRpb25fZmllbGQgPSAzIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fU09VUkNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgc291cmNlUmV0ZW50aW9uRmllbGQgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNTb3VyY2VSZXRlbnRpb25GaWVsZCgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwNCkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHNvdXJjZV9yZXRlbnRpb25fZmllbGQgPSAzIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fU09VUkNFXTs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIHNvdXJjZVJldGVudGlvbkZpZWxkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGdldFNvdXJjZVJldGVudGlvbkZpZWxkKCkgewogICAgICAgIHJldHVybiBzb3VyY2VSZXRlbnRpb25GaWVsZF87CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIHNvdXJjZV9yZXRlbnRpb25fZmllbGQgPSAzIFtyZXRlbnRpb24gPSBSRVRFTlRJT05fU09VUkNFXTs8L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgc291cmNlUmV0ZW50aW9uRmllbGQgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRTb3VyY2VSZXRlbnRpb25GaWVsZChpbnQgdmFsdWUpIHsKCiAgICAgICAgc291cmNlUmV0ZW50aW9uRmllbGRfID0gdmFsdWU7CiAgICAgICAgYml0RmllbGQwXyB8PSAweDAwMDAwMDA0OwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBzb3VyY2VfcmV0ZW50aW9uX2ZpZWxkID0gMyBbcmV0ZW50aW9uID0gUkVURU5USU9OX1NPVVJDRV07PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhclNvdXJjZVJldGVudGlvbkZpZWxkKCkgewogICAgICAgIGJpdEZpZWxkMF8gPSAoYml0RmllbGQwXyAmIH4weDAwMDAwMDA0KTsKICAgICAgICBzb3VyY2VSZXRlbnRpb25GaWVsZF8gPSAwOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lk9wdGlvbnNNZXNzYWdlKQogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChjbGFzc19zY29wZTpwcm90b2J1Zl91bml0dGVzdC5PcHRpb25zTWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE9wdGlvbnNNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPE9wdGlvbnNNZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgT3B0aW9uc01lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPcHRpb25zTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxPcHRpb25zTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIGludGVyZmFjZSBFeHRlbmRlZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5FeHRlbmRlZSkKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuCiAgICAgICAgICBFeHRlbmRhYmxlTWVzc2FnZU9yQnVpbGRlcjxFeHRlbmRlZT4gewogIH0KICAvKioKICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5FeHRlbmRlZX0KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEV4dGVuZGVlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZU1lc3NhZ2U8CiAgICAgICAgRXh0ZW5kZWU+IGltcGxlbWVudHMKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG1lc3NhZ2VfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5FeHRlbmRlZSkKICAgICAgRXh0ZW5kZWVPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIEV4dGVuZGVlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIEV4dGVuZGVlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBFeHRlbmRlZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBFeHRlbmRlZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FeHRlbmRlZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FeHRlbmRlZV9maWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5FeHRlbmRlZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5FeHRlbmRhYmxlTWVzc2FnZTxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5FeHRlbmRlZT4uRXh0ZW5zaW9uV3JpdGVyCiAgICAgICAgICBleHRlbnNpb25Xcml0ZXIgPSBuZXdFeHRlbnNpb25Xcml0ZXIoKTsKICAgICAgZXh0ZW5zaW9uV3JpdGVyLndyaXRlVW50aWwoMywgb3V0cHV0KTsKICAgICAgZ2V0VW5rbm93bkZpZWxkcygpLndyaXRlVG8ob3V0cHV0KTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgaW50IGdldFNlcmlhbGl6ZWRTaXplKCkgewogICAgICBpbnQgc2l6ZSA9IG1lbW9pemVkU2l6ZTsKICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgc2l6ZSA9IDA7CiAgICAgIHNpemUgKz0gZXh0ZW5zaW9uc1NlcmlhbGl6ZWRTaXplKCk7CiAgICAgIHNpemUgKz0gZ2V0VW5rbm93bkZpZWxkcygpLmdldFNlcmlhbGl6ZWRTaXplKCk7CiAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgIHJldHVybiBzaXplOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGVxdWFscyhmaW5hbCBqYXZhLmxhbmcuT2JqZWN0IG9iaikgewogICAgICBpZiAob2JqID09IHRoaXMpIHsKICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICAgIGlmICghKG9iaiBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5FeHRlbmRlZSBvdGhlciA9IChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5FeHRlbmRlZSkgb2JqOwoKICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5FeHRlbmRlZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5FeHRlbmRlZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5FeHRlbmRlZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5FeHRlbmRlZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5FeHRlbmRlZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LkV4dGVuZGVlfQogICAgICovCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcwogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPAogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUsIEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LkV4dGVuZGVlKQogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlT3JCdWlsZGVyIHsKICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FeHRlbmRlZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRXh0ZW5kZWVfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUubmV3QnVpbGRlcigpCiAgICAgIHByaXZhdGUgQnVpbGRlcigpIHsKCiAgICAgIH0KCiAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgICAgc3VwZXIocGFyZW50KTsKCiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhcigpIHsKICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfRXh0ZW5kZWVfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5FeHRlbmRlZSh0aGlzKTsKICAgICAgICBvbkJ1aWx0KCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xvbmUoKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5PbmVvZkRlc2NyaXB0b3Igb25lb2YpIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJPbmVvZihvbmVvZik7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBpbnQgaW5kZXgsIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0UmVwZWF0ZWRGaWVsZChmaWVsZCwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGFkZFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkUmVwZWF0ZWRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUsIFR5cGU+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIHNldEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBhZGRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlLCBqYXZhLnV0aWwuTGlzdDxUeXBlPj4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFQ+IEJ1aWxkZXIgY2xlYXJFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlLCBUPiBleHRlbnNpb24pIHsKICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJFeHRlbnNpb24oZXh0ZW5zaW9uKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5FeHRlbmRlZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUpb3RoZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBzdXBlci5tZXJnZUZyb20ob3RoZXIpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20ocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUgb3RoZXIpIHsKICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIHRoaXMubWVyZ2VFeHRlbnNpb25GaWVsZHMob3RoZXIpOwogICAgICAgIHRoaXMubWVyZ2VVbmtub3duRmllbGRzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSk7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIGlmIChleHRlbnNpb25SZWdpc3RyeSA9PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgamF2YS5sYW5nLk51bGxQb2ludGVyRXhjZXB0aW9uKCk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICBib29sZWFuIGRvbmUgPSBmYWxzZTsKICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICBpbnQgdGFnID0gaW5wdXQucmVhZFRhZygpOwogICAgICAgICAgICBzd2l0Y2ggKHRhZykgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBzZXRVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIubWVyZ2VVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICB9CgoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuRXh0ZW5kZWUpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LkV4dGVuZGVlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUgREVGQVVMVF9JTlNUQU5DRTsKICAgIHN0YXRpYyB7CiAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uRXh0ZW5kZWUoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8RXh0ZW5kZWU+CiAgICAgICAgUEFSU0VSID0gbmV3IGNvbS5nb29nbGUucHJvdG9idWYuQWJzdHJhY3RQYXJzZXI8RXh0ZW5kZWU+KCkgewogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBFeHRlbmRlZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEV4dGVuZGVlPiBwYXJzZXIoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPEV4dGVuZGVlPiBnZXRQYXJzZXJGb3JUeXBlKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5FeHRlbmRlZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgfQoKICBwdWJsaWMgaW50ZXJmYWNlIFRvcExldmVsTWVzc2FnZU9yQnVpbGRlciBleHRlbmRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChpbnRlcmZhY2VfZXh0ZW5kczpwcm90b2J1Zl91bml0dGVzdC5Ub3BMZXZlbE1lc3NhZ2UpCiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLgogICAgICAgICAgRXh0ZW5kYWJsZU1lc3NhZ2VPckJ1aWxkZXI8VG9wTGV2ZWxNZXNzYWdlPiB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmID0gMSBbKC5wcm90b2J1Zl91bml0dGVzdC5maWVsZF9vcHRpb24pID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgZiBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzRigpOwogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmID0gMSBbKC5wcm90b2J1Zl91bml0dGVzdC5maWVsZF9vcHRpb24pID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGYuCiAgICAgKi8KICAgIGZsb2F0IGdldEYoKTsKCiAgICAvKioKICAgICAqIDxjb2RlPmludDY0IGkgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIGJvb2xlYW4gaGFzSSgpOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBpID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFRoZSBpLgogICAgICovCiAgICBsb25nIGdldEkoKTsKCiAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuT0Nhc2UgZ2V0T0Nhc2UoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVG9wTGV2ZWxNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVG9wTGV2ZWxNZXNzYWdlIGV4dGVuZHMKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZU1lc3NhZ2U8CiAgICAgICAgVG9wTGV2ZWxNZXNzYWdlPiBpbXBsZW1lbnRzCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVG9wTGV2ZWxNZXNzYWdlKQogICAgICBUb3BMZXZlbE1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRvcExldmVsTWVzc2FnZS5uZXdCdWlsZGVyKCkgdG8gY29uc3RydWN0LgogICAgcHJpdmF0ZSBUb3BMZXZlbE1lc3NhZ2UoY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8cHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUb3BMZXZlbE1lc3NhZ2UoKSB7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgQFN1cHByZXNzV2FybmluZ3MoeyJ1bnVzZWQifSkKICAgIHByb3RlY3RlZCBqYXZhLmxhbmcuT2JqZWN0IG5ld0luc3RhbmNlKAogICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgIHJldHVybiBuZXcgVG9wTGV2ZWxNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1RvcExldmVsTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Ub3BMZXZlbE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFByb3RvYnVmIGVudW0ge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRvcExldmVsTWVzc2FnZS5OZXN0ZWRFbnVtfQogICAgICovCiAgICBwdWJsaWMgZW51bSBOZXN0ZWRFbnVtCiAgICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgICAvKioKICAgICAgICogPGNvZGU+TkVTVEVEX1VOS05PV04gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIE5FU1RFRF9VTktOT1dOKDApLAogICAgICA7CgogICAgICAvKioKICAgICAgICogPGNvZGU+TkVTVEVEX1VOS05PV04gPSAwOzwvY29kZT4KICAgICAgICovCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IE5FU1RFRF9VTktOT1dOX1ZBTFVFID0gMDsKCgogICAgICBwdWJsaWMgZmluYWwgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICAgKiBAcmV0dXJuIFRoZSBlbnVtIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gbnVtZXJpYyB3aXJlIHZhbHVlLgogICAgICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rICNmb3JOdW1iZXIoaW50KX0gaW5zdGVhZC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZAogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtZXJpYyB3aXJlIHZhbHVlIG9mIHRoZSBjb3JyZXNwb25kaW5nIGVudW0gZW50cnkuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1lcmljIHdpcmUgdmFsdWUuCiAgICAgICAqLwogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gZm9yTnVtYmVyKGludCB2YWx1ZSkgewogICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIE5FU1RFRF9VTktOT1dOOwogICAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgICAgfQogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8TmVzdGVkRW51bT4KICAgICAgICAgIGludGVybmFsR2V0VmFsdWVNYXAoKSB7CiAgICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDwKICAgICAgICAgIE5lc3RlZEVudW0+IGludGVybmFsVmFsdWVNYXAgPQogICAgICAgICAgICBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZU1hcDxOZXN0ZWRFbnVtPigpIHsKICAgICAgICAgICAgICBwdWJsaWMgTmVzdGVkRW51bSBmaW5kVmFsdWVCeU51bWJlcihpbnQgbnVtYmVyKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gTmVzdGVkRW51bS5mb3JOdW1iZXIobnVtYmVyKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtVmFsdWVEZXNjcmlwdG9yCiAgICAgICAgICBnZXRWYWx1ZURlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgICAgfQogICAgICBwdWJsaWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5FbnVtRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3IoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5nZXREZXNjcmlwdG9yKCkuZ2V0RW51bVR5cGVzKCkuZ2V0KDApOwogICAgICB9CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBOZXN0ZWRFbnVtW10gVkFMVUVTID0gdmFsdWVzKCk7CgogICAgICBwdWJsaWMgc3RhdGljIE5lc3RlZEVudW0gdmFsdWVPZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvciBkZXNjKSB7CiAgICAgICAgaWYgKGRlc2MuZ2V0VHlwZSgpICE9IGdldERlc2NyaXB0b3IoKSkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAgICJFbnVtVmFsdWVEZXNjcmlwdG9yIGlzIG5vdCBmb3IgdGhpcyB0eXBlLiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICAgIH0KCiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwoKICAgICAgcHJpdmF0ZSBOZXN0ZWRFbnVtKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGVudW1fc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZEVudW0pCiAgICB9CgogICAgcHVibGljIGludGVyZmFjZSBOZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIGV4dGVuZHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3QuVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3JCdWlsZGVyIHsKICAgIH0KICAgIC8qKgogICAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3QuVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgTmVzdGVkTWVzc2FnZSBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMgaW1wbGVtZW50cwogICAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChtZXNzYWdlX2ltcGxlbWVudHM6cHJvdG9idWZfdW5pdHRlc3QuVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpCiAgICAgICAgTmVzdGVkTWVzc2FnZU9yQnVpbGRlciB7CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAwTDsKICAgICAgLy8gVXNlIE5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpIHRvIGNvbnN0cnVjdC4KICAgICAgcHJpdmF0ZSBOZXN0ZWRNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8Pz4gYnVpbGRlcikgewogICAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgICB9CiAgICAgIHByaXZhdGUgTmVzdGVkTWVzc2FnZSgpIHsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgICBwcm90ZWN0ZWQgamF2YS5sYW5nLk9iamVjdCBuZXdJbnN0YW5jZSgKICAgICAgICAgIFVudXNlZFByaXZhdGVQYXJhbWV0ZXIgdW51c2VkKSB7CiAgICAgICAgcmV0dXJuIG5ldyBOZXN0ZWRNZXNzYWdlKCk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVG9wTGV2ZWxNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgICBpbnRlcm5hbEdldEZpZWxkQWNjZXNzb3JUYWJsZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1RvcExldmVsTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDApIHJldHVybiBmYWxzZTsKCiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgdm9pZCB3cml0ZVRvKGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0gb3V0cHV0KQogICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBnZXRVbmtub3duRmllbGRzKCkud3JpdGVUbyhvdXRwdXQpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBpbnQgZ2V0U2VyaWFsaXplZFNpemUoKSB7CiAgICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgICAgaWYgKHNpemUgIT0gLTEpIHJldHVybiBzaXplOwoKICAgICAgICBzaXplID0gMDsKICAgICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICAgIG1lbW9pemVkU2l6ZSA9IHNpemU7CiAgICAgICAgcmV0dXJuIHNpemU7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSkpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgICB9CiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UpIG9iajsKCiAgICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgaW50IGhhc2hDb2RlKCkgewogICAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICAgIH0KICAgICAgICBpbnQgaGFzaCA9IDQxOwogICAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICAgIG1lbW9pemVkSGFzaENvZGUgPSBoYXNoOwogICAgICAgIHJldHVybiBoYXNoOwogICAgICB9CgogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VGcm9tKGJ5dGVbXSBkYXRhKQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGJ5dGVbXSBkYXRhLAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgIH0KICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgICAgfQogICAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKCkgeyByZXR1cm4gbmV3QnVpbGRlcigpOyB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpOwogICAgICB9CiAgICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFLnRvQnVpbGRlcigpLm1lcmdlRnJvbShwcm90b3R5cGUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgdG9CdWlsZGVyKCkgewogICAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0LlRvcExldmVsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlfQogICAgICAgKi8KICAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXI8QnVpbGRlcj4gaW1wbGVtZW50cwogICAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSkKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlT3JCdWlsZGVyIHsKICAgICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Ub3BMZXZlbE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1RvcExldmVsTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAgIC5lbnN1cmVGaWVsZEFjY2Vzc29yc0luaXRpYWxpemVkKAogICAgICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuQnVpbGRlci5jbGFzcyk7CiAgICAgICAgfQoKICAgICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UubmV3QnVpbGRlcigpCiAgICAgICAgcHJpdmF0ZSBCdWlsZGVyKCkgewoKICAgICAgICB9CgogICAgICAgIHByaXZhdGUgQnVpbGRlcigKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgICBzdXBlci5jbGVhcigpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgICBnZXREZXNjcmlwdG9yRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVG9wTGV2ZWxNZXNzYWdlX05lc3RlZE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKTsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgYnVpbGQoKSB7CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSByZXN1bHQgPSBidWlsZFBhcnRpYWwoKTsKICAgICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UgcmVzdWx0ID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKHRoaXMpOwogICAgICAgICAgb25CdWlsdCgpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbG9uZSgpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuY2xlYXJGaWVsZChmaWVsZCk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck9uZW9mKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICAgIH0KICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShjb20uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2Ugb3RoZXIpIHsKICAgICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKSB7CiAgICAgICAgICAgIHJldHVybiBtZXJnZUZyb20oKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKW90aGVyKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlIG90aGVyKSB7CiAgICAgICAgICBpZiAob3RoZXIgPT0gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgICAgdGhpcy5tZXJnZVVua25vd25GaWVsZHMob3RoZXIuZ2V0VW5rbm93bkZpZWxkcygpKTsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgaWYgKGV4dGVuc2lvblJlZ2lzdHJ5ID09IG51bGwpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgICAgfQogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlICghZG9uZSkgewogICAgICAgICAgICAgIGludCB0YWcgPSBpbnB1dC5yZWFkVGFnKCk7CiAgICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgICBpZiAoIXN1cGVyLnBhcnNlVW5rbm93bkZpZWxkKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSwgdGFnKSkgewogICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgICAgfSAvLyB3aGlsZSAoIWRvbmUpCiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICAgIH0gZmluYWxseSB7CiAgICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICAgIHJldHVybiBzdXBlci5zZXRVbmtub3duRmllbGRzKHVua25vd25GaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIG1lcmdlVW5rbm93bkZpZWxkcygKICAgICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgICB9CgoKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSkKICAgICAgfQoKICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRvcExldmVsTWVzc2FnZS5OZXN0ZWRNZXNzYWdlKQogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBERUZBVUxUX0lOU1RBTkNFOwogICAgICBzdGF0aWMgewogICAgICAgIERFRkFVTFRfSU5TVEFOQ0UgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLk5lc3RlZE1lc3NhZ2UoKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPE5lc3RlZE1lc3NhZ2U+CiAgICAgICAgICBQQVJTRVIgPSBuZXcgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdFBhcnNlcjxOZXN0ZWRNZXNzYWdlPigpIHsKICAgICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgICAgcHVibGljIE5lc3RlZE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IGUuc2V0VW5maW5pc2hlZE1lc3NhZ2UoYnVpbGRlci5idWlsZFBhcnRpYWwoKSk7CiAgICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfSBjYXRjaCAoamF2YS5pby5JT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgfQogICAgICB9OwoKICAgICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxOZXN0ZWRNZXNzYWdlPiBwYXJzZXIoKSB7CiAgICAgICAgcmV0dXJuIFBBUlNFUjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8TmVzdGVkTWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gUEFSU0VSOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgICB9CgogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwcml2YXRlIGludCBvQ2FzZV8gPSAwOwogICAgQFN1cHByZXNzV2FybmluZ3MoInNlcmlhbCIpCiAgICBwcml2YXRlIGphdmEubGFuZy5PYmplY3Qgb187CiAgICBwdWJsaWMgZW51bSBPQ2FzZQogICAgICAgIGltcGxlbWVudHMgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnRlcm5hbC5FbnVtTGl0ZSwKICAgICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5BYnN0cmFjdE1lc3NhZ2UuSW50ZXJuYWxPbmVPZkVudW0gewogICAgICBJKDIpLAogICAgICBPX05PVF9TRVQoMCk7CiAgICAgIHByaXZhdGUgZmluYWwgaW50IHZhbHVlOwogICAgICBwcml2YXRlIE9DYXNlKGludCB2YWx1ZSkgewogICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgfQogICAgICAvKioKICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBudW1iZXIgb2YgdGhlIGVudW0gdG8gbG9vayBmb3IuCiAgICAgICAqIEByZXR1cm4gVGhlIGVudW0gYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBudW1iZXIuCiAgICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5EZXByZWNhdGVkCiAgICAgIHB1YmxpYyBzdGF0aWMgT0Nhc2UgdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgICByZXR1cm4gZm9yTnVtYmVyKHZhbHVlKTsKICAgICAgfQoKICAgICAgcHVibGljIHN0YXRpYyBPQ2FzZSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgY2FzZSAyOiByZXR1cm4gSTsKICAgICAgICAgIGNhc2UgMDogcmV0dXJuIE9fTk9UX1NFVDsKICAgICAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsOwogICAgICAgIH0KICAgICAgfQogICAgICBwdWJsaWMgaW50IGdldE51bWJlcigpIHsKICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgT0Nhc2UKICAgIGdldE9DYXNlKCkgewogICAgICByZXR1cm4gT0Nhc2UuZm9yTnVtYmVyKAogICAgICAgICAgb0Nhc2VfKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGZsb2F0IGZfID0gMEY7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGYgPSAxIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdGlvbikgPSB7IC4uLiB9PC9jb2RlPgogICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBmIGZpZWxkIGlzIHNldC4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gaGFzRigpIHsKICAgICAgcmV0dXJuICgoYml0RmllbGQwXyAmIDB4MDAwMDAwMDEpICE9IDApOwogICAgfQogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBmbG9hdCBmID0gMSBbKC5wcm90b2J1Zl91bml0dGVzdC5maWVsZF9vcHRpb24pID0geyAuLi4gfTwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGYuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBmbG9hdCBnZXRGKCkgewogICAgICByZXR1cm4gZl87CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgSV9GSUVMRF9OVU1CRVIgPSAyOwogICAgLyoqCiAgICAgKiA8Y29kZT5pbnQ2NCBpID0gMjs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGkgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBoYXNJKCkgewogICAgICByZXR1cm4gb0Nhc2VfID09IDI7CiAgICB9CiAgICAvKioKICAgICAqIDxjb2RlPmludDY0IGkgPSAyOzwvY29kZT4KICAgICAqIEByZXR1cm4gVGhlIGkuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBsb25nIGdldEkoKSB7CiAgICAgIGlmIChvQ2FzZV8gPT0gMikgewogICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIG9fOwogICAgICB9CiAgICAgIHJldHVybiAwTDsKICAgIH0KCiAgICBwcml2YXRlIGJ5dGUgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gLTE7CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgZmluYWwgYm9vbGVhbiBpc0luaXRpYWxpemVkKCkgewogICAgICBieXRlIGlzSW5pdGlhbGl6ZWQgPSBtZW1vaXplZElzSW5pdGlhbGl6ZWQ7CiAgICAgIGlmIChpc0luaXRpYWxpemVkID09IDEpIHJldHVybiB0cnVlOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAwKSByZXR1cm4gZmFsc2U7CgogICAgICBpZiAoIWV4dGVuc2lvbnNBcmVJbml0aWFsaXplZCgpKSB7CiAgICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMDsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgbWVtb2l6ZWRJc0luaXRpYWxpemVkID0gMTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHZvaWQgd3JpdGVUbyhjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkT3V0cHV0U3RyZWFtIG91dHB1dCkKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgIC5FeHRlbmRhYmxlTWVzc2FnZTxwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2U+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUZsb2F0KDEsIGZfKTsKICAgICAgfQogICAgICBpZiAob0Nhc2VfID09IDIpIHsKICAgICAgICBvdXRwdXQud3JpdGVJbnQ2NCgKICAgICAgICAgICAgMiwgKGxvbmcpKChqYXZhLmxhbmcuTG9uZykgb18pKTsKICAgICAgfQogICAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCgxMDEsIG91dHB1dCk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlRmxvYXRTaXplKDEsIGZfKTsKICAgICAgfQogICAgICBpZiAob0Nhc2VfID09IDIpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50NjRTaXplKAogICAgICAgICAgICAgIDIsIChsb25nKSgoamF2YS5sYW5nLkxvbmcpIG9fKSk7CiAgICAgIH0KICAgICAgc2l6ZSArPSBleHRlbnNpb25zU2VyaWFsaXplZFNpemUoKTsKICAgICAgc2l6ZSArPSBnZXRVbmtub3duRmllbGRzKCkuZ2V0U2VyaWFsaXplZFNpemUoKTsKICAgICAgbWVtb2l6ZWRTaXplID0gc2l6ZTsKICAgICAgcmV0dXJuIHNpemU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKGZpbmFsIGphdmEubGFuZy5PYmplY3Qgb2JqKSB7CiAgICAgIGlmIChvYmogPT0gdGhpcykgewogICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaWYgKCEob2JqIGluc3RhbmNlb2YgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlKSkgewogICAgICAgIHJldHVybiBzdXBlci5lcXVhbHMob2JqKTsKICAgICAgfQogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlKSBvYmo7CgogICAgICBpZiAoaGFzRigpICE9IG90aGVyLmhhc0YoKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoaGFzRigpKSB7CiAgICAgICAgaWYgKGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cyhnZXRGKCkpCiAgICAgICAgICAgICE9IGphdmEubGFuZy5GbG9hdC5mbG9hdFRvSW50Qml0cygKICAgICAgICAgICAgICAgIG90aGVyLmdldEYoKSkpIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICBpZiAoIWdldE9DYXNlKCkuZXF1YWxzKG90aGVyLmdldE9DYXNlKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIHN3aXRjaCAob0Nhc2VfKSB7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgaWYgKGdldEkoKQogICAgICAgICAgICAgICE9IG90aGVyLmdldEkoKSkgcmV0dXJuIGZhbHNlOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAwOgogICAgICAgIGRlZmF1bHQ6CiAgICAgIH0KICAgICAgaWYgKCFnZXRVbmtub3duRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldFVua25vd25GaWVsZHMoKSkpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKCFnZXRFeHRlbnNpb25GaWVsZHMoKS5lcXVhbHMob3RoZXIuZ2V0RXh0ZW5zaW9uRmllbGRzKCkpKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBoYXNoQ29kZSgpIHsKICAgICAgaWYgKG1lbW9pemVkSGFzaENvZGUgIT0gMCkgewogICAgICAgIHJldHVybiBtZW1vaXplZEhhc2hDb2RlOwogICAgICB9CiAgICAgIGludCBoYXNoID0gNDE7CiAgICAgIGhhc2ggPSAoMTkgKiBoYXNoKSArIGdldERlc2NyaXB0b3IoKS5oYXNoQ29kZSgpOwogICAgICBpZiAoaGFzRigpKSB7CiAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgRl9GSUVMRF9OVU1CRVI7CiAgICAgICAgaGFzaCA9ICg1MyAqIGhhc2gpICsgamF2YS5sYW5nLkZsb2F0LmZsb2F0VG9JbnRCaXRzKAogICAgICAgICAgICBnZXRGKCkpOwogICAgICB9CiAgICAgIHN3aXRjaCAob0Nhc2VfKSB7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgaGFzaCA9ICgzNyAqIGhhc2gpICsgSV9GSUVMRF9OVU1CRVI7CiAgICAgICAgICBoYXNoID0gKDUzICogaGFzaCkgKyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLmhhc2hMb25nKAogICAgICAgICAgICAgIGdldEkoKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDA6CiAgICAgICAgZGVmYXVsdDoKICAgICAgfQogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEubmlvLkJ5dGVCdWZmZXIgZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLm5pby5CeXRlQnVmZmVyIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlIHBhcnNlRnJvbShieXRlW10gZGF0YSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSBwYXJzZUZyb20oamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSBwYXJzZURlbGltaXRlZEZyb20oCiAgICAgICAgamF2YS5pby5JbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMwogICAgICAgICAgLnBhcnNlRGVsaW1pdGVkV2l0aElPRXhjZXB0aW9uKFBBUlNFUiwgaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSBwcm90b3R5cGUpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0UudG9CdWlsZGVyKCkubWVyZ2VGcm9tKHByb3RvdHlwZSk7CiAgICB9CiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciB0b0J1aWxkZXIoKSB7CiAgICAgIHJldHVybiB0aGlzID09IERFRkFVTFRfSU5TVEFOQ0UKICAgICAgICAgID8gbmV3IEJ1aWxkZXIoKSA6IG5ldyBCdWlsZGVyKCkubWVyZ2VGcm9tKHRoaXMpOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHByb3RlY3RlZCBCdWlsZGVyIG5ld0J1aWxkZXJGb3JUeXBlKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkJ1aWxkZXJQYXJlbnQgcGFyZW50KSB7CiAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKHBhcmVudCk7CiAgICAgIHJldHVybiBidWlsZGVyOwogICAgfQogICAgLyoqCiAgICAgKiBQcm90b2J1ZiB0eXBlIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5Ub3BMZXZlbE1lc3NhZ2V9CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgQnVpbGRlciBleHRlbmRzCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRXh0ZW5kYWJsZUJ1aWxkZXI8CiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UsIEJ1aWxkZXI+IGltcGxlbWVudHMKICAgICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0LlRvcExldmVsTWVzc2FnZSkKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2VPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1RvcExldmVsTWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVG9wTGV2ZWxNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZS5jbGFzcywgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgICB9CgogICAgICAvLyBDb25zdHJ1Y3QgdXNpbmcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBmXyA9IDBGOwogICAgICAgIG9DYXNlXyA9IDA7CiAgICAgICAgb18gPSBudWxsOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgICAgICAgIGdldERlc2NyaXB0b3JGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVG9wTGV2ZWxNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSBidWlsZCgpIHsKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UgcmVzdWx0ID0gYnVpbGRQYXJ0aWFsKCk7CiAgICAgICAgaWYgKCFyZXN1bHQuaXNJbml0aWFsaXplZCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXdVbmluaXRpYWxpemVkTWVzc2FnZUV4Y2VwdGlvbihyZXN1bHQpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSByZXN1bHQgPSBuZXcgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlKHRoaXMpOwogICAgICAgIGlmIChiaXRGaWVsZDBfICE9IDApIHsgYnVpbGRQYXJ0aWFsMChyZXN1bHQpOyB9CiAgICAgICAgYnVpbGRQYXJ0aWFsT25lb2ZzKHJlc3VsdCk7CiAgICAgICAgb25CdWlsdCgpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgdm9pZCBidWlsZFBhcnRpYWwwKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5mXyA9IGZfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsT25lb2ZzKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSByZXN1bHQpIHsKICAgICAgICByZXN1bHQub0Nhc2VfID0gb0Nhc2VfOwogICAgICAgIHJlc3VsdC5vXyA9IHRoaXMub187CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xvbmUoKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsb25lKCk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBzZXRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRGaWVsZChmaWVsZCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyRmllbGQoZmllbGQpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXJPbmVvZigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuT25lb2ZEZXNjcmlwdG9yIG9uZW9mKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmNsZWFyT25lb2Yob25lb2YpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0UmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgaW50IGluZGV4LCBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFJlcGVhdGVkRmllbGQoZmllbGQsIGluZGV4LCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBhZGRSZXBlYXRlZEZpZWxkKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWVsZERlc2NyaXB0b3IgZmllbGQsCiAgICAgICAgICBqYXZhLmxhbmcuT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZFJlcGVhdGVkRmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBzZXRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSwgVHlwZT4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBpbnQgaW5kZXgsIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RXh0ZW5zaW9uKGV4dGVuc2lvbiwgaW5kZXgsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VHlwZT4gQnVpbGRlciBhZGRFeHRlbnNpb24oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIFR5cGUgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuYWRkRXh0ZW5zaW9uKGV4dGVuc2lvbiwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUPiBCdWlsZGVyIGNsZWFyRXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UsIFQ+IGV4dGVuc2lvbikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckV4dGVuc2lvbihleHRlbnNpb24pOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSkgewogICAgICAgICAgcmV0dXJuIG1lcmdlRnJvbSgocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlKW90aGVyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3VwZXIubWVyZ2VGcm9tKG90aGVyKTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KICAgICAgfQoKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpIHJldHVybiB0aGlzOwogICAgICAgIGlmIChvdGhlci5oYXNGKCkpIHsKICAgICAgICAgIHNldEYob3RoZXIuZ2V0RigpKTsKICAgICAgICB9CiAgICAgICAgc3dpdGNoIChvdGhlci5nZXRPQ2FzZSgpKSB7CiAgICAgICAgICBjYXNlIEk6IHsKICAgICAgICAgICAgc2V0SShvdGhlci5nZXRJKCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNhc2UgT19OT1RfU0VUOiB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlRXh0ZW5zaW9uRmllbGRzKG90aGVyKTsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgMTM6IHsKICAgICAgICAgICAgICAgIGZfID0gaW5wdXQucmVhZEZsb2F0KCk7CiAgICAgICAgICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGNhc2UgMTMKICAgICAgICAgICAgICBjYXNlIDE2OiB7CiAgICAgICAgICAgICAgICBvXyA9IGlucHV0LnJlYWRJbnQ2NCgpOwogICAgICAgICAgICAgICAgb0Nhc2VfID0gMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSAxNgogICAgICAgICAgICAgIGRlZmF1bHQ6IHsKICAgICAgICAgICAgICAgIGlmICghc3VwZXIucGFyc2VVbmtub3duRmllbGQoaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5LCB0YWcpKSB7CiAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOyAvLyB3YXMgYW4gZW5kZ3JvdXAgdGFnCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9IC8vIGRlZmF1bHQ6CiAgICAgICAgICAgIH0gLy8gc3dpdGNoICh0YWcpCiAgICAgICAgICB9IC8vIHdoaWxlICghZG9uZSkKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnVud3JhcElPRXhjZXB0aW9uKCk7CiAgICAgICAgfSBmaW5hbGx5IHsKICAgICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIH0gLy8gZmluYWxseQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIHByaXZhdGUgaW50IG9DYXNlXyA9IDA7CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLk9iamVjdCBvXzsKICAgICAgcHVibGljIE9DYXNlCiAgICAgICAgICBnZXRPQ2FzZSgpIHsKICAgICAgICByZXR1cm4gT0Nhc2UuZm9yTnVtYmVyKAogICAgICAgICAgICBvQ2FzZV8pOwogICAgICB9CgogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhck8oKSB7CiAgICAgICAgb0Nhc2VfID0gMDsKICAgICAgICBvXyA9IG51bGw7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CgogICAgICBwcml2YXRlIGZsb2F0IGZfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGYgPSAxIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdGlvbikgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGYgZmllbGQgaXMgc2V0LgogICAgICAgKi8KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNGKCkgewogICAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZiA9IDEgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0aW9uKSA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEByZXR1cm4gVGhlIGYuCiAgICAgICAqLwogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmbG9hdCBnZXRGKCkgewogICAgICAgIHJldHVybiBmXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgZmxvYXQgZiA9IDEgWygucHJvdG9idWZfdW5pdHRlc3QuZmllbGRfb3B0aW9uKSA9IHsgLi4uIH08L2NvZGU+CiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgZiB0byBzZXQuCiAgICAgICAqIEByZXR1cm4gVGhpcyBidWlsZGVyIGZvciBjaGFpbmluZy4KICAgICAgICovCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldEYoZmxvYXQgdmFsdWUpIHsKCiAgICAgICAgZl8gPSB2YWx1ZTsKICAgICAgICBiaXRGaWVsZDBfIHw9IDB4MDAwMDAwMDE7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGZsb2F0IGYgPSAxIFsoLnByb3RvYnVmX3VuaXR0ZXN0LmZpZWxkX29wdGlvbikgPSB7IC4uLiB9PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckYoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGZfID0gMEY7CiAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiA8Y29kZT5pbnQ2NCBpID0gMjs8L2NvZGU+CiAgICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgaSBmaWVsZCBpcyBzZXQuCiAgICAgICAqLwogICAgICBwdWJsaWMgYm9vbGVhbiBoYXNJKCkgewogICAgICAgIHJldHVybiBvQ2FzZV8gPT0gMjsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50NjQgaSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoZSBpLgogICAgICAgKi8KICAgICAgcHVibGljIGxvbmcgZ2V0SSgpIHsKICAgICAgICBpZiAob0Nhc2VfID09IDIpIHsKICAgICAgICAgIHJldHVybiAoamF2YS5sYW5nLkxvbmcpIG9fOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMEw7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPmludDY0IGkgPSAyOzwvY29kZT4KICAgICAgICogQHBhcmFtIHZhbHVlIFRoZSBpIHRvIHNldC4KICAgICAgICogQHJldHVybiBUaGlzIGJ1aWxkZXIgZm9yIGNoYWluaW5nLgogICAgICAgKi8KICAgICAgcHVibGljIEJ1aWxkZXIgc2V0SShsb25nIHZhbHVlKSB7CgogICAgICAgIG9DYXNlXyA9IDI7CiAgICAgICAgb18gPSB2YWx1ZTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+aW50NjQgaSA9IDI7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckkoKSB7CiAgICAgICAgaWYgKG9DYXNlXyA9PSAyKSB7CiAgICAgICAgICBvQ2FzZV8gPSAwOwogICAgICAgICAgb18gPSBudWxsOwogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgc2V0VW5rbm93bkZpZWxkcygKICAgICAgICAgIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuVW5rbm93bkZpZWxkU2V0IHVua25vd25GaWVsZHMpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0VW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgZmluYWwgQnVpbGRlciBtZXJnZVVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLm1lcmdlVW5rbm93bkZpZWxkcyh1bmtub3duRmllbGRzKTsKICAgICAgfQoKCiAgICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChidWlsZGVyX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0LlRvcExldmVsTWVzc2FnZSkKICAgIH0KCiAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoY2xhc3Nfc2NvcGU6cHJvdG9idWZfdW5pdHRlc3QuVG9wTGV2ZWxNZXNzYWdlKQogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uVG9wTGV2ZWxNZXNzYWdlIGdldERlZmF1bHRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogICAgQGphdmEubGFuZy5EZXByZWNhdGVkIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5QYXJzZXI8VG9wTGV2ZWxNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRvcExldmVsTWVzc2FnZT4oKSB7CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIFRvcExldmVsTWVzc2FnZSBwYXJzZVBhcnRpYWxGcm9tKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0LAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICAgIEJ1aWxkZXIgYnVpbGRlciA9IG5ld0J1aWxkZXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgYnVpbGRlci5tZXJnZUZyb20oaW5wdXQsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiBlKSB7CiAgICAgICAgICB0aHJvdyBlLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuVW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5hc0ludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbigpLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0gY2F0Y2ggKGphdmEuaW8uSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgbmV3IGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uKGUpCiAgICAgICAgICAgICAgLnNldFVuZmluaXNoZWRNZXNzYWdlKGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYnVpbGRlci5idWlsZFBhcnRpYWwoKTsKICAgICAgfQogICAgfTsKCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRvcExldmVsTWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUb3BMZXZlbE1lc3NhZ2U+IGdldFBhcnNlckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBQQVJTRVI7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLlRvcExldmVsTWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2VGb3JUeXBlKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBTX0ZJRUxEX05VTUJFUiA9IDI7CiAgICAvKioKICAgICAqIDxjb2RlPmV4dGVuZCAucHJvdG9idWZfdW5pdHRlc3QuRXh0ZW5kZWUgeyAuLi4gfTwvY29kZT4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlLAogICAgICAgIGphdmEubGFuZy5TdHJpbmc+IHMgPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgICAgLm5ld01lc3NhZ2VTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5Ub3BMZXZlbE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCksCiAgICAgICAgICAwLAogICAgICAgICAgamF2YS5sYW5nLlN0cmluZy5jbGFzcywKICAgICAgICAgIG51bGwpOwogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUExBSU5fT1BUSU9OX0ZJRUxEX05VTUJFUiA9IDUwNTA5MjgwNjsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5GaWxlT3B0aW9ucywKICAgICAgamF2YS5sYW5nLkludGVnZXI+IHBsYWluT3B0aW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBSVU5USU1FX1JFVEVOVElPTl9PUFRJT05fRklFTERfTlVNQkVSID0gNTA1MDM5MTMyOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gcnVudGltZVJldGVudGlvbk9wdGlvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgU09VUkNFX1JFVEVOVElPTl9PUFRJT05fRklFTERfTlVNQkVSID0gNTA0ODc4Njc2OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpbGVPcHRpb25zLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gc291cmNlUmV0ZW50aW9uT3B0aW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBqYXZhLmxhbmcuSW50ZWdlci5jbGFzcywKICAgICAgICBudWxsKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGSUxFX09QVElPTl9GSUVMRF9OVU1CRVIgPSA1MDQ4NzExNjg7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmlsZU9wdGlvbnMsCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlPiBmaWxlT3B0aW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZS5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgUkVQRUFURURfT1BUSU9OU19GSUVMRF9OVU1CRVIgPSA1MDQ4MjM1NzA7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRmlsZU9wdGlvbnMsCiAgICAgIGphdmEudXRpbC5MaXN0PHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlPj4gcmVwZWF0ZWRPcHRpb25zID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZS5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRVhURU5TSU9OX1JBTkdFX09QVElPTl9GSUVMRF9OVU1CRVIgPSA1MDQ4MjIxNDg7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmFuZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkV4dGVuc2lvblJhbmdlT3B0aW9ucywKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2U+IGV4dGVuc2lvblJhbmdlT3B0aW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZS5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTUVTU0FHRV9PUFRJT05fRklFTERfTlVNQkVSID0gNTA0ODIwODE5OwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1lc3NhZ2VPcHRpb25zLAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZT4gbWVzc2FnZU9wdGlvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UuY2xhc3MsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZJRUxEX09QVElPTl9GSUVMRF9OVU1CRVIgPSA1MDQ1ODkyMTk7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLkZpZWxkT3B0aW9ucywKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2U+IGZpZWxkT3B0aW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZS5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgT05FT0ZfT1BUSU9OX0ZJRUxEX05VTUJFUiA9IDUwNDQ3OTE1MzsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5PbmVvZk9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuT25lb2ZPcHRpb25zLAogICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZT4gb25lb2ZPcHRpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlLmNsYXNzLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBFTlVNX09QVElPTl9GSUVMRF9OVU1CRVIgPSA1MDQ0NTE1Njc7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRW51bU9wdGlvbnMsCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlPiBlbnVtT3B0aW9uID0gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlCiAgICAgICAgICAubmV3RmlsZVNjb3BlZEdlbmVyYXRlZEV4dGVuc2lvbigKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZS5jbGFzcywKICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5PcHRpb25zTWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSk7CiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRU5VTV9FTlRSWV9PUFRJT05fRklFTERfTlVNQkVSID0gNTA0NDUwNTIyOwogIC8qKgogICAqIDxjb2RlPmV4dGVuZCAuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMgeyAuLi4gfTwvY29kZT4KICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UuR2VuZXJhdGVkRXh0ZW5zaW9uPAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuRW51bVZhbHVlT3B0aW9ucywKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2U+IGVudW1FbnRyeU9wdGlvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UuY2xhc3MsCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCkpOwogIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNFUlZJQ0VfT1BUSU9OX0ZJRUxEX05VTUJFUiA9IDUwNDM4NzcwOTsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3Rvcy5TZXJ2aWNlT3B0aW9ucywKICAgICAgcHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uT3B0aW9uc01lc3NhZ2U+IHNlcnZpY2VPcHRpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlLmNsYXNzLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBNRVRIT0RfT1BUSU9OX0ZJRUxEX05VTUJFUiA9IDUwNDM0OTQyMDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zIHsgLi4uIH08L2NvZGU+CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLk1ldGhvZE9wdGlvbnMsCiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlPiBtZXRob2RPcHRpb24gPSBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2UKICAgICAgICAgIC5uZXdGaWxlU2NvcGVkR2VuZXJhdGVkRXh0ZW5zaW9uKAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlLmNsYXNzLAogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLk9wdGlvbnNNZXNzYWdlLmdldERlZmF1bHRJbnN0YW5jZSgpKTsKICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBJX0ZJRUxEX05VTUJFUiA9IDE7CiAgLyoqCiAgICogPGNvZGU+ZXh0ZW5kIC5wcm90b2J1Zl91bml0dGVzdC5FeHRlbmRlZSB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLkV4dGVuZGVlLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gaSA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT3B0aW9uc01lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfT3B0aW9uc01lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0V4dGVuZGVlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X0V4dGVuZGVlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Ub3BMZXZlbE1lc3NhZ2VfZGVzY3JpcHRvcjsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCAKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZQogICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVG9wTGV2ZWxNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZTsKICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkRlc2NyaXB0b3IKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Ub3BMZXZlbE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yOwogIHByaXZhdGUgc3RhdGljIGZpbmFsIAogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Ub3BMZXZlbE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuKGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9yZXRlbnRpb24ucHJvIiArCiAgICAgICJ0b1wwMjJcMDIxcHJvdG9idWZfdW5pdHRlc3RcMDMyIGdvb2dsZS9wcm90b2J1Zi9kIiArCiAgICAgICJlc2NyaXB0b3IucHJvdG9cInBcblwwMTZPcHRpb25zTWVzc2FnZVwwMjJcMDIzXG5cMDEzcGxhIiArCiAgICAgICJpbl9maWVsZFwwMzBcMDAxIFwwMDEoXDAwNVwwMjIkXG5cMDI3cnVudGltZV9yZXRlbnRpb25fZmllbCIgKwogICAgICAiZFwwMzBcMDAyIFwwMDEoXDAwNUJcMDAzXDIxMFwwMDFcMDAxXDAyMiNcblwwMjZzb3VyY2VfcmV0ZW50aW9uX2ZpZWxkXDAzMFwwMDMiICsKICAgICAgIiBcMDAxKFwwMDVCXDAwM1wyMTBcMDAxXDAwMlwiXDAyNlxuXDAxMEV4dGVuZGVlKlwwMDRcMDEwXDAwMVwwMjBcMDAyKlwwMDRcMDEwXDAwMlwwMjBcMDAzXCJcMzQzXDAwMVxuXDAxN1RvIiArCiAgICAgICJwTGV2ZWxNZXNzYWdlXDAyMlwwMjVcblwwMDFmXDAzMFwwMDEgXDAwMShcMDAyQlxuXDIzMlwyNzJcMzU1XDIwNFwwMTdcMDA0XDAxMFwwMDFcMDIwXDAwMlwwMjJcMDEzXG5cMDAxIiArCiAgICAgICJpXDAzMFwwMDIgXDAwMShcMDAzSFwwMDBcMDMyXDAzM1xuXHJOZXN0ZWRNZXNzYWdlOlxuXDIzMlwzMDVcMzM2XDIwNVwwMTdcMDA0XDAxMFwwMDFcMDIwXDAwMlwiLCIgKwogICAgICAiXG5cbk5lc3RlZEVudW1cMDIyXDAyMlxuXDAxNk5FU1RFRF9VTktOT1dOXDAyMFwwMDBcMDMyXG5cMzcyXDIzNlwyNTJcMjA0XDAxN1wwMDQiICsKICAgICAgIlwwMTBcMDAxXDAyMFwwMDIqXDAyMFwwMTBcblwwMjBlXDAzMlxuXDI0MlwyMzBcMzM3XDIwNVwwMTdcMDA0XDAxMFwwMDFcMDIwXDAwMjIyXG5cMDAxc1wwMjJcMDMzLnByb3RvYnVmX3UiICsKICAgICAgIm5pdHRlc3QuRXh0ZW5kZWVcMDMwXDAwMiBcMDAxKFx0QlxuXDIzMlwyNzJcMzU1XDIwNFwwMTdcMDA0XDAxMFwwMDFcMDIwXDAwMjpcblwyMzJcMzA1XDMzNlwyMDUiICsKICAgICAgIlwwMTdcMDA0XDAxMFwwMDFcMDIwXDAwMkJcMDE3XG5cMDAxb1wwMjJcblwyMTJcMzMzXDI2N1wyMDRcMDE3XDAwNFwwMTBcMDAxXDAyMFwwMDIqPVxuXDAxNFRvcExldmVsRW51bVwwMjIiICsKICAgICAgIiFcblwwMjFUT1BfTEVWRUxfVU5LTk9XTlwwMjBcMDAwXDAzMlxuXDMyMlwzMzVcMjUxXDIwNFwwMTdcMDA0XDAxMFwwMDFcMDIwXDAwMlwwMzJcblwzNzJcMjM2XDI1MlwyMDQiICsKICAgICAgIlwwMTdcMDA0XDAxMFwwMDFcMDIwXDAwMjJ0XG5cMDA3U2VydmljZVwwMjJdXG5cMDA3RG9TdHVmZlwwMjJcIi5wcm90b2J1Zl8iICsKICAgICAgInVuaXR0ZXN0LlRvcExldmVsTWVzc2FnZVwwMzJcIi5wcm90b2J1Zl91bml0IiArCiAgICAgICJ0ZXN0LlRvcExldmVsTWVzc2FnZVwiXG5cMzQyXDI1NlwzNzBcMjAzXDAxN1wwMDRcMDEwXDAwMVwwMjBcMDAyXDAzMlxuXDM1MlwyMDdcMjEzXDIwNFwwMTdcMDA0IiArCiAgICAgICJcMDEwXDAwMVwwMjBcMDAyOjZcblwwMTRwbGFpbl9vcHRpb25cMDIyXDAzNC5nb29nbGUucHJvdG9idWYuRiIgKwogICAgICAiaWxlT3B0aW9uc1wwMzBcMzA2XDI2NVwzNTRcMzYwXDAwMSBcMDAxKFwwMDU6R1xuXDAzMHJ1bnRpbWVfcmV0ZW50aW8iICsKICAgICAgIm5fb3B0aW9uXDAyMlwwMzQuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zXDAzMFwyMzQiICsKICAgICAgIlwyMjJcMzUxXDM2MFwwMDEgXDAwMShcMDA1QlwwMDNcMjEwXDAwMVwwMDE6RlxuXDAyN3NvdXJjZV9yZXRlbnRpb25fb3B0aW9uIiArCiAgICAgICJcMDIyXDAzNC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcMDMwXDMyNFwyNTRcMzM3XDM2MFwwMDEgXDAwMShcMDA1IiArCiAgICAgICJCXDAwM1wyMTBcMDAxXDAwMjpYXG5cMDEzZmlsZV9vcHRpb25cMDIyXDAzNC5nb29nbGUucHJvdG9idWYuRiIgKwogICAgICAiaWxlT3B0aW9uc1wwMzBcMjAwXDM2MlwzMzZcMzYwXDAwMSBcMDAxKFwwMTMyIS5wcm90b2J1Zl91bml0dGVzdCIgKwogICAgICAiLk9wdGlvbnNNZXNzYWdlOl1cblwwMjByZXBlYXRlZF9vcHRpb25zXDAyMlwwMzQuZ28iICsKICAgICAgIm9nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNcMDMwXDIyMlwzNzZcMzMzXDM2MFwwMDEgXDAwMyhcMDEzMiEucHIiICsKICAgICAgIm90b2J1Zl91bml0dGVzdC5PcHRpb25zTWVzc2FnZTptXG5cMDI2ZXh0ZW5zIiArCiAgICAgICJpb25fcmFuZ2Vfb3B0aW9uXDAyMiYuZ29vZ2xlLnByb3RvYnVmLkV4dGVuIiArCiAgICAgICJzaW9uUmFuZ2VPcHRpb25zXDAzMFwyMDRcMzYzXDMzM1wzNjBcMDAxIFwwMDEoXDAxMzIhLnByb3RvYnVmX3VuIiArCiAgICAgICJpdHRlc3QuT3B0aW9uc01lc3NhZ2U6XlxuXDAxNm1lc3NhZ2Vfb3B0aW9uXDAyMiIgKwogICAgICAiXDAzNy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnNcMDMwXDMyM1wzNTBcMzMzXDM2MFwwMDEgXDAwMSIgKwogICAgICAiKFwwMTMyIS5wcm90b2J1Zl91bml0dGVzdC5PcHRpb25zTWVzc2FnZTpaXG4iICsKICAgICAgIlwwMTRmaWVsZF9vcHRpb25cMDIyXDAzNS5nb29nbGUucHJvdG9idWYuRmllbGRPcHQiICsKICAgICAgImlvbnNcMDMwXDI0M1wzMjdcMzE1XDM2MFwwMDEgXDAwMShcMDEzMiEucHJvdG9idWZfdW5pdHRlc3QuT3B0aW8iICsKICAgICAgIm5zTWVzc2FnZTpaXG5cMDE0b25lb2Zfb3B0aW9uXDAyMlwwMzUuZ29vZ2xlLnByb3RvIiArCiAgICAgICJidWYuT25lb2ZPcHRpb25zXDAzMFwyNjFcMzczXDMwNlwzNjBcMDAxIFwwMDEoXDAxMzIhLnByb3RvYnVmX3VuIiArCiAgICAgICJpdHRlc3QuT3B0aW9uc01lc3NhZ2U6WFxuXDAxM2VudW1fb3B0aW9uXDAyMlwwMzQuZyIgKwogICAgICAib29nbGUucHJvdG9idWYuRW51bU9wdGlvbnNcMDMwXDM1N1wyNDNcMzA1XDM2MFwwMDEgXDAwMShcMDEzMiEucCIgKwogICAgICAicm90b2J1Zl91bml0dGVzdC5PcHRpb25zTWVzc2FnZTpjXG5cMDIxZW51bV8iICsKICAgICAgImVudHJ5X29wdGlvblwwMjIhLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUiICsKICAgICAgIk9wdGlvbnNcMDMwXDMzMlwyMzNcMzA1XDM2MFwwMDEgXDAwMShcMDEzMiEucHJvdG9idWZfdW5pdHRlc3QuT3AiICsKICAgICAgInRpb25zTWVzc2FnZTpeXG5cMDE2c2VydmljZV9vcHRpb25cMDIyXDAzNy5nb29nbGUuIiArCiAgICAgICJwcm90b2J1Zi5TZXJ2aWNlT3B0aW9uc1wwMzBcMzc1XDI2MFwzMDFcMzYwXDAwMSBcMDAxKFwwMTMyIS5wcm90IiArCiAgICAgICJvYnVmX3VuaXR0ZXN0Lk9wdGlvbnNNZXNzYWdlOlxcXG5ccm1ldGhvZF9vIiArCiAgICAgICJwdGlvblwwMjJcMDM2Lmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zXDAzMFwzNTRcMjA1IiArCiAgICAgICJcMjc3XDM2MFwwMDEgXDAwMShcMDEzMiEucHJvdG9idWZfdW5pdHRlc3QuT3B0aW9uc01lc3NhIiArCiAgICAgICJnZToyXG5cMDAxaVwwMjJcMDMzLnByb3RvYnVmX3VuaXR0ZXN0LkV4dGVuZGVlXDAzMFwwMDEgXDAwMSIgKwogICAgICAiKFwwMDVCXG5cMjMyXDI3MlwzNTVcMjA0XDAxN1wwMDRcMDEwXDAwMVwwMjBcMDAyQjNcMjUyXDAwMlwwMjBQcm90b2J1ZlVuaXR0ZXN0XDIyMlwzNjFcMzM3XDIwNVwwMTciICsKICAgICAgIlwwMDRcMDEwXDAwMVwwMjBcMDAyXDIwMlwyMjBcMzY3XDIwNVwwMTdcMDA0XDAxMFwwMDFcMDIwXDAwMlwzNDBcMjIxXDMxMVwyMDZcMDE3XDAwMlwyNjBcMjU0XDM0M1wyMDZcMDE3XDAwMSIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9zLmdldERlc2NyaXB0b3IoKSwKICAgICAgICB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PcHRpb25zTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PcHRpb25zTWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9PcHRpb25zTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiUGxhaW5GaWVsZCIsICJSdW50aW1lUmV0ZW50aW9uRmllbGQiLCAiU291cmNlUmV0ZW50aW9uRmllbGQiLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FeHRlbmRlZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgxKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FeHRlbmRlZV9maWVsZEFjY2Vzc29yVGFibGUgPSBuZXcKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlKAogICAgICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9FeHRlbmRlZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Ub3BMZXZlbE1lc3NhZ2VfZGVzY3JpcHRvciA9CiAgICAgIGdldERlc2NyaXB0b3IoKS5nZXRNZXNzYWdlVHlwZXMoKS5nZXQoMik7CiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3RfVG9wTGV2ZWxNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1RvcExldmVsTWVzc2FnZV9kZXNjcmlwdG9yLAogICAgICAgIG5ldyBqYXZhLmxhbmcuU3RyaW5nW10geyAiRiIsICJJIiwgIk8iLCB9KTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9Ub3BMZXZlbE1lc3NhZ2VfTmVzdGVkTWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1RvcExldmVsTWVzc2FnZV9kZXNjcmlwdG9yLmdldE5lc3RlZFR5cGVzKCkuZ2V0KDApOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1RvcExldmVsTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZSA9IG5ldwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUoCiAgICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X1RvcExldmVsTWVzc2FnZV9OZXN0ZWRNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7IH0pOwogICAgcGxhaW5PcHRpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgwKSk7CiAgICBydW50aW1lUmV0ZW50aW9uT3B0aW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMSkpOwogICAgc291cmNlUmV0ZW50aW9uT3B0aW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMikpOwogICAgZmlsZU9wdGlvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDMpKTsKICAgIHJlcGVhdGVkT3B0aW9ucy5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDQpKTsKICAgIGV4dGVuc2lvblJhbmdlT3B0aW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNSkpOwogICAgbWVzc2FnZU9wdGlvbi5pbnRlcm5hbEluaXQoZGVzY3JpcHRvci5nZXRFeHRlbnNpb25zKCkuZ2V0KDYpKTsKICAgIGZpZWxkT3B0aW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoNykpOwogICAgb25lb2ZPcHRpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCg4KSk7CiAgICBlbnVtT3B0aW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoOSkpOwogICAgZW51bUVudHJ5T3B0aW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTApKTsKICAgIHNlcnZpY2VPcHRpb24uaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxMSkpOwogICAgbWV0aG9kT3B0aW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMTIpKTsKICAgIGkuaW50ZXJuYWxJbml0KGRlc2NyaXB0b3IuZ2V0RXh0ZW5zaW9ucygpLmdldCgxMykpOwogICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSA9CiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeS5uZXdJbnN0YW5jZSgpOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLmVudW1FbnRyeU9wdGlvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uZW51bU9wdGlvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24uZXh0ZW5zaW9uUmFuZ2VPcHRpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLmZpZWxkT3B0aW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5maWxlT3B0aW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5tZXNzYWdlT3B0aW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5tZXRob2RPcHRpb24pOwogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0LlVuaXR0ZXN0UmV0ZW50aW9uLm9uZW9mT3B0aW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5wbGFpbk9wdGlvbik7CiAgICByZWdpc3RyeS5hZGQocHJvdG9idWZfdW5pdHRlc3QuVW5pdHRlc3RSZXRlbnRpb24ucmVwZWF0ZWRPcHRpb25zKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5ydW50aW1lUmV0ZW50aW9uT3B0aW9uKTsKICAgIHJlZ2lzdHJ5LmFkZChwcm90b2J1Zl91bml0dGVzdC5Vbml0dGVzdFJldGVudGlvbi5zZXJ2aWNlT3B0aW9uKTsKICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmlsZURlc2NyaXB0b3IKICAgICAgICAuaW50ZXJuYWxVcGRhdGVGaWxlRGVzY3JpcHRvcihkZXNjcmlwdG9yLCByZWdpc3RyeSk7CiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90b3MuZ2V0RGVzY3JpcHRvcigpOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAwQKAAAAAAAAACEAmZebaV1rAABdawAASQAAAHByb3RvYnVmX3VuaXR0ZXN0L25vX2dlbmVyaWNfc2VydmljZXNfdGVzdC9Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLmphdmEvLyBHZW5lcmF0ZWQgYnkgdGhlIHByb3RvY29sIGJ1ZmZlciBjb21waWxlci4gIERPIE5PVCBFRElUIQovLyBzb3VyY2U6IGdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzLnByb3RvCgovLyBQcm90b2J1ZiBKYXZhIFZlcnNpb246IDMuMjUuNC1kZXYKcGFja2FnZSBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3Q7CgpwdWJsaWMgZmluYWwgY2xhc3MgVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcyB7CiAgcHJpdmF0ZSBVbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzKCkge30KICBwdWJsaWMgc3RhdGljIHZvaWQgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSByZWdpc3RyeSkgewogICAgcmVnaXN0cnkuYWRkKHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLnRlc3RFeHRlbnNpb24pOwogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHJlZ2lzdGVyQWxsRXh0ZW5zaW9ucygKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeSByZWdpc3RyeSkgewogICAgcmVnaXN0ZXJBbGxFeHRlbnNpb25zKAogICAgICAgIChjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSkgcmVnaXN0cnkpOwogIH0KICAvKioKICAgKiBQcm90b2J1ZiBlbnVtIHtAY29kZSBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVGVzdEVudW19CiAgICovCiAgcHVibGljIGVudW0gVGVzdEVudW0KICAgICAgaW1wbGVtZW50cyBjb20uZ29vZ2xlLnByb3RvYnVmLlByb3RvY29sTWVzc2FnZUVudW0gewogICAgLyoqCiAgICAgKiA8Y29kZT5GT08gPSAxOzwvY29kZT4KICAgICAqLwogICAgRk9PKDEpLAogICAgOwoKICAgIC8qKgogICAgICogPGNvZGU+Rk9PID0gMTs8L2NvZGU+CiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgaW50IEZPT19WQUxVRSA9IDE7CgoKICAgIHB1YmxpYyBmaW5hbCBpbnQgZ2V0TnVtYmVyKCkgewogICAgICByZXR1cm4gdmFsdWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgI2Zvck51bWJlcihpbnQpfSBpbnN0ZWFkLgogICAgICovCiAgICBAamF2YS5sYW5nLkRlcHJlY2F0ZWQKICAgIHB1YmxpYyBzdGF0aWMgVGVzdEVudW0gdmFsdWVPZihpbnQgdmFsdWUpIHsKICAgICAgcmV0dXJuIGZvck51bWJlcih2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWVyaWMgd2lyZSB2YWx1ZSBvZiB0aGUgY29ycmVzcG9uZGluZyBlbnVtIGVudHJ5LgogICAgICogQHJldHVybiBUaGUgZW51bSBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIG51bWVyaWMgd2lyZSB2YWx1ZS4KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBUZXN0RW51bSBmb3JOdW1iZXIoaW50IHZhbHVlKSB7CiAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICBjYXNlIDE6IHJldHVybiBGT087CiAgICAgICAgZGVmYXVsdDogcmV0dXJuIG51bGw7CiAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGNvbS5nb29nbGUucHJvdG9idWYuSW50ZXJuYWwuRW51bUxpdGVNYXA8VGVzdEVudW0+CiAgICAgICAgaW50ZXJuYWxHZXRWYWx1ZU1hcCgpIHsKICAgICAgcmV0dXJuIGludGVybmFsVmFsdWVNYXA7CiAgICB9CiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPAogICAgICAgIFRlc3RFbnVtPiBpbnRlcm5hbFZhbHVlTWFwID0KICAgICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludGVybmFsLkVudW1MaXRlTWFwPFRlc3RFbnVtPigpIHsKICAgICAgICAgICAgcHVibGljIFRlc3RFbnVtIGZpbmRWYWx1ZUJ5TnVtYmVyKGludCBudW1iZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gVGVzdEVudW0uZm9yTnVtYmVyKG51bWJlcik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgcHVibGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bVZhbHVlRGVzY3JpcHRvcgogICAgICAgIGdldFZhbHVlRGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIGdldERlc2NyaXB0b3IoKS5nZXRWYWx1ZXMoKS5nZXQob3JkaW5hbCgpKTsKICAgIH0KICAgIHB1YmxpYyBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgIHJldHVybiBnZXREZXNjcmlwdG9yKCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRW51bURlc2NyaXB0b3IKICAgICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuZ2V0RGVzY3JpcHRvcigpLmdldEVudW1UeXBlcygpLmdldCgwKTsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBUZXN0RW51bVtdIFZBTFVFUyA9IHZhbHVlcygpOwoKICAgIHB1YmxpYyBzdGF0aWMgVGVzdEVudW0gdmFsdWVPZigKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkVudW1WYWx1ZURlc2NyaXB0b3IgZGVzYykgewogICAgICBpZiAoZGVzYy5nZXRUeXBlKCkgIT0gZ2V0RGVzY3JpcHRvcigpKSB7CiAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oCiAgICAgICAgICAiRW51bVZhbHVlRGVzY3JpcHRvciBpcyBub3QgZm9yIHRoaXMgdHlwZS4iKTsKICAgICAgfQogICAgICByZXR1cm4gVkFMVUVTW2Rlc2MuZ2V0SW5kZXgoKV07CiAgICB9CgogICAgcHJpdmF0ZSBmaW5hbCBpbnQgdmFsdWU7CgogICAgcHJpdmF0ZSBUZXN0RW51bShpbnQgdmFsdWUpIHsKICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlOwogICAgfQoKICAgIC8vIEBAcHJvdG9jX2luc2VydGlvbl9wb2ludChlbnVtX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5UZXN0RW51bSkKICB9CgogIHB1YmxpYyBpbnRlcmZhY2UgVGVzdE1lc3NhZ2VPckJ1aWxkZXIgZXh0ZW5kcwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoaW50ZXJmYWNlX2V4dGVuZHM6cHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlRlc3RNZXNzYWdlKQogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy4KICAgICAgICAgIEV4dGVuZGFibGVNZXNzYWdlT3JCdWlsZGVyPFRlc3RNZXNzYWdlPiB7CgogICAgLyoqCiAgICAgKiA8Y29kZT5vcHRpb25hbCBpbnQzMiBhID0gMTs8L2NvZGU+CiAgICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIGEgZmllbGQgaXMgc2V0LgogICAgICovCiAgICBib29sZWFuIGhhc0EoKTsKICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgaW50IGdldEEoKTsKICB9CiAgLyoqCiAgICogUHJvdG9idWYgdHlwZSB7QGNvZGUgcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlRlc3RNZXNzYWdlfQogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgY2xhc3MgVGVzdE1lc3NhZ2UgZXh0ZW5kcwogICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlTWVzc2FnZTwKICAgICAgICBUZXN0TWVzc2FnZT4gaW1wbGVtZW50cwogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQobWVzc2FnZV9pbXBsZW1lbnRzOnByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5UZXN0TWVzc2FnZSkKICAgICAgVGVzdE1lc3NhZ2VPckJ1aWxkZXIgewogIHByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDBMOwogICAgLy8gVXNlIFRlc3RNZXNzYWdlLm5ld0J1aWxkZXIoKSB0byBjb25zdHJ1Y3QuCiAgICBwcml2YXRlIFRlc3RNZXNzYWdlKGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkV4dGVuZGFibGVCdWlsZGVyPHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlLCA/PiBidWlsZGVyKSB7CiAgICAgIHN1cGVyKGJ1aWxkZXIpOwogICAgfQogICAgcHJpdmF0ZSBUZXN0TWVzc2FnZSgpIHsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBAU3VwcHJlc3NXYXJuaW5ncyh7InVudXNlZCJ9KQogICAgcHJvdGVjdGVkIGphdmEubGFuZy5PYmplY3QgbmV3SW5zdGFuY2UoCiAgICAgICAgVW51c2VkUHJpdmF0ZVBhcmFtZXRlciB1bnVzZWQpIHsKICAgICAgcmV0dXJuIG5ldyBUZXN0TWVzc2FnZSgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3RfVGVzdE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwcm90ZWN0ZWQgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuRmllbGRBY2Nlc3NvclRhYmxlCiAgICAgICAgaW50ZXJuYWxHZXRGaWVsZEFjY2Vzc29yVGFibGUoKSB7CiAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0X1Rlc3RNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgLmVuc3VyZUZpZWxkQWNjZXNzb3JzSW5pdGlhbGl6ZWQoCiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2UuY2xhc3MsIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlLkJ1aWxkZXIuY2xhc3MpOwogICAgfQoKICAgIHByaXZhdGUgaW50IGJpdEZpZWxkMF87CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGludCBBX0ZJRUxEX05VTUJFUiA9IDE7CiAgICBwcml2YXRlIGludCBhXyA9IDA7CiAgICAvKioKICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAqIEByZXR1cm4gV2hldGhlciB0aGUgYSBmaWVsZCBpcyBzZXQuCiAgICAgKi8KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBib29sZWFuIGhhc0EoKSB7CiAgICAgIHJldHVybiAoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKTsKICAgIH0KICAgIC8qKgogICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICogQHJldHVybiBUaGUgYS4KICAgICAqLwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRBKCkgewogICAgICByZXR1cm4gYV87CiAgICB9CgogICAgcHJpdmF0ZSBieXRlIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IC0xOwogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGZpbmFsIGJvb2xlYW4gaXNJbml0aWFsaXplZCgpIHsKICAgICAgYnl0ZSBpc0luaXRpYWxpemVkID0gbWVtb2l6ZWRJc0luaXRpYWxpemVkOwogICAgICBpZiAoaXNJbml0aWFsaXplZCA9PSAxKSByZXR1cm4gdHJ1ZTsKICAgICAgaWYgKGlzSW5pdGlhbGl6ZWQgPT0gMCkgcmV0dXJuIGZhbHNlOwoKICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIG1lbW9pemVkSXNJbml0aWFsaXplZCA9IDE7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyB2b2lkIHdyaXRlVG8oY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZE91dHB1dFN0cmVhbSBvdXRwdXQpCiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAuRXh0ZW5kYWJsZU1lc3NhZ2U8cHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2U+LkV4dGVuc2lvbldyaXRlcgogICAgICAgICAgZXh0ZW5zaW9uV3JpdGVyID0gbmV3RXh0ZW5zaW9uV3JpdGVyKCk7CiAgICAgIGlmICgoKGJpdEZpZWxkMF8gJiAweDAwMDAwMDAxKSAhPSAwKSkgewogICAgICAgIG91dHB1dC53cml0ZUludDMyKDEsIGFfKTsKICAgICAgfQogICAgICBleHRlbnNpb25Xcml0ZXIud3JpdGVVbnRpbCg1MzY4NzA5MTIsIG91dHB1dCk7CiAgICAgIGdldFVua25vd25GaWVsZHMoKS53cml0ZVRvKG91dHB1dCk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIGludCBnZXRTZXJpYWxpemVkU2l6ZSgpIHsKICAgICAgaW50IHNpemUgPSBtZW1vaXplZFNpemU7CiAgICAgIGlmIChzaXplICE9IC0xKSByZXR1cm4gc2l6ZTsKCiAgICAgIHNpemUgPSAwOwogICAgICBpZiAoKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICBzaXplICs9IGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRPdXRwdXRTdHJlYW0KICAgICAgICAgIC5jb21wdXRlSW50MzJTaXplKDEsIGFfKTsKICAgICAgfQogICAgICBzaXplICs9IGV4dGVuc2lvbnNTZXJpYWxpemVkU2l6ZSgpOwogICAgICBzaXplICs9IGdldFVua25vd25GaWVsZHMoKS5nZXRTZXJpYWxpemVkU2l6ZSgpOwogICAgICBtZW1vaXplZFNpemUgPSBzaXplOwogICAgICByZXR1cm4gc2l6ZTsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoZmluYWwgamF2YS5sYW5nLk9iamVjdCBvYmopIHsKICAgICAgaWYgKG9iaiA9PSB0aGlzKSB7CiAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQogICAgICBpZiAoIShvYmogaW5zdGFuY2VvZiBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSkpIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXF1YWxzKG9iaik7CiAgICAgIH0KICAgICAgcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2Ugb3RoZXIgPSAocHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2UpIG9iajsKCiAgICAgIGlmIChoYXNBKCkgIT0gb3RoZXIuaGFzQSgpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmIChoYXNBKCkpIHsKICAgICAgICBpZiAoZ2V0QSgpCiAgICAgICAgICAgICE9IG90aGVyLmdldEEoKSkgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIGlmICghZ2V0VW5rbm93bkZpZWxkcygpLmVxdWFscyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpKSByZXR1cm4gZmFsc2U7CiAgICAgIGlmICghZ2V0RXh0ZW5zaW9uRmllbGRzKCkuZXF1YWxzKG90aGVyLmdldEV4dGVuc2lvbkZpZWxkcygpKSkKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgIGlmIChtZW1vaXplZEhhc2hDb2RlICE9IDApIHsKICAgICAgICByZXR1cm4gbWVtb2l6ZWRIYXNoQ29kZTsKICAgICAgfQogICAgICBpbnQgaGFzaCA9IDQxOwogICAgICBoYXNoID0gKDE5ICogaGFzaCkgKyBnZXREZXNjcmlwdG9yKCkuaGFzaENvZGUoKTsKICAgICAgaWYgKGhhc0EoKSkgewogICAgICAgIGhhc2ggPSAoMzcgKiBoYXNoKSArIEFfRklFTERfTlVNQkVSOwogICAgICAgIGhhc2ggPSAoNTMgKiBoYXNoKSArIGdldEEoKTsKICAgICAgfQogICAgICBoYXNoID0gaGFzaEZpZWxkcyhoYXNoLCBnZXRFeHRlbnNpb25GaWVsZHMoKSk7CiAgICAgIGhhc2ggPSAoMjkgKiBoYXNoKSArIGdldFVua25vd25GaWVsZHMoKS5oYXNoQ29kZSgpOwogICAgICBtZW1vaXplZEhhc2hDb2RlID0gaGFzaDsKICAgICAgcmV0dXJuIGhhc2g7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgamF2YS5uaW8uQnl0ZUJ1ZmZlciBkYXRhLAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEsIGV4dGVuc2lvblJlZ2lzdHJ5KTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2UgcGFyc2VGcm9tKAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQnl0ZVN0cmluZyBkYXRhKQogICAgICAgIHRocm93cyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbiB7CiAgICAgIHJldHVybiBQQVJTRVIucGFyc2VGcm9tKGRhdGEpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5CeXRlU3RyaW5nIGRhdGEsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSBwYXJzZUZyb20oYnl0ZVtdIGRhdGEpCiAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIFBBUlNFUi5wYXJzZUZyb20oZGF0YSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBieXRlW10gZGF0YSwKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICB0aHJvd3MgY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gewogICAgICByZXR1cm4gUEFSU0VSLnBhcnNlRnJvbShkYXRhLCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlIHBhcnNlRnJvbShqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2UgcGFyc2VEZWxpbWl0ZWRGcm9tKGphdmEuaW8uSW5wdXRTdHJlYW0gaW5wdXQpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZURlbGltaXRlZFdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlIHBhcnNlRGVsaW1pdGVkRnJvbSgKICAgICAgICBqYXZhLmlvLklucHV0U3RyZWFtIGlucHV0LAogICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VEZWxpbWl0ZWRXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnkpOwogICAgfQogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSBwYXJzZUZyb20oCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5Db2RlZElucHV0U3RyZWFtIGlucHV0KQogICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgcmV0dXJuIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzCiAgICAgICAgICAucGFyc2VXaXRoSU9FeGNlcHRpb24oUEFSU0VSLCBpbnB1dCk7CiAgICB9CiAgICBwdWJsaWMgc3RhdGljIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlIHBhcnNlRnJvbSgKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SZWdpc3RyeUxpdGUgZXh0ZW5zaW9uUmVnaXN0cnkpCiAgICAgICAgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICByZXR1cm4gY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMKICAgICAgICAgIC5wYXJzZVdpdGhJT0V4Y2VwdGlvbihQQVJTRVIsIGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoKSB7IHJldHVybiBuZXdCdWlsZGVyKCk7IH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKCkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKTsKICAgIH0KICAgIHB1YmxpYyBzdGF0aWMgQnVpbGRlciBuZXdCdWlsZGVyKHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlIHByb3RvdHlwZSkgewogICAgICByZXR1cm4gREVGQVVMVF9JTlNUQU5DRS50b0J1aWxkZXIoKS5tZXJnZUZyb20ocHJvdG90eXBlKTsKICAgIH0KICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHRvQnVpbGRlcigpIHsKICAgICAgcmV0dXJuIHRoaXMgPT0gREVGQVVMVF9JTlNUQU5DRQogICAgICAgICAgPyBuZXcgQnVpbGRlcigpIDogbmV3IEJ1aWxkZXIoKS5tZXJnZUZyb20odGhpcyk7CiAgICB9CgogICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgcHJvdGVjdGVkIEJ1aWxkZXIgbmV3QnVpbGRlckZvclR5cGUoCiAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlVjMuQnVpbGRlclBhcmVudCBwYXJlbnQpIHsKICAgICAgQnVpbGRlciBidWlsZGVyID0gbmV3IEJ1aWxkZXIocGFyZW50KTsKICAgICAgcmV0dXJuIGJ1aWxkZXI7CiAgICB9CiAgICAvKioKICAgICAqIFByb3RvYnVmIHR5cGUge0Bjb2RlIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5UZXN0TWVzc2FnZX0KICAgICAqLwogICAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMKICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5FeHRlbmRhYmxlQnVpbGRlcjwKICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlLCBCdWlsZGVyPiBpbXBsZW1lbnRzCiAgICAgICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGJ1aWxkZXJfaW1wbGVtZW50czpwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVGVzdE1lc3NhZ2UpCiAgICAgICAgcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2VPckJ1aWxkZXIgewogICAgICBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvcigpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXNfdGVzdF9UZXN0TWVzc2FnZV9kZXNjcmlwdG9yOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHByb3RlY3RlZCBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgICAgIGludGVybmFsR2V0RmllbGRBY2Nlc3NvclRhYmxlKCkgewogICAgICAgIHJldHVybiBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5pbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0X1Rlc3RNZXNzYWdlX2ZpZWxkQWNjZXNzb3JUYWJsZQogICAgICAgICAgICAuZW5zdXJlRmllbGRBY2Nlc3NvcnNJbml0aWFsaXplZCgKICAgICAgICAgICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlLmNsYXNzLCBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZS5CdWlsZGVyLmNsYXNzKTsKICAgICAgfQoKICAgICAgLy8gQ29uc3RydWN0IHVzaW5nIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlLm5ld0J1aWxkZXIoKQogICAgICBwcml2YXRlIEJ1aWxkZXIoKSB7CgogICAgICB9CgogICAgICBwcml2YXRlIEJ1aWxkZXIoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5CdWlsZGVyUGFyZW50IHBhcmVudCkgewogICAgICAgIHN1cGVyKHBhcmVudCk7CgogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgY2xlYXIoKSB7CiAgICAgICAgc3VwZXIuY2xlYXIoKTsKICAgICAgICBiaXRGaWVsZDBfID0gMDsKICAgICAgICBhXyA9IDA7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRGVzY3JpcHRvcgogICAgICAgICAgZ2V0RGVzY3JpcHRvckZvclR5cGUoKSB7CiAgICAgICAgcmV0dXJuIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLmludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3RfVGVzdE1lc3NhZ2VfZGVzY3JpcHRvcjsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgICByZXR1cm4gcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2UuZ2V0RGVmYXVsdEluc3RhbmNlKCk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlIGJ1aWxkKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlIHJlc3VsdCA9IGJ1aWxkUGFydGlhbCgpOwogICAgICAgIGlmICghcmVzdWx0LmlzSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgdGhyb3cgbmV3VW5pbml0aWFsaXplZE1lc3NhZ2VFeGNlcHRpb24ocmVzdWx0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2UgYnVpbGRQYXJ0aWFsKCkgewogICAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlIHJlc3VsdCA9IG5ldyBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSh0aGlzKTsKICAgICAgICBpZiAoYml0RmllbGQwXyAhPSAwKSB7IGJ1aWxkUGFydGlhbDAocmVzdWx0KTsgfQogICAgICAgIG9uQnVpbHQoKTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwcml2YXRlIHZvaWQgYnVpbGRQYXJ0aWFsMChwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSByZXN1bHQpIHsKICAgICAgICBpbnQgZnJvbV9iaXRGaWVsZDBfID0gYml0RmllbGQwXzsKICAgICAgICBpbnQgdG9fYml0RmllbGQwXyA9IDA7CiAgICAgICAgaWYgKCgoZnJvbV9iaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCkpIHsKICAgICAgICAgIHJlc3VsdC5hXyA9IGFfOwogICAgICAgICAgdG9fYml0RmllbGQwXyB8PSAweDAwMDAwMDAxOwogICAgICAgIH0KICAgICAgICByZXN1bHQuYml0RmllbGQwXyB8PSB0b19iaXRGaWVsZDBfOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsb25lKCkgewogICAgICAgIHJldHVybiBzdXBlci5jbG9uZSgpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgc2V0RmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGphdmEubGFuZy5PYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gc3VwZXIuc2V0RmllbGQoZmllbGQsIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCkgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckZpZWxkKGZpZWxkKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIGNsZWFyT25lb2YoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLk9uZW9mRGVzY3JpcHRvciBvbmVvZikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhck9uZW9mKG9uZW9mKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBCdWlsZGVyIHNldFJlcGVhdGVkRmllbGQoCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpZWxkRGVzY3JpcHRvciBmaWVsZCwKICAgICAgICAgIGludCBpbmRleCwgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRSZXBlYXRlZEZpZWxkKGZpZWxkLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgYWRkUmVwZWF0ZWRGaWVsZCgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvcnMuRmllbGREZXNjcmlwdG9yIGZpZWxkLAogICAgICAgICAgamF2YS5sYW5nLk9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5hZGRSZXBlYXRlZEZpZWxkKGZpZWxkLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSwgVHlwZT4gZXh0ZW5zaW9uLAogICAgICAgICAgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCB2YWx1ZSk7CiAgICAgIH0KICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgPFR5cGU+IEJ1aWxkZXIgc2V0RXh0ZW5zaW9uKAogICAgICAgICAgY29tLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRNZXNzYWdlLkdlbmVyYXRlZEV4dGVuc2lvbjwKICAgICAgICAgICAgICBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSwgamF2YS51dGlsLkxpc3Q8VHlwZT4+IGV4dGVuc2lvbiwKICAgICAgICAgIGludCBpbmRleCwgVHlwZSB2YWx1ZSkgewogICAgICAgIHJldHVybiBzdXBlci5zZXRFeHRlbnNpb24oZXh0ZW5zaW9uLCBpbmRleCwgdmFsdWUpOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIDxUeXBlPiBCdWlsZGVyIGFkZEV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2UsIGphdmEudXRpbC5MaXN0PFR5cGU+PiBleHRlbnNpb24sCiAgICAgICAgICBUeXBlIHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmFkZEV4dGVuc2lvbihleHRlbnNpb24sIHZhbHVlKTsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyA8VD4gQnVpbGRlciBjbGVhckV4dGVuc2lvbigKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgICAgICAgICAgcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2UsIFQ+IGV4dGVuc2lvbikgewogICAgICAgIHJldHVybiBzdXBlci5jbGVhckV4dGVuc2lvbihleHRlbnNpb24pOwogICAgICB9CiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIEJ1aWxkZXIgbWVyZ2VGcm9tKGNvbS5nb29nbGUucHJvdG9idWYuTWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciBpbnN0YW5jZW9mIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlKSB7CiAgICAgICAgICByZXR1cm4gbWVyZ2VGcm9tKChwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSlvdGhlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHN1cGVyLm1lcmdlRnJvbShvdGhlcik7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHB1YmxpYyBCdWlsZGVyIG1lcmdlRnJvbShwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSBvdGhlcikgewogICAgICAgIGlmIChvdGhlciA9PSBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZS5nZXREZWZhdWx0SW5zdGFuY2UoKSkgcmV0dXJuIHRoaXM7CiAgICAgICAgaWYgKG90aGVyLmhhc0EoKSkgewogICAgICAgICAgc2V0QShvdGhlci5nZXRBKCkpOwogICAgICAgIH0KICAgICAgICB0aGlzLm1lcmdlRXh0ZW5zaW9uRmllbGRzKG90aGVyKTsKICAgICAgICB0aGlzLm1lcmdlVW5rbm93bkZpZWxkcyhvdGhlci5nZXRVbmtub3duRmllbGRzKCkpOwogICAgICAgIG9uQ2hhbmdlZCgpOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBib29sZWFuIGlzSW5pdGlhbGl6ZWQoKSB7CiAgICAgICAgaWYgKCFleHRlbnNpb25zQXJlSW5pdGlhbGl6ZWQoKSkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgfQoKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgQnVpbGRlciBtZXJnZUZyb20oCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkNvZGVkSW5wdXRTdHJlYW0gaW5wdXQsCiAgICAgICAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkV4dGVuc2lvblJlZ2lzdHJ5TGl0ZSBleHRlbnNpb25SZWdpc3RyeSkKICAgICAgICAgIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBpZiAoZXh0ZW5zaW9uUmVnaXN0cnkgPT0gbnVsbCkgewogICAgICAgICAgdGhyb3cgbmV3IGphdmEubGFuZy5OdWxsUG9pbnRlckV4Y2VwdGlvbigpOwogICAgICAgIH0KICAgICAgICB0cnkgewogICAgICAgICAgYm9vbGVhbiBkb25lID0gZmFsc2U7CiAgICAgICAgICB3aGlsZSAoIWRvbmUpIHsKICAgICAgICAgICAgaW50IHRhZyA9IGlucHV0LnJlYWRUYWcoKTsKICAgICAgICAgICAgc3dpdGNoICh0YWcpIHsKICAgICAgICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNhc2UgODogewogICAgICAgICAgICAgICAgYV8gPSBpbnB1dC5yZWFkSW50MzIoKTsKICAgICAgICAgICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gY2FzZSA4CiAgICAgICAgICAgICAgZGVmYXVsdDogewogICAgICAgICAgICAgICAgaWYgKCFzdXBlci5wYXJzZVVua25vd25GaWVsZChpbnB1dCwgZXh0ZW5zaW9uUmVnaXN0cnksIHRhZykpIHsKICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7IC8vIHdhcyBhbiBlbmRncm91cCB0YWcKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0gLy8gZGVmYXVsdDoKICAgICAgICAgICAgfSAvLyBzd2l0Y2ggKHRhZykKICAgICAgICAgIH0gLy8gd2hpbGUgKCFkb25lKQogICAgICAgIH0gY2F0Y2ggKGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUudW53cmFwSU9FeGNlcHRpb24oKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgb25DaGFuZ2VkKCk7CiAgICAgICAgfSAvLyBmaW5hbGx5CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KICAgICAgcHJpdmF0ZSBpbnQgYml0RmllbGQwXzsKCiAgICAgIHByaXZhdGUgaW50IGFfIDsKICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBXaGV0aGVyIHRoZSBhIGZpZWxkIGlzIHNldC4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGJvb2xlYW4gaGFzQSgpIHsKICAgICAgICByZXR1cm4gKChiaXRGaWVsZDBfICYgMHgwMDAwMDAwMSkgIT0gMCk7CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIDxjb2RlPm9wdGlvbmFsIGludDMyIGEgPSAxOzwvY29kZT4KICAgICAgICogQHJldHVybiBUaGUgYS4KICAgICAgICovCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGludCBnZXRBKCkgewogICAgICAgIHJldHVybiBhXzsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIGEgdG8gc2V0LgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBzZXRBKGludCB2YWx1ZSkgewoKICAgICAgICBhXyA9IHZhbHVlOwogICAgICAgIGJpdEZpZWxkMF8gfD0gMHgwMDAwMDAwMTsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICAvKioKICAgICAgICogPGNvZGU+b3B0aW9uYWwgaW50MzIgYSA9IDE7PC9jb2RlPgogICAgICAgKiBAcmV0dXJuIFRoaXMgYnVpbGRlciBmb3IgY2hhaW5pbmcuCiAgICAgICAqLwogICAgICBwdWJsaWMgQnVpbGRlciBjbGVhckEoKSB7CiAgICAgICAgYml0RmllbGQwXyA9IChiaXRGaWVsZDBfICYgfjB4MDAwMDAwMDEpOwogICAgICAgIGFfID0gMDsKICAgICAgICBvbkNoYW5nZWQoKTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQogICAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICAgIHB1YmxpYyBmaW5hbCBCdWlsZGVyIHNldFVua25vd25GaWVsZHMoCiAgICAgICAgICBmaW5hbCBjb20uZ29vZ2xlLnByb3RvYnVmLlVua25vd25GaWVsZFNldCB1bmtub3duRmllbGRzKSB7CiAgICAgICAgcmV0dXJuIHN1cGVyLnNldFVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgICAgcHVibGljIGZpbmFsIEJ1aWxkZXIgbWVyZ2VVbmtub3duRmllbGRzKAogICAgICAgICAgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5Vbmtub3duRmllbGRTZXQgdW5rbm93bkZpZWxkcykgewogICAgICAgIHJldHVybiBzdXBlci5tZXJnZVVua25vd25GaWVsZHModW5rbm93bkZpZWxkcyk7CiAgICAgIH0KCgogICAgICAvLyBAQHByb3RvY19pbnNlcnRpb25fcG9pbnQoYnVpbGRlcl9zY29wZTpwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVGVzdE1lc3NhZ2UpCiAgICB9CgogICAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KGNsYXNzX3Njb3BlOnByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5UZXN0TWVzc2FnZSkKICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlIERFRkFVTFRfSU5TVEFOQ0U7CiAgICBzdGF0aWMgewogICAgICBERUZBVUxUX0lOU1RBTkNFID0gbmV3IHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBwcm90b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuVW5pdHRlc3ROb0dlbmVyaWNTZXJ2aWNlcy5UZXN0TWVzc2FnZSBnZXREZWZhdWx0SW5zdGFuY2UoKSB7CiAgICAgIHJldHVybiBERUZBVUxUX0lOU1RBTkNFOwogICAgfQoKICAgIEBqYXZhLmxhbmcuRGVwcmVjYXRlZCBwdWJsaWMgc3RhdGljIGZpbmFsIGNvbS5nb29nbGUucHJvdG9idWYuUGFyc2VyPFRlc3RNZXNzYWdlPgogICAgICAgIFBBUlNFUiA9IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkFic3RyYWN0UGFyc2VyPFRlc3RNZXNzYWdlPigpIHsKICAgICAgQGphdmEubGFuZy5PdmVycmlkZQogICAgICBwdWJsaWMgVGVzdE1lc3NhZ2UgcGFyc2VQYXJ0aWFsRnJvbSgKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuQ29kZWRJbnB1dFN0cmVhbSBpbnB1dCwKICAgICAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmVnaXN0cnlMaXRlIGV4dGVuc2lvblJlZ2lzdHJ5KQogICAgICAgICAgdGhyb3dzIGNvbS5nb29nbGUucHJvdG9idWYuSW52YWxpZFByb3RvY29sQnVmZmVyRXhjZXB0aW9uIHsKICAgICAgICBCdWlsZGVyIGJ1aWxkZXIgPSBuZXdCdWlsZGVyKCk7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGJ1aWxkZXIubWVyZ2VGcm9tKGlucHV0LCBleHRlbnNpb25SZWdpc3RyeSk7CiAgICAgICAgfSBjYXRjaCAoY29tLmdvb2dsZS5wcm90b2J1Zi5JbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24gZSkgewogICAgICAgICAgdGhyb3cgZS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChjb20uZ29vZ2xlLnByb3RvYnVmLlVuaW5pdGlhbGl6ZWRNZXNzYWdlRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IGUuYXNJbnZhbGlkUHJvdG9jb2xCdWZmZXJFeGNlcHRpb24oKS5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9IGNhdGNoIChqYXZhLmlvLklPRXhjZXB0aW9uIGUpIHsKICAgICAgICAgIHRocm93IG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkludmFsaWRQcm90b2NvbEJ1ZmZlckV4Y2VwdGlvbihlKQogICAgICAgICAgICAgIC5zZXRVbmZpbmlzaGVkTWVzc2FnZShidWlsZGVyLmJ1aWxkUGFydGlhbCgpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJ1aWxkZXIuYnVpbGRQYXJ0aWFsKCk7CiAgICAgIH0KICAgIH07CgogICAgcHVibGljIHN0YXRpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZT4gcGFyc2VyKCkgewogICAgICByZXR1cm4gUEFSU0VSOwogICAgfQoKICAgIEBqYXZhLmxhbmcuT3ZlcnJpZGUKICAgIHB1YmxpYyBjb20uZ29vZ2xlLnByb3RvYnVmLlBhcnNlcjxUZXN0TWVzc2FnZT4gZ2V0UGFyc2VyRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIFBBUlNFUjsKICAgIH0KCiAgICBAamF2YS5sYW5nLk92ZXJyaWRlCiAgICBwdWJsaWMgcHJvdG9idWZfdW5pdHRlc3Qubm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlVuaXR0ZXN0Tm9HZW5lcmljU2VydmljZXMuVGVzdE1lc3NhZ2UgZ2V0RGVmYXVsdEluc3RhbmNlRm9yVHlwZSgpIHsKICAgICAgcmV0dXJuIERFRkFVTFRfSU5TVEFOQ0U7CiAgICB9CgogIH0KCiAgcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgVEVTVF9FWFRFTlNJT05fRklFTERfTlVNQkVSID0gMTAwMDsKICAvKioKICAgKiA8Y29kZT5leHRlbmQgLnByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5UZXN0TWVzc2FnZSB7IC4uLiB9PC9jb2RlPgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwKICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZS5HZW5lcmF0ZWRFeHRlbnNpb248CiAgICAgIHByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLlRlc3RNZXNzYWdlLAogICAgICBqYXZhLmxhbmcuSW50ZWdlcj4gdGVzdEV4dGVuc2lvbiA9IGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZQogICAgICAgICAgLm5ld0ZpbGVTY29wZWRHZW5lcmF0ZWRFeHRlbnNpb24oCiAgICAgICAgamF2YS5sYW5nLkludGVnZXIuY2xhc3MsCiAgICAgICAgbnVsbCk7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5EZXNjcmlwdG9yCiAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0X1Rlc3RNZXNzYWdlX2Rlc2NyaXB0b3I7CiAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgCiAgICBjb20uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZE1lc3NhZ2VWMy5GaWVsZEFjY2Vzc29yVGFibGUKICAgICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXNfdGVzdF9UZXN0TWVzc2FnZV9maWVsZEFjY2Vzc29yVGFibGU7CgogIHB1YmxpYyBzdGF0aWMgY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICBnZXREZXNjcmlwdG9yKCkgewogICAgcmV0dXJuIGRlc2NyaXB0b3I7CiAgfQogIHByaXZhdGUgc3RhdGljICBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yCiAgICAgIGRlc2NyaXB0b3I7CiAgc3RhdGljIHsKICAgIGphdmEubGFuZy5TdHJpbmdbXSBkZXNjcmlwdG9yRGF0YSA9IHsKICAgICAgIlxuMmdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9ub19nZW5lcmljX3NlIiArCiAgICAgICJydmljZXMucHJvdG9cMDIyKnByb3RvYnVmX3VuaXR0ZXN0Lm5vX2dlbmVyIiArCiAgICAgICJpY19zZXJ2aWNlc190ZXN0XCIjXG5cMDEzVGVzdE1lc3NhZ2VcMDIyXHRcblwwMDFhXDAzMFwwMDEgXDAwMSIgKwogICAgICAiKFwwMDUqXHRcMDEwXDM1MFwwMDdcMDIwXDIwMFwyMDBcMjAwXDIwMFwwMDIqXDAyM1xuXDAxMFRlc3RFbnVtXDAyMlwwMDdcblwwMDNGT09cMDIwXDAwMTJcMjA2XDAwMVxuXDAxM1QiICsKICAgICAgImVzdFNlcnZpY2VcMDIyd1xuXDAwM0Zvb1wwMjI3LnByb3RvYnVmX3VuaXR0ZXN0Lm5vIiArCiAgICAgICJfZ2VuZXJpY19zZXJ2aWNlc190ZXN0LlRlc3RNZXNzYWdlXDAzMjcucHJvIiArCiAgICAgICJ0b2J1Zl91bml0dGVzdC5ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3QuIiArCiAgICAgICJUZXN0TWVzc2FnZTpQXG5cMDE2dGVzdF9leHRlbnNpb25cMDIyNy5wcm90b2J1ZiIgKwogICAgICAiX3VuaXR0ZXN0Lm5vX2dlbmVyaWNfc2VydmljZXNfdGVzdC5UZXN0TSIgKwogICAgICAiZXNzYWdlXDAzMFwzNTBcMDA3IFwwMDEoXDAwNSIKICAgIH07CiAgICBkZXNjcmlwdG9yID0gY29tLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9ycy5GaWxlRGVzY3JpcHRvcgogICAgICAuaW50ZXJuYWxCdWlsZEdlbmVyYXRlZEZpbGVGcm9tKGRlc2NyaXB0b3JEYXRhLAogICAgICAgIG5ldyBjb20uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JzLkZpbGVEZXNjcmlwdG9yW10gewogICAgICAgIH0pOwogICAgaW50ZXJuYWxfc3RhdGljX3Byb3RvYnVmX3VuaXR0ZXN0X25vX2dlbmVyaWNfc2VydmljZXNfdGVzdF9UZXN0TWVzc2FnZV9kZXNjcmlwdG9yID0KICAgICAgZ2V0RGVzY3JpcHRvcigpLmdldE1lc3NhZ2VUeXBlcygpLmdldCgwKTsKICAgIGludGVybmFsX3N0YXRpY19wcm90b2J1Zl91bml0dGVzdF9ub19nZW5lcmljX3NlcnZpY2VzX3Rlc3RfVGVzdE1lc3NhZ2VfZmllbGRBY2Nlc3NvclRhYmxlID0gbmV3CiAgICAgIGNvbS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkTWVzc2FnZVYzLkZpZWxkQWNjZXNzb3JUYWJsZSgKICAgICAgICBpbnRlcm5hbF9zdGF0aWNfcHJvdG9idWZfdW5pdHRlc3Rfbm9fZ2VuZXJpY19zZXJ2aWNlc190ZXN0X1Rlc3RNZXNzYWdlX2Rlc2NyaXB0b3IsCiAgICAgICAgbmV3IGphdmEubGFuZy5TdHJpbmdbXSB7ICJBIiwgfSk7CiAgICB0ZXN0RXh0ZW5zaW9uLmludGVybmFsSW5pdChkZXNjcmlwdG9yLmdldEV4dGVuc2lvbnMoKS5nZXQoMCkpOwogIH0KCiAgLy8gQEBwcm90b2NfaW5zZXJ0aW9uX3BvaW50KG91dGVyX2NsYXNzX3Njb3BlKQp9ClBLAQIKAAoAAAAAAAAAIQAmbx6fMgAAADIAAAAUAAAAAAAAAAAAAAAAAAAAAABNRVRBLUlORi9NQU5JRkVTVC5NRlBLAQIKAAoAAAAAAAAAIQBaWG8ALAQAACwEAAASAAAAAAAAAAAAAAAAAGQAAABVbml0dGVzdEVtcHR5LmphdmFQSwECCgAKAAAAAAAAACEA75bietBlswDQZbMAMwAAAAAAAAAAAAAAAADABAAAY29tL2dvb2dsZS9wcm90b2J1Zi9Vbml0dGVzdEVub3Jtb3VzRGVzY3JpcHRvci5qYXZhUEsBAgoACgAAAAAAAAAhAMGJ9Hr8SgMA/EoDAC8AAAAAAAAAAAAAAAAA4WqzAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdC9NYXBXZWxsS25vd25UeXBlcy5qYXZhUEsBAgoACgAAAAAAAAAhABDKWmFVSQAAVUkAADgAAAAAAAAAAAAAAAAAKra2AGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdC9NYXBXZWxsS25vd25UeXBlc09yQnVpbGRlci5qYXZhUEsBAgoACgAAAAAAAAAhAIU2VGswKgIAMCoCADEAAAAAAAAAAAAAAAAA1f+2AGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdC9PbmVvZldlbGxLbm93blR5cGVzLmphdmFQSwECCgAKAAAAAAAAACEAlB5aq54hAACeIQAAOgAAAAAAAAAAAAAAAABUKrkAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0L09uZW9mV2VsbEtub3duVHlwZXNPckJ1aWxkZXIuamF2YVBLAQIKAAoAAAAAAAAAIQDfus9gMpUDADKVAwA0AAAAAAAAAAAAAAAAAEpMuQBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3QvUmVwZWF0ZWRXZWxsS25vd25UeXBlcy5qYXZhUEsBAgoACgAAAAAAAAAhAJnCqx3zOQAA8zkAAD0AAAAAAAAAAAAAAAAAzuG8AGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdC9SZXBlYXRlZFdlbGxLbm93blR5cGVzT3JCdWlsZGVyLmphdmFQSwECCgAKAAAAAAAAACEA3uIiFSEaAgAhGgIAMAAAAAAAAAAAAAAAAAAcHL0AY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0L1Rlc3RXZWxsS25vd25UeXBlcy5qYXZhUEsBAgoACgAAAAAAAAAhAC2B8sMCJAAAAiQAADkAAAAAAAAAAAAAAAAAiza/AGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdC9UZXN0V2VsbEtub3duVHlwZXNPckJ1aWxkZXIuamF2YVBLAQIKAAoAAAAAAAAAIQBF/aMOtmcAALZnAAAsAAAAAAAAAAAAAAAAAORavwBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3QvVW5pdHRlc3RJbXBvcnQuamF2YVBLAQIKAAoAAAAAAAAAIQCAqR+1BlEAAAZRAAAyAAAAAAAAAAAAAAAAAOTCvwBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3QvVW5pdHRlc3RJbXBvcnRQdWJsaWMuamF2YVBLAQIKAAoAAAAAAAAAIQCteki53ngAAN54AAA0AAAAAAAAAAAAAAAAADoUwABjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3QvVW5pdHRlc3RXZWxsS25vd25UeXBlcy5qYXZhUEsBAgoACgAAAAAAAAAhAEvyR6A7KAAAOygAAC8AAAAAAAAAAAAAAAAAao3AAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9wcm90by9CYWROYW1lcy5qYXZhUEsBAgoACgAAAAAAAAAhAGlux2bECwAAxAsAACoAAAAAAAAAAAAAAAAA8rXAAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9wcm90by9HSUQuamF2YVBLAQIKAAoAAAAAAAAAIQBqbymh+j4AAPo+AAA/AAAAAAAAAAAAAAAAAP7BwABjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvcHJvdG8vUHJvdG8zT3B0aW9uYWxFeHRlbnNpb25zLmphdmFQSwECCgAKAAAAAAAAACEAUf8fCY4BAACOAQAASAAAAAAAAAAAAAAAAABVAcEAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3Byb3RvL1Byb3RvM09wdGlvbmFsRXh0ZW5zaW9uc09yQnVpbGRlci5qYXZhUEsBAgoACgAAAAAAAAAhAAs4UTgHvwEAB78BADkAAAAAAAAAAAAAAAAASQPBAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9wcm90by9UZXN0UHJvdG8zT3B0aW9uYWwuamF2YVBLAQIKAAoAAAAAAAAAIQCmHIl7y9AAAMvQAABAAAAAAAAAAAAAAAAAAKfCwgBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvcHJvdG8vVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZS5qYXZhUEsBAgoACgAAAAAAAAAhADCVZYMIBwAACAcAAEkAAAAAAAAAAAAAAAAA0JPDAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9wcm90by9UZXN0UHJvdG8zT3B0aW9uYWxNZXNzYWdlT3JCdWlsZGVyLmphdmFQSwECCgAKAAAAAAAAACEAabV+36ceAACnHgAAQgAAAAAAAAAAAAAAAAA/m8MAY29tL2dvb2dsZS9wcm90b2J1Zi90ZXN0aW5nL3Byb3RvL1Rlc3RQcm90bzNPcHRpb25hbE9yQnVpbGRlci5qYXZhUEsBAgoACgAAAAAAAAAhAEbDi3HDCwAAwwsAACoAAAAAAAAAAAAAAAAARrrDAGNvbS9nb29nbGUvcHJvdG9idWYvdGVzdGluZy9wcm90by9VSUQuamF2YVBLAQIKAAoAAAAAAAAAIQAAjQOsxgkAAMYJAAA+AAAAAAAAAAAAAAAAAFHGwwBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvcHJvdG8vVW5pdHRlc3RQcm90bzNCYWRNYWNyb3MuamF2YVBLAQIKAAoAAAAAAAAAIQDB+FS2bSUAAG0lAAA9AAAAAAAAAAAAAAAAAHPQwwBjb20vZ29vZ2xlL3Byb3RvYnVmL3Rlc3RpbmcvcHJvdG8vVW5pdHRlc3RQcm90bzNPcHRpb25hbC5qYXZhUEsBAgoACgAAAAAAAAAhAHXK+hOxlwIAsZcCABgAAAAAAAAAAAAAAAAAO/bDAHBiL1VuaXR0ZXN0RmVhdHVyZXMuamF2YVBLAQIKAAoAAAAAAAAAIQDO9ZVSVWMAAFVjAAAfAAAAAAAAAAAAAAAAACKOxgBwYi9Vbml0dGVzdEludmFsaWRGZWF0dXJlcy5qYXZhUEsBAgoACgAAAAAAAAAhABQ2WEnsuQAA7LkAADYAAAAAAAAAAAAAAAAAtPHGAHByb3RvMl93aXJlZm9ybWF0X3VuaXR0ZXN0L1VuaXR0ZXN0TXNldFdpcmVGb3JtYXQuamF2YVBLAQIKAAoAAAAAAAAAIQCiPfwdxs4KAMbOCgA3AAAAAAAAAAAAAAAAAPSrxwBwcm90bzNfYXJlbmFfbGl0ZV91bml0dGVzdC9Vbml0dGVzdFByb3RvM0FyZW5hTGl0ZS5qYXZhUEsBAgoACgAAAAAAAAAhAPXXgZ5VKQ0AVSkNAC4AAAAAAAAAAAAAAAAAD3vSAHByb3RvM19hcmVuYV91bml0dGVzdC9Vbml0dGVzdFByb3RvM0FyZW5hLmphdmFQSwECCgAKAAAAAAAAACEAMEUkgTSnCgA0pwoALAAAAAAAAAAAAAAAAACwpN8AcHJvdG8zX2xpdGVfdW5pdHRlc3QvVW5pdHRlc3RQcm90bzNMaXRlLmphdmFQSwECCgAKAAAAAAAAACEAswso1T+KCwA/igsAIwAAAAAAAAAAAAAAAAAuTOoAcHJvdG8zX3VuaXR0ZXN0L1VuaXR0ZXN0UHJvdG8zLmphdmFQSwECCgAKAAAAAAAAACEA/cEp43LmCwBy5gsAKAAAAAAAAAAAAAAAAACu1vUAcHJvdG9idWZfdW5pdHRlc3QvTWFwUHJvdG8yVW5pdHRlc3QuamF2YVBLAQIKAAoAAAAAAAAAIQCPdWJlVJoKAFSaCgAiAAAAAAAAAAAAAAAAAGa9AQFwcm90b2J1Zl91bml0dGVzdC9NYXBVbml0dGVzdC5qYXZhUEsBAgoACgAAAAAAAAAhAI1UfFHDrgAAw64AACMAAAAAAAAAAAAAAAAA+lcMAXByb3RvYnVmX3VuaXR0ZXN0L1Rlc3RBbnlQcm90by5qYXZhUEsBAgoACgAAAAAAAAAhALcRYJi/9AoAv/QKACwAAAAAAAAAAAAAAAAA/gYNAXByb3RvYnVmX3VuaXR0ZXN0L1VuaXR0ZXN0Q3VzdG9tT3B0aW9ucy5qYXZhUEsBAgoACgAAAAAAAAAhAJsdb3HJtgAAybYAAC8AAAAAAAAAAAAAAAAAB/wXAXByb3RvYnVmX3VuaXR0ZXN0L1VuaXR0ZXN0RW1iZWRPcHRpbWl6ZUZvci5qYXZhUEsBAgoACgAAAAAAAAAhAEYv16pukAAAbpAAADEAAAAAAAAAAAAAAAAAHbMYAXByb3RvYnVmX3VuaXR0ZXN0L1VuaXR0ZXN0TGl0ZUltcG9ydHNOb25saXRlLmphdmFQSwECCgAKAAAAAAAAACEAS48OxfifAwD4nwMAIwAAAAAAAAAAAAAAAADaQxkBcHJvdG9idWZfdW5pdHRlc3QvVW5pdHRlc3RNc2V0LmphdmFQSwECCgAKAAAAAAAAACEAiv/KA/0VAQD9FQEAKgAAAAAAAAAAAAAAAAAT5BwBcHJvdG9idWZfdW5pdHRlc3QvVW5pdHRlc3RPcHRpbWl6ZUZvci5qYXZhUEsBAgoACgAAAAAAAAAhAPE0A9/OhWgAzoVoACQAAAAAAAAAAAAAAAAAWPodAXByb3RvYnVmX3VuaXR0ZXN0L1VuaXR0ZXN0UHJvdG8uamF2YVBLAQIKAAoAAAAAAAAAIQB54YTmX6cBAF+nAQAoAAAAAAAAAAAAAAAAAGiAhgFwcm90b2J1Zl91bml0dGVzdC9Vbml0dGVzdFJldGVudGlvbi5qYXZhUEsBAgoACgAAAAAAAAAhAJmXm2ldawAAXWsAAEkAAAAAAAAAAAAAAAAADSiIAXByb3RvYnVmX3VuaXR0ZXN0L25vX2dlbmVyaWNfc2VydmljZXNfdGVzdC9Vbml0dGVzdE5vR2VuZXJpY1NlcnZpY2VzLmphdmFQSwUGAAAAACsAKwDWDwAA0ZOIAQAA